package com.maintain.business.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.maintain.business.domain.ErpRepairForm;
import com.maintain.business.domain.ErpSettlementMaintainRepairForm;
import com.maintain.business.domain.bo.ErpSettlementMaintainRepairFormBo;
import com.maintain.business.mapper.ErpRepairFormMapper;
import com.maintain.business.mapper.ErpSettlementMaintainRepairFormMapper;
import com.maintain.common.enums.RepairFormSettlementState;
import com.maintain.common.enums.SettlementState;
import com.maintain.common.helper.LoginHelper;
import com.maintain.common.utils.StringUtils;
import com.maintain.common.core.page.TableDataInfo;
import com.maintain.common.core.domain.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.maintain.common.utils.redis.RedisUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import com.maintain.business.domain.bo.ErpSettlementMaintainBo;
import com.maintain.business.domain.vo.ErpSettlementMaintainVo;
import com.maintain.business.domain.ErpSettlementMaintain;
import com.maintain.business.mapper.ErpSettlementMaintainMapper;
import com.maintain.business.service.IErpSettlementMaintainService;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Collection;
import java.util.stream.Collectors;

/**
 * 结算维修单Service业务层处理
 *
 * @author liushuai
 * @date 2025-04-03
 */
@RequiredArgsConstructor
@Service
public class ErpSettlementMaintainServiceImpl implements IErpSettlementMaintainService {

    private final ErpSettlementMaintainMapper baseMapper;
    private final ErpSettlementMaintainRepairFormMapper settlementMaintainRepairFormMapper;
    private final ErpRepairFormMapper repairFormMapper;

    /**
     * 查询结算维修单
     */
    @Override
    public ErpSettlementMaintainVo queryById(Long id){
        return baseMapper.selectVoById(id);
    }

