package com.qnfhq.modules.c2c.controller;


import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.json.JSONUtil;
import com.qnfhq.annotation.RepeatSubmit;
import com.qnfhq.common.ApiBaseController;
import com.qnfhq.common.constant.Constant;
import com.qnfhq.common.page.PageData;
import com.qnfhq.common.redis.RedisUtils;
import com.qnfhq.common.utils.MessageUtils;
import com.qnfhq.common.utils.Result;
import com.qnfhq.common.validator.ValidatorUtils;
import com.qnfhq.constant.CacheConstants;
import com.qnfhq.modules.c2c.dto.*;
import com.qnfhq.modules.c2c.dto.setting.AdSetting;
import com.qnfhq.modules.c2c.entity.*;
import com.qnfhq.modules.c2c.enums.AdStatusEnum;
import com.qnfhq.modules.c2c.enums.DirectionEnum;
import com.qnfhq.modules.c2c.service.*;
import com.qnfhq.modules.user.entity.SettingEntity;
import com.qnfhq.modules.user.enums.SettingEnum;
import com.qnfhq.modules.user.service.SettingService;
import io.swagger.v3.oas.annotations.Operation;
import jakarta.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;
import io.swagger.v3.oas.annotations.tags.Tag;

/**
 * c2c商家广告
 *
 * @author yelz 30262728@qq.com
 * @since 1.0.0 2025-11-17
 */
@RestController
@RequestMapping("/c2cad")
@Tag(name="c2c商家广告")
public class C2cAdController extends ApiBaseController {
    @Resource
    private C2cAdService c2cAdService;

    @Resource
    private C2cOrderService c2cOrderService;


    @Resource
    private RedisUtils redisUtils;

    @Resource
    private SettingService settingService;

    @Resource
    private C2cUserReceiptService c2cUserReceiptService;

    @Autowired
    private C2cLegalCoinService c2cLegalCoinService;

    @Autowired
    private C2cPayWayService c2cPayWayService;

    @PostMapping("/create")
    @RepeatSubmit(interval = 3000, message = "请求过于频繁")
    @Operation(summary = "创建广告")
    public Result create(@RequestBody C2cAdCreateDTO request) {
        ValidatorUtils.validateEntity(request);

        Result result = new Result();
        Integer direction = request.getDirection();
        if(!DirectionEnum.isValidCode(direction)) {
            return result.error(MessageUtils.message("merchant.param.direction.invalid"));//参数direction值不正确
        }
        String symbol = request.getSymbol().toLowerCase();
        String legalCoin = request.getLegalCoin().toUpperCase();
        Integer priceType = request.getPriceType();
        BigDecimal price = request.getPrice();//价格
        BigDecimal num = request.getNum();//买入/卖出数量
        BigDecimal minAmount = request.getMinAmount();
        BigDecimal maxAmount = request.getMaxAmount();
        String payway = request.getPayway().trim();

        if(minAmount.compareTo(BigDecimal.ZERO)<=0) {
            return result.error(MessageUtils.message("merchant.ad.minAmount.bigger.zero"));//最小限额必须大于0
        }
        if(maxAmount.compareTo(minAmount)<=0) {
            return result.error(MessageUtils.message("merchant.minAmount.smaller.maxAmount"));//最小限额必须小于最大限额
        }
        if(num.compareTo(BigDecimal.ZERO) < 1) {
            return result.error(MessageUtils.message("merchant.num.bigger.zero"));//数量必须大于0
        }
        if(price.compareTo(BigDecimal.ZERO) < 1) {
            return result.error(MessageUtils.message("merchant.price.bigger.zero"));//价格必须大于0
        }
        if(maxAmount.compareTo(price.multiply(num)) == 1) {
            return result.error(MessageUtils.message("merchant.maxAmount.smaller.price.num"));//最大限额必须小于价格和数量之积
        }

        //广告配置
        SettingEntity setting = settingService.getSetting(SettingEnum.AD_SETTING.name());
        List<AdSetting> adSettingsList = JSONUtil.toList(JSONUtil.parseArray(setting.getSettingValue()), AdSetting.class);
        if (!CollectionUtils.isEmpty(adSettingsList)) {
            Map<String, List<AdSetting>> symbolGroup = adSettingsList.stream().collect(Collectors.groupingBy(AdSetting::getSymbol));
            List<AdSetting> symbolSettingList = symbolGroup.get(symbol);
            AdSetting adSet = null;
            for(AdSetting adSetting : symbolSettingList) {
                if(adSetting.getLegalCoin().equals(legalCoin)) {
                    adSet = adSetting;
                    break;
                }
            }
            if(adSet != null) {
                if(price.compareTo(adSet.getMinPrice())==-1) {
                    return result.error(MessageUtils.message("c2cAd.price.must.bigger.set",adSet.getMinPrice()));//价格必须大于{}
                } else if (price.compareTo(adSet.getMaxPrice())==1) {
                    return result.error(MessageUtils.message("c2cAd.price.must.small.set",adSet.getMaxPrice()));//价格必须小于{}
                }
                if(minAmount.compareTo(adSet.getMinAmount())==1) {
                    return result.error(MessageUtils.message("c2cAd.minAmount.must.bigger.set",adSet.getMinAmount()));//最小限额必须大于{}
                }
                if(maxAmount.compareTo(adSet.getMaxAmount())==1) {
                    return result.error(MessageUtils.message("c2cAd.maxAmount.must.small.set",adSet.getMaxAmount()));//最大限额必须小于{}
                }
            }
        }

        try {
            long loginId = StpUtil.getLoginIdAsLong();
            return c2cAdService.createAd(request,loginId);
        } catch (Exception e) {
            return result.error(e.getMessage());
        }
    }


