package com.bizzan.bitrade.dao;

import com.bizzan.bitrade.entity.ContractCoin;
import com.bizzan.bitrade.entity.ContractType;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.querydsl.QueryDslPredicateExecutor;
import org.springframework.data.repository.query.Param;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.List;

public interface ContractCoinRepository extends JpaRepository<ContractCoin, Long>, JpaSpecificationExecutor<ContractCoin>, QueryDslPredicateExecutor<ContractCoin> {
    ContractCoin findBySymbol(String symbol);

    ContractCoin findBySymbolAndType(String symbol, ContractType type);

    @Query("select distinct a.baseSymbol from  ContractCoin a where a.enable = 1")
    List<String> findBaseSymbol();

    @Query("select distinct a.coinSymbol from  ContractCoin a where a.enable = 1 and a.baseSymbol = :baseSymbol")
    List<String> findCoinSymbol(@Param("baseSymbol")String baseSymbol);

    @Query("select distinct a.coinSymbol from  ContractCoin a where a.enable = 1")
    List<String> findAllCoinSymbol();

    @Transactional(rollbackFor = Exception.class)
    @Modifying
    @Query("update ContractCoin coin set coin.totalLoss=coin.totalLoss+:amount where coin.id = :cid")
    void increaseTotalLoss(@Param("cid")Long cid, @Param("amount")BigDecimal amount);

    @Transactional(rollbackFor = Exception.class)
    @Modifying
    @Query("update ContractCoin coin set coin.totalProfit=coin.totalProfit+:amount where coin.id = :cid")
    void increaseTotalProfit(@Param("cid")Long cid, @Param("amount")BigDecimal amount);

    @Transactional(rollbackFor = Exception.class)
    @Modifying
    @Query("update ContractCoin coin set coin.totalOpenFee=coin.totalOpenFee+:openFee where coin.id = :cid")
    void increaseOpenFee(@Param("cid")Long cid, @Param("openFee")BigDecimal openFee);

    @Transactional(rollbackFor = Exception.class)
    @Modifying
    @Query("update ContractCoin coin set coin.totalCloseFee=coin.totalCloseFee+:closeFee where coin.id = :cid")
    void increaseCloseFee(@Param("cid")Long cid, @Param("closeFee")BigDecimal closeFee);

    @Query(value="select sum(total_profit) as total_profit from contract_coin a where a.enable = 1",nativeQuery = true)
    BigDecimal sumTotalProfit();
    
    @Query(value="select sum(total_loss) as total_loss from contract_coin a where a.enable = 1",nativeQuery = true)
    BigDecimal sumTotalLoss();
    
    @Query(value="SELECT coin.symbol, stat.volume FROM contract_coin coin left JOIN (SELECT contract_id, sum(open_price*total_position) as volume FROM member_contract_position where create_time between :startTime and :endTime group by contract_id) stat on coin.id = stat.contract_id",nativeQuery = true)
	Object[][] statVolume(@Param("startTime")String startTime, @Param("endTime")String endTime);
}