    /**
     * 查询结算维修单列表
     */
    @Override
    public TableDataInfo<ErpSettlementMaintainVo> queryPageList(ErpSettlementMaintainBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<ErpSettlementMaintain> lqw = buildQueryWrapper(bo);
        Page<ErpSettlementMaintainVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询结算维修单列表
     */
    @Override
    public List<ErpSettlementMaintainVo> queryList(ErpSettlementMaintainBo bo) {
        LambdaQueryWrapper<ErpSettlementMaintain> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<ErpSettlementMaintain> buildQueryWrapper(ErpSettlementMaintainBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<ErpSettlementMaintain> lqw = Wrappers.lambdaQuery();
        lqw.like(StringUtils.isNotBlank(bo.getSettlementNumber()), ErpSettlementMaintain::getSettlementNumber, bo.getSettlementNumber());
        lqw.eq(bo.getClientId() != null, ErpSettlementMaintain::getClientId, bo.getClientId());
        lqw.like(StringUtils.isNotBlank(bo.getClientName()), ErpSettlementMaintain::getClientName, bo.getClientName());
        lqw.like(StringUtils.isNotBlank(bo.getClientPhone()), ErpSettlementMaintain::getClientPhone, bo.getClientPhone());
        lqw.eq(bo.getClientType() != null, ErpSettlementMaintain::getClientType, bo.getClientType());
        lqw.eq(bo.getClientCertificateType() != null, ErpSettlementMaintain::getClientCertificateType, bo.getClientCertificateType());
        lqw.eq(StringUtils.isNotBlank(bo.getClientCertificateNumber()), ErpSettlementMaintain::getClientCertificateNumber, bo.getClientCertificateNumber());
        lqw.eq(bo.getState() != null, ErpSettlementMaintain::getState, bo.getState());
        lqw.eq(bo.getCreateDeptId() != null, ErpSettlementMaintain::getCreateDeptId, bo.getCreateDeptId());
        lqw.orderByDesc(ErpSettlementMaintain::getCreateTime);
        return lqw;
    }

    /**
     * 新增结算维修单
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean insertByBo(ErpSettlementMaintainBo bo) {
        ErpSettlementMaintain add = BeanUtil.toBean(bo, ErpSettlementMaintain.class);
        validEntityBeforeSave(add);
        add.setSettlementNumber(RedisUtils.generateNextNumber("BXJS"));
        add.setCreateDeptId(LoginHelper.getDeptId());
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            settlementMaintainRepairFormMapper.insertBatch(bo.getRepairFormIds().stream().map(item -> {
                ErpSettlementMaintainRepairForm repairForm = new ErpSettlementMaintainRepairForm();
                repairForm.setRepairFormId(item);
                repairForm.setSettlementMaintainId(add.getId());
                return repairForm;
            }).collect(Collectors.toList()));
            repairFormMapper.updateBatchById(bo.getRepairFormIds().stream().map(item ->{
                ErpRepairForm repairForm = new ErpRepairForm();
                repairForm.setId(item);
                repairForm.setSettlementTime(new Date());
                repairForm.setSettlementState(RepairFormSettlementState.TWO.getCode());
                return repairForm;
            }).collect(Collectors.toList()));
        }
        return flag;
    }

    /**
     * 修改结算维修单
     */
    @Override
    public Boolean updateByBo(ErpSettlementMaintainBo bo) {
        ErpSettlementMaintain update = BeanUtil.toBean(bo, ErpSettlementMaintain.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(ErpSettlementMaintain entity){
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除结算维修单
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        boolean flag = baseMapper.deleteBatchIds(ids) > 0;
        if (flag) {
            // 查出所有关联的报修单
            LambdaQueryWrapper<ErpSettlementMaintainRepairForm> lqw = Wrappers.lambdaQuery();
            lqw.in(ErpSettlementMaintainRepairForm::getSettlementMaintainId, ids);
            List<ErpSettlementMaintainRepairForm> repairFormList = settlementMaintainRepairFormMapper.selectList(lqw);

            // 关联的报修单状态更改至待结算
            LambdaUpdateWrapper<ErpRepairForm> luw = Wrappers.lambdaUpdate();
            luw.in(ErpRepairForm::getId, repairFormList.stream().map(ErpSettlementMaintainRepairForm::getRepairFormId).collect(Collectors.toList()))
                .set(ErpRepairForm::getSettlementState, RepairFormSettlementState.TWO.getCode());
            repairFormMapper.update(luw);
            // 删除结算单与报修单关联关系表数据
            settlementMaintainRepairFormMapper.deleteBatchIds(repairFormList.stream().map(ErpSettlementMaintainRepairForm::getId).collect(Collectors.toList()));
        }
        return flag;
    }

    /**
     * 结算维修单回执
     *
     * @param bo
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean receiptByBo(ErpSettlementMaintainBo bo) {
        ErpSettlementMaintain settlementMaintain = baseMapper.selectById(bo.getId());
        settlementMaintain.setCollectionTime(bo.getCollectionTime());
        settlementMaintain.setCollectionVoucher(bo.getCollectionVoucher());
        settlementMaintain.setCollectionAccount(bo.getCollectionAccount());
        settlementMaintain.setCollectionSerialNumber(bo.getCollectionSerialNumber());
        settlementMaintain.setCollectionRemark(bo.getCollectionRemark());
        settlementMaintain.setState(SettlementState.TWO.getCode());
        boolean flag = baseMapper.updateById(settlementMaintain) > 0;
        if (flag) {
            // 查出所有关联的报修单
            LambdaQueryWrapper<ErpSettlementMaintainRepairForm> lqw = Wrappers.lambdaQuery();
            lqw.eq(ErpSettlementMaintainRepairForm::getSettlementMaintainId, settlementMaintain.getId());
            List<ErpSettlementMaintainRepairForm> repairFormList = settlementMaintainRepairFormMapper.selectList(lqw);

            // 关联的报修单状态更改至待结算
            LambdaUpdateWrapper<ErpRepairForm> luw = Wrappers.lambdaUpdate();
            luw.in(ErpRepairForm::getId, repairFormList.stream().map(ErpSettlementMaintainRepairForm::getRepairFormId).collect(Collectors.toList()))
                .set(ErpRepairForm::getSettlementState, RepairFormSettlementState.THREE.getCode());
            repairFormMapper.update(luw);
        }
        return flag;
    }
}
