package com.fzm.mall.server.front.asset.mapper;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fzm.mall.server.front.asset.model.UserAsset;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.fzm.mall.server.front.asset.model.po.qo.CoinLogQO;
import com.fzm.mall.server.front.asset.model.po.qo.CoinQO;
import com.fzm.mall.server.front.asset.model.vo.coin.CoinLogVO;
import com.fzm.mall.server.front.asset.model.vo.coin.UserCoinVO;
import com.fzm.mall.server.front.asset.sql.CoinSqlFactory;
import org.apache.ibatis.annotations.*;
import org.springframework.stereotype.Repository;

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

/**
 * <p>
 * 用户资产信息表 Mapper 接口
 * </p>
 *
 * @author fzm
 * @since 2021-03-01
 */
@Mapper
@Repository
public interface UserAssetMapper extends BaseMapper<UserAsset> {
    /**
     * 查询用户指定资产
     */
    @Select("select  uc.`coin`, uc.`amount`, uc.`frozen`, spu.name, " +
            "from user_asset uc " +
            "left join goods_sku sku on uc.coin = sku.coin_name and sku.status = 1 " +
            "left join goods_spu spu on sku.goods_id = spu.goods_id " +
            "where uc.uid = #{uid} and uc.coin = #{coin}")
    UserAsset coin(@Param("uid") String uid, @Param("isToken") String isToken, @Param("coin") String coin, @Param("block") String block);

    List<UserAsset> searchAssetLike(@Param("uid") String uid,
                                    @Param("type") Integer type,
                                    @Param("keyWord") String keyWord);

    /**
     * 分页查询用户账户资产
     */
    @SelectProvider(type = CoinSqlFactory.class, method = "listCoin")
    List<UserAsset> listCoin(CoinQO coinQO);

    /**
     * 分页查询用户账户资产
     */
    @SelectProvider(type = CoinSqlFactory.class, method = "countCoin")
    Integer countCoin(CoinQO coinQO);

    /**
     * 分页查询用户账户资产日志
     */
    @SelectProvider(type = CoinSqlFactory.class, method = "listLog")
    List<CoinLogVO> listLog(CoinLogQO coinLogQO);

    /**
     * 分页查询用户账户资产日志
     */
    @SelectProvider(type = CoinSqlFactory.class, method = "countLog")
    Integer countLog(CoinLogQO coinLogQO);

    /**
     * 查询用户是否有指定币
     */
    @Select("select id from user_asset where uid = #{uid} and is_token = #{isToken} and coin = #{coin} and block = #{block}")
    Integer coinExist(@Param("uid") String uid, @Param("isToken") Integer isToken, @Param("coin") String coin, @Param("block") Integer block);

    /**
     * 保存用户指定币
     */
    @Insert("insert into user_asset(uid, is_token, coin, block, amount, update_time) values(#{uid}, #{isToken}, #{coin}, #{block}, #{amount}, #{timestamp})")
    Integer saveUserCoin(@Param("uid") String uid, @Param("isToken") Integer isToken, @Param("coin") String coin, @Param("block") Integer block, @Param("amount") String amount, @Param("timestamp") long timestamp);

    /**
     * 查询是否有充足的指定币
     */
    @Select("select id from user_asset where uid = #{uid} and is_token = #{isToken} and coin = #{coin} and block = #{block} and amount - #{amount} >=0")
    Integer coinEnough(@Param("uid") String uid, @Param("isToken") Integer isToken, @Param("coin") String coin, @Param("block") Integer block, @Param("amount") String amount);

    /**
     * 减少用户的指定币
     */
    @Update("update user_asset set amount = amount - #{amount}, update_time = #{timestamp} where uid = #{uid} and is_token = #{isToken} and coin = #{coin} and block = #{block} and amount - #{amount} >=0")
    Integer updateMinusCoin(@Param("uid") String uid, @Param("isToken") Integer isToken, @Param("coin") String coin, @Param("block") Integer block, @Param("amount") String amount, @Param("timestamp") long timestamp);

    /**
     * 增加用户指定币
     */
    @Update("update user_asset set amount = amount + #{amount}, update_time = #{timestamp} where uid = #{uid} and is_token = #{isToken} and coin = #{coin} and block = #{block}")
    Integer updateAddCoin(@Param("uid") String uid, @Param("isToken") Integer isToken, @Param("coin") String coin, @Param("block") Integer block, @Param("amount") String amount, @Param("timestamp") long timestamp);

    /**
     * 冻结用户指定币
     */
    @Update("update user_asset set amount = amount - #{amount}, frozen = frozen + #{amount}, update_time = #{timestamp} where uid = #{uid} and is_token = #{isToken} and coin = #{coin} and block = #{block} and amount - #{amount} >=0")
    Integer frozen(@Param("uid") String uid, @Param("isToken") Integer isToken, @Param("coin") String coin, @Param("block") Integer block, @Param("amount") String amount, @Param("timestamp") long timestamp);

