package com.njzscloud.supervisory.order.service;

import cn.hutool.core.lang.Assert;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.njzscloud.common.core.ex.Exceptions;
import com.njzscloud.supervisory.expense.contant.ExpenseItemCategory;
import com.njzscloud.supervisory.money.contant.MoneyChangeCategory;
import com.njzscloud.supervisory.money.pojo.entity.MoneyAccountEntity;
import com.njzscloud.supervisory.money.pojo.entity.MoneyChangeDetailEntity;
import com.njzscloud.supervisory.money.service.MoneyAccountService;
import com.njzscloud.supervisory.money.service.MoneyChangeDetailService;
import com.njzscloud.supervisory.order.pojo.entity.OrderExpenseItemsEntity;
import com.njzscloud.supervisory.order.pojo.entity.OrderInfoEntity;
import com.njzscloud.supervisory.order.pojo.param.RegulationParam;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.YearMonth;

/**
 * 调账
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class AccountRegulationService {

    private final OrderInfoService orderInfoService;

    private final MoneyAccountService moneyAccountService;

    private final MoneyChangeDetailService moneyChangeDetailService;

    private final OrderExpenseItemsService orderExpenseItemsService;

    /**
     * 业务调账
     */
    @Transactional(rollbackFor = Exception.class)
    public void accountRegulation(RegulationParam param) {
        OrderInfoEntity order = orderInfoService.getOne(Wrappers.<OrderInfoEntity>lambdaQuery()
                .eq(OrderInfoEntity::getSn, param.getSn())
                .eq(OrderInfoEntity::getTransCompanyId, param.getCompanyId()));
        Assert.notNull(order, () -> Exceptions.clierr("当前客户不存在该笔订单，请检查订单号是否正确"));

        // 判断订单创建时间是否在上个月1号和本月26号之间
        LocalDateTime createTime = order.getCreateTime();
        if (createTime != null) {
            LocalDateTime lastMonthFirstDay = YearMonth.now().minusMonths(1).atDay(1).atStartOfDay();
            LocalDateTime currentMonth26th = YearMonth.now().atDay(26).atTime(23, 59, 59);
            boolean isInRange = !createTime.isBefore(lastMonthFirstDay) && !createTime.isAfter(currentMonth26th);
            if (!isInRange) {
                throw Exceptions.clierr("只能对上月1号至本月26号之间的订单调账");
            }
        }

        // 新增一条付费项
        OrderExpenseItemsEntity productItem = new OrderExpenseItemsEntity()
                .setExpenseItemCategory(ExpenseItemCategory.ChanPin.getVal())
                .setOrderId(order.getId())
                .setOriginExpenseItemId(202511081532L)
                .setExpenseItemName("业务调账")
                .setUnitPrice(new BigDecimal("0"))
                .setUnit("Che")
                .setMoneyStrategy("Che")
                .setQuantity(1)
                .setTotalMoney(param.getDelta())
                .setSettleMoney(param.getDelta());
        orderExpenseItemsService.save(productItem);

        // 查询账户
        MoneyAccountEntity accountEntity = moneyAccountService.getOne(Wrappers.<MoneyAccountEntity>lambdaQuery()
                .eq(MoneyAccountEntity::getStationId, param.getCompanyId()));
        if (null == accountEntity) {
            throw Exceptions.clierr("资金账户不存在");
        }
        BigDecimal newMoney = accountEntity.getMoney().add(param.getDelta());
        // 新增一条资金明细
        MoneyChangeDetailEntity changeDetail = new MoneyChangeDetailEntity()
                .setCompanyId(param.getCompanyId())
                .setOrderId(order.getId())
                .setMoneyAccountId(accountEntity.getId())
                .setOldMoney(accountEntity.getMoney())
                .setDelta(param.getDelta())
                .setNewMoney(newMoney)
                .setMoneyChangeCategory(MoneyChangeCategory.DingDanTiaoZhang)
                .setMemo(param.getMemo());

        moneyChangeDetailService.save(changeDetail);

        // 变更资金账户金额
        MoneyAccountEntity companyAccount = new MoneyAccountEntity()
                .setId(accountEntity.getId())
                .setMoney(newMoney);
        moneyAccountService.updateById(companyAccount);

    }

}
