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


import cn.fzm.chain.simplesdk.client.MainChainClient;
import cn.fzm.chain.simplesdk.constant.TxStatusEnum;
import cn.fzm.chain.simplesdk.model.Balance;
import cn.fzm.chain.simplesdk.model.TxResult;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.service.IService;
import com.fzm.mall.server.front.asset.model.UserAsset;
import com.fzm.mall.server.front.asset.model.dto.AssetTranDTO;
import com.fzm.mall.server.front.asset.model.po.qo.OrderQO;
import com.fzm.mall.server.front.asset.model.vo.asset.UserAssetVo;
import com.fzm.mall.server.front.asset.model.vo.order.OrderPageVo;
import com.fzm.mall.server.front.asset.service.IUserAssetService;
import com.fzm.mall.server.front.base.PageVO;
import com.fzm.mall.server.front.base.ResponseVO;
import com.fzm.mall.server.front.constant.MallResponseEnum;
import com.fzm.mall.server.front.constant.PageConst;
import com.fzm.mall.server.front.enums.QueueTTLTypeEnum;
import com.fzm.mall.server.front.goods.model.vo.SkuVo;
import com.fzm.mall.server.front.goods.service.ISkuService;
import com.fzm.mall.server.front.mq.MsgProducer;
import com.fzm.mall.server.front.order.model.po.TranDto;
import com.fzm.mall.server.front.order.model.vo.DeliveryVO;
import com.fzm.mall.server.front.order.service.IOrderService;
import com.fzm.mall.server.front.user.model.Header;
import com.fzm.mall.server.front.user.model.User;
import com.fzm.mall.server.front.user.service.IRedisService;
import com.fzm.mall.server.front.user.service.IUserService;
import com.fzm.mall.server.front.valid.LongValid;
import io.netty.util.internal.StringUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import springfox.documentation.annotations.ApiIgnore;

import java.math.BigDecimal;

/**
 * <p>
 * 用户资产信息表 前端控制器
 * </p>
 *
 * @author fzm
 * @since 2021-03-01
 */
@Api(tags = "资产接口", description = "用户资产")
@Slf4j
@RestController
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
@RequestMapping("/mall/asset")
public class UserAssetController {
    private final IUserService userService;
    private final IUserAssetService userAssetService;
    private final ISkuService skuService;
    private final MainChainClient mainChainClient;
    private final IRedisService redisService;

    @ApiOperation(value = "分页查询用户资产")
    @PostMapping("/select")
    public ResponseVO<PageVO<UserAsset>> pageAsset(@RequestBody UserAssetVo userAssetVo, @ApiIgnore @RequestAttribute Header header) {
        String page = userAssetVo.getPage();
        String size = userAssetVo.getSize();
        if (!LongValid.positiveLong(page)) {
            page = PageConst.DEFAULT_PAGE;
        }
        if (!LongValid.positiveLong(size)) {
            size = PageConst.DEFAULT_SIZE;
        }
        userAssetVo.setPage(page);
        userAssetVo.setSize(size);
        userAssetVo.setUid(header.getUid());
        PageVO<UserAsset> pageAsset = userAssetService.pageAsset(userAssetVo);
        return new ResponseVO<>(MallResponseEnum.SUCCESS, pageAsset);
    }

    @ApiOperation(value = "查询我的资产")
    @PostMapping("/getOwnAsset")
    public ResponseVO<UserAssetVo> getOwnAsset(@ApiParam(name = "coin", value = "币名称") @RequestBody JSONObject obj, @ApiIgnore @RequestAttribute Header header) {
        String uid = header.getUid();
        String coin = obj.getString("coin");
        SkuVo skuVo = skuService.querySkuByCoin(coin);
        UserAssetVo userAssetVo = userAssetService.getOwnAsset(uid, coin);
        userAssetVo.setSkuVo(skuVo);
        User user = userService.getByUid(uid);
        userAssetVo.setAddress(user.getAddress());
        return new ResponseVO<>(MallResponseEnum.SUCCESS, userAssetVo);
    }


    @ApiOperation(value = "资产转账")
    @PostMapping("/assetTran")
    public ResponseVO<String> assetTran(@RequestBody AssetTranDTO assetTranDto, @ApiIgnore @RequestAttribute Header header) {
        String uid = header.getUid();
        User user = userService.getByUid(uid);
        String res = "";
        try {
            if (!redisService.setNx(uid + "assetTran")) {
                return new ResponseVO<>(MallResponseEnum.OPERATION_OFTEN);
            }
            res = userAssetService.mallAssetTrans(assetTranDto, user);
            redisService.del(uid + "assetTran");
        } catch (Exception e) {
            redisService.del(uid + "assetTran");
            if (StringUtil.isNullOrEmpty(e.getMessage())) {
                log.error(e.toString());
                return new ResponseVO<>(MallResponseEnum.DB_ERROR);
            }
            if (e.getMessage().contains("asset_not_enough")) {
                return new ResponseVO<>(MallResponseEnum.ASSET_NOT_ENOUGH);
            }
            if (e.getMessage().contains("address_not_exist")) {
                return new ResponseVO<>(MallResponseEnum.ADDRESS_NOT_EXIST);
            }
        }
        return new ResponseVO<>(MallResponseEnum.SUCCESS, res);
    }

    @ApiOperation(value = "查询链上资产")
    @PostMapping("/getAssetTran")
    public ResponseVO<Balance> getAssetTran(@RequestBody AssetTranDTO assetTranDto, @ApiIgnore @RequestAttribute Header header) {
        Balance balance = mainChainClient.tokenBalance(assetTranDto.getOtherAddress(), assetTranDto.getCoin());
        return new ResponseVO<>(MallResponseEnum.SUCCESS, balance);
    }

    @ApiOperation(value = "增发链上资产")
    @PostMapping("/addAssetTran")
    public ResponseVO<String> addAssetTran(@RequestBody AssetTranDTO assetTranDto, @ApiIgnore @RequestAttribute Header header) {
        String uid = header.getUid();
        User user = userService.getByUid(uid);
        //Balance balance= mainChainClient.tokenBalance(user.getAddress(), assetTranDto.getCoin());
        String hash = mainChainClient.mainTokenMint(assetTranDto.getCoin(), user.getAddress(), null, assetTranDto.getAmount());
        TxResult tr = mainChainClient.cycleConfirmTxWithHash(hash, false, 1000);
        if (tr.getStatus() != TxStatusEnum.SUCCESS) {
            log.error("TOKEN增发失败，交易HASH:{},失败原因：{}", hash, tr.getErrMsg());
            return new ResponseVO<>(MallResponseEnum.SUCCESS, "failed");
            //map.put("errMsg", tr.getErrMsg().getValue());
        }
        return new ResponseVO<>(MallResponseEnum.SUCCESS, "success");
    }
}