    /**
     * 解冻用户指定币
     */
    @Update("update user_asset set amount = amount + #{amount}, frozen = frozen - #{amount}, update_time = #{timestamp} where uid = #{uid} and is_token = #{isToken} and coin = #{coin} and block = #{block} and frozen-#{amount} >= 0")
    Integer unfrozen(@Param("uid") String uid, @Param("isToken") Integer isToken, @Param("coin") String coin, @Param("block") Integer block, @Param("amount") String amount, @Param("timestamp") long timestamp);

    /**
     * 减少用户的指定冻结币
     */
    @Update("update user_asset set frozen = frozen - #{amount}, update_time = #{timestamp} where uid = #{uid} and is_token = #{isToken} and coin = #{coin} and block = #{block} and frozen-#{amount} >= 0")
    Integer updateMinusCoinfrozen(@Param("uid") String uid, @Param("isToken") Integer isToken, @Param("coin") String coin, @Param("block") Integer block, @Param("amount") String amount, @Param("timestamp") long timestamp);

    @Update("update user_asset set frozen = frozen + #{amount}, update_time = #{timestamp} where uid = #{uid} and is_token = #{isToken} and coin = #{coin} and block = #{block}")
    Integer updateAddCoinfrozen(@Param("uid") String uid, @Param("isToken") Integer isToken, @Param("coin") String coin, @Param("block") Integer block, @Param("amount") String amount, @Param("timestamp") long timestamp);

    @Select(" <script>" +
            " select uid,block,is_token,coin,amount,frozen" +
            " from user_asset where uid = #{uid} and coin in " +
            " <foreach collection='coins' open='(' item='coinItem' separator=',' close=')'> #{coinItem}</foreach> " +
            " </script>")
    List<UserAsset> coinList(@Param("uid") String uid, @Param("coins") List<String> coins);

    @Select("select uid,block,is_token,coin,amount,frozen from user_coin where uid = #{uid}")
    List<UserAsset> userCoinList(@Param("uid") String uid);

    @Update("update user_asset set amount = amount - #{unpaidAmount} where uid = #{uid} and coin = #{coinName} and amount >= #{unpaidAmount}")
    int delAsset(@Param("uid") String uid, @Param("unpaidAmount") BigDecimal unpaidAmount, @Param("coinName") String coinName);

    @Select("select * from user_asset where uid = #{uid} and amount >0 and goods_coin != 'BASE' limit #{start},#{size}")
    List<UserAsset> getList(@Param("uid") String uid, @Param("start") int start, @Param("size") Integer size);

    @Select("select count(*) from user_asset where uid = #{uid} and amount >0 and coin != 'BASE' ")
    Integer getCount(@Param("uid") String uid);

    @Select("select IFNULL(sum(a.amount * b.original_price),0) from user_asset a left join goods_sku b on a.goods_coin = b.coin_name where a.uid = #{uid} and a.amount > 0 and a.coin != #{mallCoin}")
    BigDecimal getAllNotMallCoin(@Param("uid") String uid,@Param("mallCoin") String mallCoin);

    @Update("update user_asset set amount = amount + #{amount} where id = #{id}")
    void addCoin(@Param("id") Long id, @Param("amount") BigDecimal amount);

    @Update("update user_asset set amount = amount - #{number},frozen = frozen + #{number} where uid = #{uid} and coin = #{coin} and amount >= #{number}")
    int frozenUserAssets(@Param("uid") String uid, @Param("coin") String coin, @Param("number") Integer number);

    @Update("update user_asset set amount = amount + #{number},frozen = frozen - #{number} where uid = #{uid} and coin = #{coin} and frozen >= #{number}")
    int unfrozenUserAsset(@Param("uid") String uid, @Param("number") Integer number, @Param("coin") String coin);


    @Update("update user_asset set frozen = frozen + #{amount} where id = #{id}")
    void addUserfrozenAsset(@Param("id") Long id, @Param("amount") BigDecimal amount);

    @Update("update user_asset set frozen = frozen - #{amount},update_time = (select REPLACE(unix_timestamp(current_timestamp(3)),'.',''))  where id = #{id} and frozen >= #{amount} ")
    int deleteFrozen(@Param("id") Long id, @Param("amount") BigDecimal amount);

    @Update("update user_asset set amount = amount - #{amount}  where id = #{id} and amount >= #{amount}")
    int deleteAmount(@Param("id") Long id, @Param("amount") BigDecimal amount);

    @Select("select * from user_asset where uid = #{uid} and coin = #{coin}")
    UserAsset getCoin(@Param("uid") String uid, @Param("coin") String value);
}
