package com.dayou.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.dayou.common.BaseEntity;
import com.dayou.dto.*;
import com.dayou.entity.*;
import com.dayou.enums.GlobalConfigEnum;
import com.dayou.enums.MainBusinessEnum;
import com.dayou.enums.workflow.NodeStateEnum;
import com.dayou.exception.ErrorCode;
import com.dayou.mapper.MajorMapper;
import com.dayou.mapper.WorkTaskRecordMapper;
import com.dayou.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dayou.service.workflow.IWorkFlowNodeInstanceService;
import com.dayou.service.workflow.IWorkFlowService;
import com.dayou.service.workflow.IWorkNodeService;
import com.dayou.service.workflow.IWorkTaskRecordService;
import com.dayou.utils.LoginContext;
import com.dayou.vo.MajorVO;
import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

import static com.dayou.common.Constants.BY_TURNS;
import static com.dayou.enums.GlobalConfigEnum.DepartmentTurns.MAJOR_BUSINESS;

/**
 * <p>
 * 大中型项目 服务实现类
 * </p>
 *
 * @author wucl
 * @since 2023-10-30
 */
@DS("mbs")
@Service
public class MajorServiceImpl extends ServiceImpl<MajorMapper, Major> implements IMajorService {

    @Autowired
    private IWorkFlowService workFlowService;

    @Autowired
    private IWorkFlowNodeInstanceService workFlowNodeInstanceService;

    @Autowired
    private IGlobalConfigService globalConfigService;

    @Autowired
    private ISortedDepartmentService sortedDepartmentService;


    @Autowired
    private MajorMapper  majorMapper;

    @Autowired
    private IBusinessNumberService businessNumberService;

    @Autowired
    private IOrderFundService orderFundService;

    @Override
    @SuppressWarnings("unchecked")
    public Page<MajorVO> selectPage(Page page, MajorVO major,String keyword){
        Page<MajorVO> result = majorMapper.getPage(page,major,keyword);
        return result;
    }

    /**
     * 条件查询大中型已终止流程
     * @param page 分页
     * @param major 查询条件
     * @param keyword 关键字
     * @return Page<MajorVO>
     */
    @Override
    public Page<MajorVO> getTerminatedPage(Page page, MajorVO major, String keyword) {
        return majorMapper.getTerminatedPage(page,major,keyword,LoginContext.getCurrentUserId());
    }


    @Override
    public MajorVO detail(Long id){
        MajorVO majorVO = majorMapper.getDetail(id);
        String terminalClienteleType = majorVO.getTerminalClienteleType();
        if (StrUtil.isNotBlank(terminalClienteleType) && terminalClienteleType.equals("企业")){
            majorVO.setTMobile(majorVO.getTCompanyMobile());
        }
        return majorVO;
    }


    @Transactional
    @Override
    public WorkNodeCommit add(Major major){
        if (BY_TURNS.equals(major.getAllotType())){
            //确定接单部门
            Long allotDepartmentId = getAllotDepartmentId(MainBusinessEnum.MAJOR_BUSINESS);
            major.setDepartmentId(allotDepartmentId);
        }
        major.setOrderId(businessNumberService.takeOrderNumber());
        //保存业务数据
        this.save(major);
        //业务下单
        WorkNodeCommit commit = workFlowService.openingOrder(MainBusinessEnum.MAJOR_BUSINESS, major.getId(), null, major.getRemark());
        //下单完成后创建订单应收款记录
        orderFundService.createOrderFundWhenOpeningOrder(major.getId(),major.getOrderId(),major.getName(),MainBusinessEnum.MAJOR_BUSINESS);
        return commit;

    }

    @Override
    public Boolean update(Major major){
        return  this.updateById(major);
    }

    @Override
    public Boolean delete(Long id){
        //逻辑删除
        return this.removeById(id);
    }

    @Override
    public Boolean allocation(TaskRecordDTO<MajorVO> taskRecordDTO) {
        MajorVO taskData = taskRecordDTO.getTaskData();
        List<Long> membersId = taskData.getMembersId();
        if (taskData.getPrincipalId()==null || CollectionUtil.isEmpty(membersId)){
            ErrorCode.throwBusinessException(ErrorCode.CUSTOM_ERROR,"项目负责人和项目参与人员不能为空。");
        }
        String members = JSON.toJSONString(membersId);
        return this.update(new LambdaUpdateWrapper<Major>().set(Major::getMembers,members).set(Major::getPrincipalId,taskData.getPrincipalId())
                .eq(BaseEntity::getId,taskData.getId()));
    }

