package com.bizzan.bitrade.controller.system;

import com.bizzan.bitrade.annotation.AccessLog;
import com.bizzan.bitrade.constant.AdminModule;
import com.bizzan.bitrade.constant.PageModel;
import com.bizzan.bitrade.controller.common.BaseAdminController;
import com.bizzan.bitrade.dao.CoinNetworkConfigDao;
import com.bizzan.bitrade.dao.CoinNetworkDao;
import com.bizzan.bitrade.entity.CoinNetwork;
import com.bizzan.bitrade.entity.CoinNetworkConfig;
import com.bizzan.bitrade.service.CoinNetworkConfigService;
import com.bizzan.bitrade.service.CoinNetworkService;
import com.bizzan.bitrade.util.MessageResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.web.bind.annotation.*;

/**
 * 币种主网配置管理
 */
@RestController
@RequestMapping("/system/coin-network-config")
@Slf4j
public class CoinNetworkConfigController extends BaseAdminController {

    @Autowired
    private CoinNetworkConfigService coinNetworkConfigService;

    @Autowired
    private CoinNetworkConfigDao coinNetworkConfigDao;

    @Autowired
    private CoinNetworkService coinNetworkService;

    @RequiresPermissions("system:coin-network-config:page-query")
    @PostMapping("page-query")
    @AccessLog(module = AdminModule.SYSTEM, operation = "分页查询币种主网配置")
    public MessageResult pageQuery(PageModel pageModel) {
        PageRequest pageable = new PageRequest(
                pageModel.getPageNo() - 1,
                pageModel.getPageSize(),
                new Sort(Sort.Direction.ASC, "sort")
        );
        Page<CoinNetworkConfig> pageResult = coinNetworkConfigDao.findAll(pageable);
        return success(pageResult);
    }

    /**
     * 下拉：指定主网下可配置的子币种（parent_coin_name 不为空且未配置）
     */
    @PostMapping("available-coins")
    @AccessLog(module = AdminModule.SYSTEM, operation = "查询主网下可配置币种")
    public MessageResult availableCoins(
            @RequestParam("networkId") Long networkId,
            @RequestParam(value = "includeCoinName", required = false) String includeCoinName) {
        if (networkId == null) {
            return error("请选择主网");
        }
        if (coinNetworkService.findById(networkId) == null) {
            return error("主网不存在");
        }
        return success(coinNetworkConfigService.findAvailableCoinNames(networkId, includeCoinName));
    }

    @RequiresPermissions("system:coin-network-config:detail")
    @PostMapping("detail")
    @AccessLog(module = AdminModule.SYSTEM, operation = "查询币种主网配置详情")
    public MessageResult detail(@RequestParam("id") Long id) {
        CoinNetworkConfig config = coinNetworkConfigService.findById(id);
        if (config == null) {
            return error("配置不存在");
        }
        return success(config);
    }

    @RequiresPermissions("system:coin-network-config:create")
    @PostMapping("create")
    @AccessLog(module = AdminModule.SYSTEM, operation = "新增币种主网配置")
    public MessageResult create(
            @RequestParam("coinName") String coinName,
            @RequestParam("networkId") Long networkId,
            @RequestParam(value = "contractAddress", required = false) String contractAddress,
            @RequestParam(value = "rechargeAddress", required = false) String rechargeAddress,
            @RequestParam(value = "contractDecimals", defaultValue = "6") int contractDecimals,
            @RequestParam(value = "scale", defaultValue = "2") int scale,
            @RequestParam(value = "sort", defaultValue = "0") int sort,
            @RequestParam(value = "memo", required = false) String memo) {
        CoinNetworkConfig config = new CoinNetworkConfig();
        config.setCoinName(coinName);
        CoinNetwork network = new CoinNetwork();
        network.setId(networkId);
        config.setNetwork(network);
        config.setContractAddress(contractAddress);
        config.setRechargeAddress(rechargeAddress);
        config.setContractDecimals(contractDecimals);
        config.setScale(scale);
        config.setSort(sort);
        config.setMemo(memo);
        try {
            coinNetworkConfigService.save(config);
        } catch (IllegalArgumentException e) {
            return error(e.getMessage());
        }
        return success();
    }

    @RequiresPermissions("system:coin-network-config:update")
    @PostMapping("update")
    @AccessLog(module = AdminModule.SYSTEM, operation = "更新币种主网配置")
    public MessageResult update(
            @RequestParam("id") Long id,
            @RequestParam("coinName") String coinName,
            @RequestParam("networkId") Long networkId,
            @RequestParam(value = "contractAddress", required = false) String contractAddress,
            @RequestParam(value = "rechargeAddress", required = false) String rechargeAddress,
            @RequestParam(value = "contractDecimals", defaultValue = "6") int contractDecimals,
            @RequestParam(value = "scale", defaultValue = "2") int scale,
            @RequestParam(value = "sort", defaultValue = "0") int sort,
            @RequestParam(value = "memo", required = false) String memo) {
        CoinNetworkConfig config = coinNetworkConfigService.findById(id);
        if (config == null) {
            return error("配置不存在");
        }
        config.setCoinName(coinName);
        CoinNetwork network = new CoinNetwork();
        network.setId(networkId);
        config.setNetwork(network);
        config.setContractAddress(contractAddress);
        config.setRechargeAddress(rechargeAddress);
        config.setContractDecimals(contractDecimals);
        config.setScale(scale);
        config.setSort(sort);
        config.setMemo(memo);
        coinNetworkConfigService.update(config);
        return success();
    }

    @RequiresPermissions("system:coin-network-config:delete")
    @PostMapping("delete")
    @AccessLog(module = AdminModule.SYSTEM, operation = "删除币种主网配置")
    public MessageResult delete(@RequestParam("id") Long id) {
        coinNetworkConfigDao.delete(id);
        return success();
    }
}
