package com.jeesharp.business.modules.finance.profitsharing.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.jeesharp.business.modules.finance.profitsharing.entity.ProfitSharingOrder;
import com.jeesharp.business.modules.finance.profitsharing.enums.ProfitSharingStatusEnum;
import com.jeesharp.business.modules.finance.profitsharing.mapper.ProfitSharingOrderMapper;
import com.jeesharp.business.modules.finance.profitsharing.service.ProfitSharingOrderService;
import com.jeesharp.business.modules.finance.profitsharing.vo.ProfitSharingOrderQueryVO;
import com.jeesharp.framework.mybatis.core.service.CrudService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

/**
 * 微信分账单领域服务实现。
 *
 * @author jeesharp
 * @since 2026-06-11
 */
@Service
@Transactional(readOnly = true)
public class ProfitSharingOrderServiceImpl
        extends CrudService<ProfitSharingOrderMapper, ProfitSharingOrder, ProfitSharingOrderQueryVO>
        implements ProfitSharingOrderService {

    @Override
    public ProfitSharingOrder findByMallOrderId(String mallOrderId) {
        if (StrUtil.isBlank(mallOrderId)) {
            return null;
        }
        LambdaQueryWrapper<ProfitSharingOrder> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ProfitSharingOrder::getMallOrderId, mallOrderId.trim());
        wrapper.last("LIMIT 1");
        return getBaseMapper().selectOne(wrapper);
    }

    @Override
    public List<ProfitSharingOrder> listRetryCandidates(LocalDateTime now, int maxRetryCount, int limit) {
        LambdaQueryWrapper<ProfitSharingOrder> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ProfitSharingOrder::getStatus, ProfitSharingStatusEnum.FAIL.getValue());
        wrapper.le(ProfitSharingOrder::getRetryCount, maxRetryCount);
        if (now != null) {
            wrapper.and(w -> w.isNull(ProfitSharingOrder::getNextRetryTime)
                    .or()
                    .le(ProfitSharingOrder::getNextRetryTime, now));
        }
        wrapper.orderByAsc(ProfitSharingOrder::getNextRetryTime);
        wrapper.last("LIMIT " + Math.max(limit, 1));
        return getBaseMapper().selectList(wrapper);
    }

    @Override
    public List<ProfitSharingOrder> listByPayBatchId(String payBatchId) {
        if (StrUtil.isBlank(payBatchId)) {
            return List.of();
        }
        LambdaQueryWrapper<ProfitSharingOrder> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ProfitSharingOrder::getPayBatchId, payBatchId.trim());
        return getBaseMapper().selectList(wrapper);
    }

    @Override
    public List<ProfitSharingOrder> listByTransactionId(String transactionId) {
        if (StrUtil.isBlank(transactionId)) {
            return List.of();
        }
        LambdaQueryWrapper<ProfitSharingOrder> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ProfitSharingOrder::getTransactionId, transactionId.trim());
        return getBaseMapper().selectList(wrapper);
    }

    @Override
    public boolean isFinishDone(String transactionId, String subMchId) {
        if (StrUtil.isBlank(transactionId) || StrUtil.isBlank(subMchId)) {
            return false;
        }
        LambdaQueryWrapper<ProfitSharingOrder> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ProfitSharingOrder::getTransactionId, transactionId.trim());
        wrapper.eq(ProfitSharingOrder::getSubMchId, subMchId.trim());
        wrapper.eq(ProfitSharingOrder::getFinishStatus, 1);
        wrapper.last("LIMIT 1");
        return getBaseMapper().selectOne(wrapper) != null;
    }

    @Override
    @Transactional(readOnly = false)
    public void markFinishDone(String payBatchId, String transactionId, String subMchId) {
        LambdaQueryWrapper<ProfitSharingOrder> wrapper = new LambdaQueryWrapper<>();
        if (StrUtil.isNotBlank(payBatchId)) {
            wrapper.eq(ProfitSharingOrder::getPayBatchId, payBatchId.trim());
        } else if (StrUtil.isNotBlank(transactionId)) {
            wrapper.eq(ProfitSharingOrder::getTransactionId, transactionId.trim());
        } else {
            return;
        }
        wrapper.eq(ProfitSharingOrder::getSubMchId, subMchId.trim());
        List<ProfitSharingOrder> rows = getBaseMapper().selectList(wrapper);
        for (ProfitSharingOrder row : rows) {
            row.setFinishStatus(1);
            getBaseMapper().updateById(row);
        }
    }

    @Override
    @Transactional(readOnly = false)
    public void cancelSharingForRefund(String mallOrderId, boolean includeFailStatus) {
        if (StrUtil.isBlank(mallOrderId)) {
            return;
        }
        ProfitSharingOrder sharing = findByMallOrderId(mallOrderId);
        if (sharing == null) {
            return;
        }
        String status = sharing.getStatus();
        boolean cancellable = ProfitSharingStatusEnum.PENDING.getValue().equals(status)
                || (includeFailStatus && ProfitSharingStatusEnum.FAIL.getValue().equals(status));
        if (!cancellable) {
            return;
        }
        sharing.setStatus(ProfitSharingStatusEnum.CANCELLED.getValue());
        sharing.setErrorMsg(StrUtil.blankToDefault(sharing.getErrorMsg(), "订单退款，取消待分账"));
        getBaseMapper().updateById(sharing);
    }
}