    @Override
    public Boolean priceFeedback(TaskRecordDTO<PriceFeedbackDTO> taskRecordDTO) {
        PriceFeedbackDTO taskData = taskRecordDTO.getTaskData();
        if (taskData.getPrinting()==null || CollectionUtil.isEmpty(taskData.getProduction())){
            ErrorCode.throwBusinessException(ErrorCode.CUSTOM_ERROR,"出具产品类型和打印份数不能为空。");
        }
//        if (taskData.getIsPay()!=null){
//            //价值意见书是否需要收款？
//            majorProductionService.update(new LambdaUpdateWrapper<MajorProduction>().set(MajorProduction::getIfPay,taskData.getIsPay())
//                    .eq(MajorProduction::getMajorId,taskData.getMajorId()).eq(MajorProduction::getReportNo,taskData.getReportNo())
//                    .eq(MajorProduction::getProduction,ProductionEnum.STATEMENT.name()).eq(BaseEntity::getDeleted,Boolean.FALSE));
//        }

        Major major = this.getOne(new LambdaQueryWrapper<Major>().eq(BaseEntity::getId, taskData.getMajorId()).select(Major::getFeedbackInfo,BaseEntity::getId).eq(BaseEntity::getDeleted, Boolean.FALSE));
        List<PriceFeedbackDTO> feedbackDTOS = JSON.parseArray(major.getFeedbackInfo(), PriceFeedbackDTO.class);
        if (feedbackDTOS!=null){
            PriceFeedbackDTO priceFeedbackDTO = null;
            if (StrUtil.isEmpty(taskData.getReportNo())){
                priceFeedbackDTO = feedbackDTOS.stream().filter(x -> taskData.getMajorId().equals(x.getMajorId())).findFirst().orElse(null);
            }else{
                 priceFeedbackDTO = feedbackDTOS.stream().filter(x -> taskData.getReportNo().equals(x.getReportNo())).findFirst().orElse(null);
            }
            if (priceFeedbackDTO!=null){
                feedbackDTOS.remove(priceFeedbackDTO);
            }
        }else{
            feedbackDTOS = new ArrayList<>();
        }
        feedbackDTOS.add(taskData);
        String feedbackStr = JSON.toJSONString(feedbackDTOS);
        return this.update(new LambdaUpdateWrapper<Major>().set(Major::getFeedbackInfo,feedbackStr).eq(BaseEntity::getId,taskData.getMajorId()));
    }

    @Override
    public MajorStaticsDTO staticsInformation() {
        MajorStaticsDTO staticsDTO =  majorMapper.staticsInformation(LoginContext.getCurrentUserId());
        return staticsDTO;
    }

    @Override
    public Page<MajorVO> xPage(Page page, MajorVO major, String keyword) {
        return majorMapper.xPage(page,major,keyword,LoginContext.getCurrentUserId());
    }

    @Transactional
    @Override
    public Boolean doRecall(Long id) {
        List<WorkFlowNodeInstance> exists = workFlowNodeInstanceService.list(new LambdaQueryWrapper<WorkFlowNodeInstance>()
                .eq(WorkFlowNodeInstance::getBusinessType, MainBusinessEnum.MAJOR_BUSINESS.name())
                .eq(WorkFlowNodeInstance::getBusinessId, id)
                .eq(BaseEntity::getDeleted, Boolean.FALSE));
        if (exists.size()>2){
            ErrorCode.throwBusinessException(ErrorCode.CUSTOM_ERROR,"业务部已分单，无法撤回。若需撤回请联系当前节点待办人退回流程。");
            return Boolean.FALSE;
        }else{
            try {
                for (WorkFlowNodeInstance workFlowNodeInstance: exists){
                    if (workFlowNodeInstance.getSequence().equals(0)){
                        workFlowNodeInstance.setState(NodeStateEnum.PENDING.name());
                        workFlowNodeInstanceService.updateById(workFlowNodeInstance);
                    }else {
                        workFlowNodeInstanceService.removeById(workFlowNodeInstance.getId());
                    }
                }
            } catch (Exception e) {
                ErrorCode.throwBusinessException(ErrorCode.DATA_NOT_EXISTS);
            }
            return Boolean.TRUE;
        }
    }

    @Override
    public List<MajorSubClientDTO> findMajorSubClient() {
        return majorMapper.findMajorSubClient();
    }

    @Override
    public MajorVO productionDetail(Long id, String productionNo,String production) {
        return majorMapper.productionDetail(id,productionNo,production);
    }

    @Override
    public Boolean feedback(PriceFeedbackDTO priceFeedbackDTO) {
        if (priceFeedbackDTO.getPrinting()==null || CollectionUtil.isEmpty(priceFeedbackDTO.getProduction())){
            ErrorCode.throwBusinessException(ErrorCode.CUSTOM_ERROR,"出具产品类型和打印份数不能为空。");
        }

        Major major = this.getOne(new LambdaQueryWrapper<Major>().eq(BaseEntity::getId, priceFeedbackDTO.getMajorId()).select(Major::getFeedbackInfo,BaseEntity::getId).eq(BaseEntity::getDeleted, Boolean.FALSE));
        List<PriceFeedbackDTO> feedbackDTOS = JSON.parseArray(major.getFeedbackInfo(), PriceFeedbackDTO.class);
        if (feedbackDTOS!=null){
            PriceFeedbackDTO feedbackDTO = null;
            if (StrUtil.isEmpty(priceFeedbackDTO.getReportNo())){
                feedbackDTO = feedbackDTOS.stream().filter(x -> priceFeedbackDTO.getMajorId().equals(x.getMajorId())).findFirst().orElse(null);
            }else{
                feedbackDTO = feedbackDTOS.stream().filter(x -> priceFeedbackDTO.getReportNo().equals(x.getReportNo())).findFirst().orElse(null);
            }
            feedbackDTO.setPrintingRemark(priceFeedbackDTO.getPrintingRemark());
            feedbackDTO.setPrinting(priceFeedbackDTO.getPrinting());
            String feedbackStr = JSON.toJSONString(feedbackDTOS);
            return this.update(new LambdaUpdateWrapper<Major>().set(Major::getFeedbackInfo,feedbackStr).eq(BaseEntity::getId,priceFeedbackDTO.getMajorId()));
        }
        return Boolean.FALSE;
    }

