package com.jy.business.listener;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson2.JSON;
import com.jy.business.capital.dao.CapitalTransactionsDao;
import com.jy.business.capital.model.dto.CapitalTransactionsDto;
import com.jy.business.capital.model.entity.CapitalTransactions;
import com.jy.business.capital.service.CapitalTransactionsService;
import com.jy.business.config.RabbitConfig;
import com.jy.business.contract.dao.ContractInfoDao;
import com.jy.business.contract.model.entity.ContractInfo;
import com.jy.business.contract.service.ContractInfoService;
import com.jy.framework.model.constants.CommonConstant;
import com.rabbitmq.client.Channel;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.util.Collections;

@Slf4j
@Component
public class JyRabbitListener {

    /**
     * 小程序账号
     */
    private static final Long APPLET_CAPITAL_ACCOUNT_ID = 1846382237635223553L;

    /**
     * 私帐
     */
    private static final Long PRIVATE_CAPITAL_ACCOUNT_ID = 1876190055198384130L;

    /**
     * 公帐
     */
    private static final Long PUBLIC_CAPITAL_ACCOUNT_ID = 1876187625165447170L;

    @Resource
    private CapitalTransactionsService capitalTransactionsService;

    @Resource
    private CapitalTransactionsDao capitalTransactionsDao;

    @Resource
    private ContractInfoService contractInfoService;

    @Resource
    private ContractInfoDao contractInfoDao;

    @Transactional(rollbackFor = Exception.class)
    @RabbitListener(bindings = {
            @QueueBinding(
                    value = @Queue(RabbitConfig.TRANSACTIONS_QUEUE),
                    exchange = @Exchange(RabbitConfig.JY_DIRECT_EXCHANGE)
            )
    })
    public void msgSend(String msg, Channel channel, Message message) throws IOException {
        log.info("消费者收到消息:【{}】", msg);
        long deliveryTag = message.getMessageProperties().getDeliveryTag();

        try {
            CapitalTransactionsDto dto = JSON.parseObject(msg).to(CapitalTransactionsDto.class);
            if (dto.getHandleType() == null) {
                dto.setTargetType(80);
                capitalTransactionsService.add(dto);
            } else {
                handle(dto);
            }

            channel.basicAck(deliveryTag, false);
        } catch (Exception e) {
            channel.basicNack(deliveryTag, false, true);
            log.error("消息消费失败:【{}】", e.getMessage(), e);
        }
    }

    private void handle(CapitalTransactionsDto dto) {
        Integer handleType = dto.getHandleType();
        switch (handleType) {
            case 1 -> handleAdd(dto);
            case 2 -> handleEdit(dto);
            case 3 -> handleDelete(dto);
            default -> {
                log.error("未知的操作类型：{}", handleType);
                throw new IllegalArgumentException("未知的操作类型：" + handleType);
            }
        }
    }

    private void handleAdd(CapitalTransactionsDto dto) {
        CapitalTransactions capitalTransactions = capitalTransactionsDao.lambdaQuery()
                .eq(CapitalTransactions::getOrderId, dto.getOrderId())
                .one();

        if (capitalTransactions != null) {
            return;
        }

        dto.setTargetType(80);

        if (ObjectUtil.equal(dto.getHasApplet(), CommonConstant.YES)) {
            dto.setCapitalAccountId(APPLET_CAPITAL_ACCOUNT_ID);
        } else if (ObjectUtil.equal(dto.getHasPrivate(), CommonConstant.YES)) {
            dto.setCapitalAccountId(PRIVATE_CAPITAL_ACCOUNT_ID);
        } else {
            dto.setCapitalAccountId(PUBLIC_CAPITAL_ACCOUNT_ID);
        }

        capitalTransactionsService.add(dto);

        if (ObjectUtil.equal(dto.getHasBulkOrder(), CommonConstant.YES) && dto.getContractInfo() != null) {
            contractInfoService.add(dto.getContractInfo());
        }
    }

    private void handleEdit(CapitalTransactionsDto dto) {
        handleDelete(dto);
        handleAdd(dto);
    }

    private void handleDelete(CapitalTransactionsDto dto) {
        // 获取资金流水
        CapitalTransactions capitalTransactions = capitalTransactionsDao.lambdaQuery()
                .eq(CapitalTransactions::getOrderId, dto.getOrderId()).one();
        if (capitalTransactions == null) {
            return;
        }
        // 删除资金流水
        capitalTransactionsService.delete(Collections.singletonList(capitalTransactions.getId()));

        // 获取合同
        ContractInfo contractInfo = contractInfoDao.lambdaQuery()
                .eq(ContractInfo::getCapitalTransactionsId, capitalTransactions.getId()).one();
        if (contractInfo == null) {
            return;
        }
        // 删除合同
        contractInfoService.delete(Collections.singletonList(contractInfo.getId()));
    }

}
