package com.njzscloud.dispose.finance.service;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.njzscloud.common.core.ex.Exceptions;
import com.njzscloud.common.mp.support.PageParam;
import com.njzscloud.common.mp.support.PageResult;
import com.njzscloud.common.sn.support.SnUtil;
import com.njzscloud.dispose.finance.constant.MoneyChangeCategory;
import com.njzscloud.dispose.finance.mapper.MoneyAccountMapper;
import com.njzscloud.dispose.finance.pojo.entity.MoneyAccountEntity;
import com.njzscloud.dispose.finance.pojo.entity.MoneyFlowEntity;
import com.njzscloud.dispose.finance.pojo.param.RechargeParam;
import com.njzscloud.dispose.finance.pojo.param.SearchMoneyAccountParam;
import com.njzscloud.dispose.finance.pojo.result.MoneyAccountResult;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * 资金账户表
 *
 * @author ljw
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class MoneyAccountService extends ServiceImpl<MoneyAccountMapper, MoneyAccountEntity> {

    private final MoneyFlowService moneyFlowService;

    /**
     * 新增
     */
    public void add(MoneyAccountEntity moneyAccountEntity) {
        moneyAccountEntity.setSn(this.generateSn());
        this.save(moneyAccountEntity);
    }

    /**
     * 修改
     */
    @Transactional(rollbackFor = Exception.class)
    public void modify(RechargeParam param) {
        if (param.getRechargeMoney() == null || param.getRechargeMoney().signum() <= 0) {
            throw Exceptions.clierr("充值金额需大于0");
        }
        MoneyAccountEntity accountEntity = this.getById(param.getId());
        if (accountEntity == null) {
            throw Exceptions.clierr("未找到该账户");
        }
        // 记录资金流水
        MoneyFlowEntity flowEntity = new MoneyFlowEntity()
            .setMoneyAccountId(accountEntity.getId())
            .setBeforeBalance(accountEntity.getRecharge())
            // 充值
            .setDelta(param.getRechargeMoney())
            .setMoneyChangeCategory(MoneyChangeCategory.ChongZhi)
            .setFileUrl(param.getFileUrl())
            .setMemo("账户充值");

        accountEntity.setRecharge(accountEntity.getRecharge().add(param.getRechargeMoney()));

        flowEntity.setAfterBalance(accountEntity.getRecharge());
        this.updateById(accountEntity);

        moneyFlowService.save(flowEntity);

        log.info("公司账户充值成功，充值金额：{}，充值前余额：{} -> 充值前余额：{}",
            param.getRechargeMoney(), flowEntity.getBeforeBalance(), flowEntity.getAfterBalance());
    }

    /**
     * 删除
     */
    @Transactional(rollbackFor = Exception.class)
    public void del(List<Long> ids) {
        this.removeBatchByIds(ids);
    }

    /**
     * 详情
     */
    public MoneyAccountResult detail(Long id) {
        return baseMapper.detail(id);
    }

    /**
     * 分页查询
     */
    public PageResult<MoneyAccountResult> paging(PageParam pageParam, SearchMoneyAccountParam param) {
        return PageResult.of(baseMapper.paging(pageParam.toPage(), Wrappers.query()
            .eq("fma.deleted", 0)
            .like(StrUtil.isNotBlank(param.getSn()), "fma.sn", param.getSn())
            .and(StrUtil.isNotBlank(param.getAccountName()), wrapper ->
                wrapper.like("cc.customer_name", param.getAccountName())
                    .or()
                    .like("co.org_name", param.getAccountName())
            )
            .eq(param.getAccountType() != null, "fma.account_type", param.getAccountType())
        ));
    }

    /**
     * 生成账户编号
     *
     * @return sn 账户编号
     */
    public String generateSn() {
        String sn = SnUtil.next("Account-SN");
        if (this.exists(Wrappers.<MoneyAccountEntity>lambdaQuery().eq(MoneyAccountEntity::getSn, sn)
            .eq(MoneyAccountEntity::getDeleted, Boolean.FALSE))) {
            this.generateSn();
        }
        return sn;
    }
}