    @Override
    public Boolean updateDepartment(TaskRecordDTO<Major> taskRecordDTO) {
        Major taskData = taskRecordDTO.getTaskData();
        return this.update(new LambdaUpdateWrapper<Major>().set(Major::getDepartmentId,taskData.getDepartmentId()).eq(Major::getId,taskData.getId()));
    }

//    /**
//     * 大中型业务下单
//     * @param businessId
//     * @param remark
//     */
//    private WorkNodeCommit openingMajorOrder(Long businessId, String remark){
//        WorkFlow majorBusinessFlow = workFlowService.getOne(new LambdaQueryWrapper<WorkFlow>()
//                .eq(WorkFlow::getCode, MainBusinessEnum.MAJOR_BUSINESS.getCode())
//                .eq(WorkFlow::getState, Boolean.FALSE)
//                .eq(BaseEntity::getDeleted, Boolean.FALSE));
//
//        if (majorBusinessFlow == null){
//            ErrorCode.throwBusinessException(ErrorCode.WORKFLOW_NOT_EXISTS,MainBusinessEnum.MAJOR_BUSINESS.getMsg());
//        }
//
//        WorkNodeDTO openingOrderNode = workNodeService.getOpeningOrderNode(majorBusinessFlow.getId());
//        if (openingOrderNode == null){
//            ErrorCode.throwBusinessException(ErrorCode.OPENING_NODE_NOT_EXISTS,MainBusinessEnum.MAJOR_BUSINESS.getMsg());
//        }
//
//        WorkFlowNodeInstance instance = new WorkFlowNodeInstance();
//        instance.setFlowId(majorBusinessFlow.getId());
//        instance.setNodeId(openingOrderNode.getId());
//        instance.setBusinessId(businessId);
//        instance.setBusinessType(MainBusinessEnum.MAJOR_BUSINESS.getCode());
//        instance.setSequence(0);
//        instance.setState(NodeStateEnum.FINISHED.name());
//        instance.setComment(remark);
//        workFlowNodeInstanceService.save(instance);
//
//        List<WorkNodeTask> tasks = openingOrderNode.getTasks();
//
//
//        if (CollectionUtil.isNotEmpty(tasks)){
//
//            //业务成功下单后，将下单任务标记已完成。
//            if (workTaskRecordService.doCreateMajorTaskRecord(tasks, instance, LoginContext.getCurrentUserId())){
//                workTaskRecordMapper.finishOpening(instance.getId(),majorBusinessFlow.getId());
//            }
//        }
//
//        //构造下单提交对象
//        WorkNodeCommit commit = new WorkNodeCommit();
//        commit.setInstanceNodeId(instance.getId());
//        commit.setComments(remark);
//        commit.setState(NodeLogEnum.PASS);
//        return commit;
//    }

    private synchronized Long getAllotDepartmentId(MainBusinessEnum businessEnum){

        List<SortedDepartment> departments = sortedDepartmentService.list(new LambdaQueryWrapper<SortedDepartment>().eq(SortedDepartment::getBusinessType, businessEnum.getCode()));

        if (CollectionUtil.isEmpty(departments)){
            ErrorCode.throwBusinessException(ErrorCode.SORTED_DEPARTMENT_NOT_EXISTS,businessEnum.getMsg());
        }


        GlobalConfig currentSorted = globalConfigService.getGlobalConfig(GlobalConfigEnum.DEPARTMENT_TURNS.name(), MAJOR_BUSINESS.name());

        Integer currentSortedIndex = Integer.valueOf(StrUtil.isBlank(currentSorted.getValue())?"0":currentSorted.getValue());

        List<Integer> indexes = departments.stream().map(SortedDepartment::getSortedIndex).sorted((b1, b2) -> b1.compareTo(b2)).collect(Collectors.toList());
        for (int i=0;i<indexes.size();i++){
            if (currentSortedIndex.equals(indexes.get(i))){
                Integer waitingIndex = indexes.get((i + 1) % indexes.size());
                currentSorted.setValue(String.valueOf(waitingIndex));
                globalConfigService.update(currentSorted);
                break;
            }
        }

        return departments.stream().filter(d -> d.getSortedIndex().equals(currentSortedIndex)).findFirst().get().getDepartmentId();
    }


}