    @PostMapping("/cancel")
    @RepeatSubmit(interval = 3000, message = "请求过于频繁")
    @Operation(summary = "取消广告")
    public Result cancel(@RequestBody C2cAdCancelDTO c2cAd) {
        ValidatorUtils.validateEntity(c2cAd);

        if(c2cAd.getId()==null) {
            return error(MessageUtils.message("c2c.ad.id.blank"));//广告编号不能空
        }

        Long adId = c2cAd.getId();
        C2cAdEntity ad = c2cAdService.selectById(adId);
        if(ad==null) {
            return error(MessageUtils.message("c2c.ad.id.invalid"));//广告编号无效
        }
        if(ad.getUserId().longValue() != StpUtil.getLoginIdAsLong()) {
            return error(MessageUtils.message("c2c.ad.cannot.cancel"));//您无权取消，您不是广告方
        }

        C2cOrderEntity c2cOrder = c2cOrderService.getTradingByAdId(adId);
        if(c2cOrder!=null) {
            return error(MessageUtils.message("c2c.ad.exist.order.cancel"));//当前广告存在进行中的订单，无法取消
        }

        try {
            return c2cAdService.cancelAd(ad);
        } catch (Exception e) {
            return error(e.getMessage());
        }
    }



    @Operation(summary = "商家主页广告列表")
    @PostMapping("/list")
    public Result list(@RequestBody C2cAdListDTO c2cAdVo) {
        ValidatorUtils.validateEntity(c2cAdVo);

        if(c2cAdVo.getMerchantId()==null) {
            return error(MessageUtils.message("c2c.ad.merchant.id.blank"));//商家编号不能空
        }
        //分页
        String pageNum = Convert.toStr(c2cAdVo.getPageNum(),"1");
        String pageSize = Convert.toStr(c2cAdVo.getPageSize(),"10");
        Map<String,Object> params = new HashMap<>();
        params.put(Constant.PAGE,pageNum);
        params.put(Constant.LIMIT,pageSize);
        params.put("merchantId",c2cAdVo.getMerchantId());
        params.put("direction",c2cAdVo.getDirection());
        params.put("status", AdStatusEnum.PASS.getCode());
        PageData<C2cAdEntity> page = c2cAdService.page(params);
        return new Result<PageData<C2cAdEntity>>().ok(page);
    }



