package com.czg.service.order.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSONObject;
import com.czg.EntryManager;
import com.czg.OcrUtils;
import com.czg.PayCst;
import com.czg.config.RabbitPublisher;
import com.czg.constants.ParamCodeCst;
import com.czg.dto.req.*;
import com.czg.order.entity.ShopDirectMerchant;
import com.czg.service.order.dto.AggregateMerchantVO;
import com.czg.service.order.dto.MerchantQueryDTO;
import com.czg.service.order.mapper.ShopDirectMerchantMapper;
import com.czg.service.order.service.ShopDirectMerchantService;
import com.czg.system.service.SysParamsService;
import com.czg.utils.FunUtils;
import com.czg.utils.PageUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicLong;

/**
 * 商户进件 服务层实现。
 *
 * @author ww
 * @since 2026-01-07
 */
@Service
public class ShopDirectMerchantServiceImpl extends ServiceImpl<ShopDirectMerchantMapper, ShopDirectMerchant> implements ShopDirectMerchantService {

    @Resource
    private RabbitPublisher rabbitPublisher;
    @DubboReference
    private SysParamsService sysParamsService;


    // 全局原子计数器，按天重置（避免数值过大）
    private static final AtomicLong COUNTER = new AtomicLong(0);
    // 记录上一次的日期，用于重置计数器
    private static String LAST_DATE = DateUtil.format(new Date(), "yyyyMMdd");

    @Override
    public JSONObject getInfoByImg(String url, String type) throws Exception {
        Map<String, String> aliOssKeys = sysParamsService.getParamsByMap("ali_oss_key_set", ParamCodeCst.ALI_OSS_KEY_SET);
        return OcrUtils.getInfoByImg(aliOssKeys.get(ParamCodeCst.AliYun.ALI_SMS_KEY), aliOssKeys.get(ParamCodeCst.AliYun.ALI_SMS_SECRET), url, type);
    }

    @Override
    public Page<ShopDirectMerchant> getEntryList(MerchantQueryDTO queryParam) {
        PageHelper.startPage(queryParam.getPage(), queryParam.getSize());
        List<ShopDirectMerchant> entryList = mapper.getEntryList(queryParam);
        return PageUtil.convert(new PageInfo<>(entryList));
    }

    @Override
    public AggregateMerchantVO getEntry(Long shopId) {
        ShopDirectMerchant merchant = getOne(query()
                .eq(ShopDirectMerchant::getShopId, shopId));
        if (merchant == null) {
            return null;
        }
        return convertVO(merchant);
    }

    @Override
    public boolean entryManager(AggregateMerchantDto reqDto) {
        boolean isSave = false;
        boolean result;
        if (StrUtil.isBlank(reqDto.getMerchantCode())) {
            reqDto.setMerchantCode(getMerchantCode());
            isSave = true;
        }
        EntryManager.verifyEntryParam(reqDto);


        ShopDirectMerchant merchant = new ShopDirectMerchant();
        merchant.setShopId(reqDto.getShopId());
        merchant.setMerchantCode(reqDto.getMerchantCode());
        merchant.setLicenceNo(reqDto.getBusinessLicenceInfo().getLicenceNo());

        MerchantBaseInfoDto merchantBaseInfo = reqDto.getMerchantBaseInfo();
        merchant.setAlipayAccount(merchantBaseInfo.getAlipayAccount());
        merchant.setUserType(merchantBaseInfo.getUserType());
        merchant.setShortName(merchantBaseInfo.getShortName());

        merchant.setMerchantBaseInfo(JSONObject.toJSONString(reqDto.getMerchantBaseInfo()));
        merchant.setLegalPersonInfo(JSONObject.toJSONString(reqDto.getLegalPersonInfo()));
        merchant.setBusinessLicenceInfo(JSONObject.toJSONString(reqDto.getBusinessLicenceInfo()));
        merchant.setStoreInfo(JSONObject.toJSONString(reqDto.getStoreInfo()));
        merchant.setSettlementInfo(JSONObject.toJSONString(reqDto.getSettlementInfo()));

        if (isSave) {
            merchant.setAlipayStatus(PayCst.EntryStatus.WAIT);
            merchant.setWechatStatus(PayCst.EntryStatus.WAIT);
            result = save(merchant);
        } else {
            ShopDirectMerchant directMerchant = getById(reqDto.getShopId());
            if (directMerchant.getAlipayStatus().equals(PayCst.EntryStatus.INIT) || directMerchant.getAlipayStatus().equals(PayCst.EntryStatus.REJECTED)) {
                merchant.setAlipayStatus(PayCst.EntryStatus.WAIT);
            }
            if (directMerchant.getWechatStatus().equals(PayCst.EntryStatus.INIT) || directMerchant.getWechatStatus().equals(PayCst.EntryStatus.REJECTED)) {
                merchant.setWechatStatus(PayCst.EntryStatus.WAIT);
            }
            result = updateById(merchant);
        }
        //发送进件队列消息
        FunUtils.transactionSafeRun(() -> rabbitPublisher.sendEntryManagerMsg(reqDto.getShopId() + ":" + merchant.getLicenceNo()));
        return result;
    }

