package org.dromara.personnel.service.impl;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.dromara.common.core.enums.BusinessStatusEnum;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.core.page.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 lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.personnel.domain.OpsTenderSupplierInput;
import org.dromara.personnel.domain.bo.OpsTenderSupplierInputBo;
import org.dromara.personnel.domain.vo.OpsTenderSupplierInputVo;
import org.dromara.personnel.mapper.OpsTenderSupplierInputMapper;
import org.dromara.personnel.service.IOpsTenderSupplierInputService;
import org.dromara.resource.api.RemoteFileService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 供应商入库Service业务层处理
 *
 * @author LionLi
 * @date 2025-09-24
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class OpsTenderSupplierInputServiceImpl extends ServiceImpl<OpsTenderSupplierInputMapper,OpsTenderSupplierInput> implements IOpsTenderSupplierInputService {

    private final OpsTenderSupplierInputMapper baseMapper;
    private final RemoteFileService remoteFileService;

    /**
     * 查询供应商入库
     *
     * @param id 主键
     * @return 供应商入库
     */
    @Override
    public OpsTenderSupplierInputVo queryById(Long id){
        return baseMapper.selectVoById(id);
    }

    /**
     * 分页查询供应商入库列表
     *
     * @param bo        查询条件
     * @param pageQuery 分页参数
     * @return 供应商入库分页列表
     */
    @Override
    public TableDataInfo<OpsTenderSupplierInputVo> queryPageList(OpsTenderSupplierInputBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<OpsTenderSupplierInput> lqw = buildQueryWrapper(bo);
        Page<OpsTenderSupplierInputVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询符合条件的供应商入库列表
     *
     * @param bo 查询条件
     * @return 供应商入库列表
     */
    @Override
    public List<OpsTenderSupplierInputVo> queryList(OpsTenderSupplierInputBo bo) {
        LambdaQueryWrapper<OpsTenderSupplierInput> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<OpsTenderSupplierInput> buildQueryWrapper(OpsTenderSupplierInputBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<OpsTenderSupplierInput> lqw = Wrappers.lambdaQuery();
        lqw.orderByDesc(OpsTenderSupplierInput::getCreateTime);
        lqw.eq(bo.getProjectId() != null, OpsTenderSupplierInput::getProjectId, bo.getProjectId());
        lqw.eq(StringUtils.isNotBlank(bo.getSupplierType()), OpsTenderSupplierInput::getSupplierType, bo.getSupplierType());
        lqw.like(StringUtils.isNotBlank(bo.getSupplierName()), OpsTenderSupplierInput::getSupplierName, bo.getSupplierName());
        lqw.like(StringUtils.isNotBlank(bo.getState()), OpsTenderSupplierInput::getState, bo.getState());
        return lqw;
    }

    /**
     * 新增供应商入库
     *
     * @param bo 供应商入库
     * @return 是否新增成功
     */
    @Override
    public Boolean insertByBo(OpsTenderSupplierInputBo bo) {
        OpsTenderSupplierInput add = MapstructUtils.convert(bo, OpsTenderSupplierInput.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }
        return flag;
    }

    /**
     * 修改供应商入库
     *
     * @param bo 供应商入库
     * @return 是否修改成功
     */
    @Override
    public Boolean updateByBo(OpsTenderSupplierInputBo bo) {
        if (bo.getId() == null) {
            throw new ServiceException("id不能为空");
        }
        OpsTenderSupplierInput update = MapstructUtils.convert(bo, OpsTenderSupplierInput.class);
        OpsTenderSupplierInput byId = getById(update.getId());
        if (BusinessStatusEnum.FINISH.getStatus().equals(byId.getState())) {
            throw new ServiceException("已审核完成数据不能修改");
        }
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(OpsTenderSupplierInput entity){
        //TODO 做一些数据校验,如唯一约束
        if (entity.getProjectId() == null){
            throw new ServiceException("项目id不能为空");
        }
        if (entity.getSupplierType() == null || entity.getSupplierType().isEmpty()){
            throw new ServiceException("企业登记注册类型不能为空");
        }
        if (entity.getSupplierName() == null || entity.getSupplierName().isEmpty()){
            throw new ServiceException("企业名称不能为空");
        }
        if (entity.getSupplierPerson() == null || entity.getSupplierPerson().isEmpty()){
            throw new ServiceException("企业法定代表人不能为空");
        }
        if (entity.getSupplierCode() == null || entity.getSupplierCode().isEmpty()){
            throw new ServiceException("统一社会信用代码不能为空");
        }
        if (entity.getPersonName() == null || entity.getPersonName().isEmpty()){
            throw new ServiceException("负责人姓名不能为空");
        }
        if (entity.getPersonPhone() == null || entity.getPersonPhone().isEmpty()){
            throw new ServiceException("负责人联系电话不能为空");
        }

    }

    /**
     * 校验并批量删除供应商入库信息
     *
     * @param ids     待删除的主键集合
     * @param isValid 是否进行有效性校验
     * @return 是否删除成功
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
            List<String> fileIds = new ArrayList<>();
            for (Long id : ids) {
                OpsTenderSupplierInput byId = getById(id);
                if (byId.getFileId() != null){
                    fileIds.add(byId.getInputFile());
                }
            }
            if (!fileIds.isEmpty()) {
                remoteFileService.deleteFile(fileIds);
            }
        }
        return baseMapper.deleteByIds(ids) > 0;
    }

    @Override
    public List<OpsTenderSupplierInputVo> getList(OpsTenderSupplierInputBo bo) {
        bo.setState("finish");
        LambdaQueryWrapper<OpsTenderSupplierInput> lqw = buildQueryWrapper(bo);
        List<OpsTenderSupplierInputVo> OpsTenderSupplierInputVos = baseMapper.selectVoList(lqw);
        List<OpsTenderSupplierInputVo> list = new ArrayList<>();
        OpsTenderSupplierInputVos.forEach(OpsTenderSupplierInputVo -> {
            OpsTenderSupplierInputVo vo = new OpsTenderSupplierInputVo();
            vo.setSupplierName(OpsTenderSupplierInputVo.getSupplierName());
            vo.setId(OpsTenderSupplierInputVo.getId());
            list.add(vo);
        });
        return list;
    }

    @Override
    public boolean importData(List<OpsTenderSupplierInputVo> OpsTenderSupplierInputVos, Long projectId) {
        List<OpsTenderSupplierInputVo> OpsTenderSupplierInputVos1 = OpsTenderSupplierInputVos.stream()
            .collect(Collectors.collectingAndThen(
                Collectors.toCollection(() ->
                    new TreeSet<>(Comparator.comparing(item ->
                        item.getSupplierName() + "_" + item.getSupplierPerson() + "_" + item.getSupplierCode()))),
                ArrayList::new
            ));
        List<OpsTenderSupplierInput> OpsTenderSupplierInputs = new ArrayList<>();
        for (OpsTenderSupplierInputVo OpsTenderSupplierInputVo : OpsTenderSupplierInputVos1) {
            Long count = baseMapper.selectCount(new LambdaQueryWrapper<OpsTenderSupplierInput>()
                .eq(OpsTenderSupplierInput::getProjectId,projectId)
                .eq(OpsTenderSupplierInput::getSupplierCode, OpsTenderSupplierInputVo.getSupplierCode())
                .eq(OpsTenderSupplierInput::getSupplierName, OpsTenderSupplierInputVo.getSupplierName())
                .eq(OpsTenderSupplierInput::getSupplierPerson, OpsTenderSupplierInputVo.getSupplierPerson()));
            if (count > 0) {
                continue;
            }
            OpsTenderSupplierInput newOpsTenderSupplierInput = new OpsTenderSupplierInput();
            BeanUtils.copyProperties(OpsTenderSupplierInputVo, newOpsTenderSupplierInput);
            newOpsTenderSupplierInput.setProjectId(projectId);
            newOpsTenderSupplierInput.setState("draft");
            OpsTenderSupplierInputs.add(newOpsTenderSupplierInput);
        }
        if (CollectionUtils.isEmpty(OpsTenderSupplierInputs)) {
            throw new ServiceException("导入数据数据库中全部存在，请核实后再导入！！！");
        }
        return baseMapper.insertBatch(OpsTenderSupplierInputs);
    }


    /**
     * 总体流程监听(例如: 草稿，撤销，退回，作废，终止，已完成，单任务完成等)
     * 正常使用只需#processEvent.flowCode=='leave1'
     * 示例为了方便则使用startsWith匹配了全部示例key
     *
     * @param processEvent 参数
     */
//    @org.springframework.context.event.EventListener(condition = "#processEvent.flowCode.endsWith('"+ constant.SUPPLIER_INPUT+"')")
//    public void processPlansHandler(ProcessEvent processEvent) {
//        log.info("物资计划审核任务执行了{}", processEvent.toString());
//        OpsTenderSupplierInput byId = getById(processEvent.getBusinessId());
//        byId.setState(processEvent.getStatus());
//        boolean b = updateById(byId);
//        if (!b){
//            log.error("更改供应商入库状态失败");
//        }
////        String batchNumber = processEvent.getBusinessId().split("_")[0];
////        //1、根据批次ID改编审核状态
////        BusCailiaoshebeiPici busCailiaoshebeiPici = new BusCailiaoshebeiPici().setApprovalPlan(processEvent.getStatus());
////        busCailiaoshebeiPiciService.update(busCailiaoshebeiPici, new LambdaQueryWrapper<BusCailiaoshebeiPici>()
////            .eq(BusCailiaoshebeiPici::getBatchNumber, batchNumber));
//    }
}