    @Operation(summary = "查询我的收款信息列表")
    @PostMapping("/myReceipt")
    public Result myReceipt(@RequestBody C2cMyReceiptDTO dto)
    {
        dto.setUserId(StpUtil.getLoginIdAsLong());
        List<C2cUserReceiptEntity> list = c2cUserReceiptService.selectListMyReceipt(dto);
        return success(list);
    }


    @Operation(summary = "新增收款信息")
    @PostMapping("/addReceipt")
    @RepeatSubmit(interval = 3000, message = "请求过于频繁")
    public Result addReceipt(@RequestBody C2cUserReceiptDTO dto)
    {
        ValidatorUtils.validateEntity(dto);

        C2cUserReceiptEntity inReceipt = new C2cUserReceiptEntity();
        inReceipt.setUserId(StpUtil.getLoginIdAsLong());
        inReceipt.setType(dto.getType());
        inReceipt.setInfo(dto.getInfo());

        if(dto.getId()==null) {
            C2cUserReceiptEntity myReceipt = c2cUserReceiptService.selectOneMyReceipt(StpUtil.getLoginIdAsLong(),dto.getType());
            if(Objects.isNull(myReceipt)) {
                inReceipt.setCreateTime(new Date());
                inReceipt.setUpdateTime(new Date());
                return toAjax(c2cUserReceiptService.insert(inReceipt));
            } else {
                return error(MessageUtils.message("c2c.userReceipt.add.repeat"));//添加成功，请勿重复提交
            }
        } else {
            C2cUserReceiptEntity oldReceipt =c2cUserReceiptService.selectById(dto.getId());
            if(Objects.isNull(oldReceipt)) {
                return error(MessageUtils.message("c2c.userReceipt.id.invalid"));//编号无效
            }
            inReceipt.setId(dto.getId());
            return toAjax(c2cUserReceiptService.updateById(inReceipt));
        }

    }



    @Operation(summary = "快捷交易查询广告")
    @PostMapping("/queryTranAd")
    public Result queryTranAd(@RequestBody C2cAdTranDTO tranDTO)
    {
        ValidatorUtils.validateEntity(tranDTO);
        return c2cAdService.queryTranAd(tranDTO);
    }


    @Operation(summary = "浏览广告")
    @PostMapping("/viewList")
    public Result viewList(@RequestBody C2cAdViewDTO viewDTO) {
        ValidatorUtils.validateEntity(viewDTO);
        return c2cAdService.selectC2cAdViewList(viewDTO);
    }


    @Operation(summary = "查询所有法币列表")
    @PostMapping("/getLegalCoinList")
    public Result getLegalCoinList() {
        Object cacheObject = redisUtils.get(CacheConstants.C2C_LEGAL_COIN_LIST);
        if(null != cacheObject) {
            return new Result().ok(cacheObject);
        }
        List<C2cLegalCoinEntity> coinList = c2cLegalCoinService.selectAllList();
        redisUtils.set(CacheConstants.C2C_LEGAL_COIN_LIST,coinList,2*3600);
        return new Result().ok(coinList);
    }


    @Operation(summary = "查询所有支付方式列表")
    @PostMapping("/getPaywayList")
    public Result getPaywayList(@RequestBody C2cPayWayDTO dto) {
        ValidatorUtils.validateEntity(dto);
        Object cacheObject = redisUtils.get(CacheConstants.C2C_LEGAL_PAYWAY_LIST);
        if(null != cacheObject) {
            return new Result().ok(cacheObject);
        }
        List<C2cPayWayEntity> paywayList = c2cPayWayService.selectListByLegalCoin("");
        redisUtils.set(CacheConstants.C2C_LEGAL_PAYWAY_LIST,paywayList,2*3600);
        return new Result().ok(paywayList);
    }

}