    private static String getMerchantCode() {
        Date now = new Date();
        // 1. 获取当前日期（yyyyMMdd）
        String currentDate = DateUtil.format(now, "yyyyMMdd");
        // 2. 每天重置计数器，避免数值溢出
        synchronized (COUNTER) {
            if (!currentDate.equals(LAST_DATE)) {
                COUNTER.set(0);
                LAST_DATE = currentDate;
            }
        }
        // 3. 原子递增，获取唯一序号（同一毫秒内不会重复）
        long seq = COUNTER.incrementAndGet();
        // 4. 时间戳（毫秒级）+ 6位序号（补零）
        String timeStr = DateUtil.format(now, "yyyyMMddHHmmss");
        String seqStr = String.format("%03d", seq);
        return "CZG" + timeStr + seqStr;
    }


    public AggregateMerchantVO convertVO(ShopDirectMerchant entity) {
        if (entity == null) {
            return null;
        }

        AggregateMerchantVO vo = new AggregateMerchantVO();
        vo.setShopId(entity.getShopId());
        vo.setMerchantCode(entity.getMerchantCode());
        vo.setShopName(entity.getShopName());

        // 解析JSON字段
        vo.setMerchantBaseInfo(JSONObject.parseObject(entity.getMerchantBaseInfo(), MerchantBaseInfoDto.class));
        vo.setLegalPersonInfo(JSONObject.parseObject(entity.getLegalPersonInfo(), LegalPersonInfoDto.class));
        vo.setBusinessLicenceInfo(JSONObject.parseObject(entity.getBusinessLicenceInfo(), BusinessLicenceInfoDto.class));
        vo.setStoreInfo(JSONObject.parseObject(entity.getStoreInfo(), StoreInfoDto.class));
        vo.setSettlementInfo(JSONObject.parseObject(entity.getSettlementInfo(), SettlementInfoDto.class));

        // 设置其他字段
        vo.setUserType(entity.getUserType());
        vo.setShortName(entity.getShortName());
        vo.setAlipayAccount(entity.getAlipayAccount());
        vo.setCreateTime(entity.getCreateTime());
        vo.setUpdateTime(entity.getUpdateTime());
        vo.setWechatApplyId(entity.getWechatApplyId());
        vo.setWechatStatus(entity.getWechatStatus());
        vo.setWechatErrorMsg(entity.getWechatErrorMsg());
        vo.setWechatSignUrl(entity.getWechatSignUrl());
        vo.setAlipayOrderId(entity.getAlipayOrderId());
        vo.setAlipayStatus(entity.getAlipayStatus());
        vo.setAlipayErrorMsg(entity.getAlipayErrorMsg());
        vo.setAlipaySignUrl(entity.getAlipaySignUrl());

        return vo;
    }
}
