package com.xjrsoft.module.ledger.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.base.MPJBaseServiceImpl;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.xjrsoft.common.utils.VoToColumnUtil;
import com.xjrsoft.module.ledger.dto.WfSubscriptionPageDto;
import com.xjrsoft.module.ledger.entity.WfSubscription;
import com.xjrsoft.module.ledger.entity.WfSubscriptionList;
import com.xjrsoft.module.ledger.mapper.WfSubscriptionListMapper;
import com.xjrsoft.module.ledger.mapper.WfSubscriptionMapper;
import com.xjrsoft.module.ledger.service.IWfSubscriptionService;
import com.xjrsoft.module.ledger.vo.WfSubscriptionExcelVo;
import com.xjrsoft.module.ledger.vo.WfSubscriptionListInfoVo;
import com.xjrsoft.module.ledger.vo.WfSubscriptionListVo;
import com.xjrsoft.module.ledger.vo.WfSubscriptionPageVo;
import com.xjrsoft.module.ledger.vo.WorkflowRecordVo;
import com.xjrsoft.module.system.entity.File;
import com.xjrsoft.module.system.service.IFileService;
import com.xjrsoft.module.workflow.entity.WorkflowExtra;
import com.xjrsoft.module.workflow.entity.WorkflowFormRelation;
import com.xjrsoft.module.workflow.entity.WorkflowRecord;
import com.xjrsoft.module.workflow.mapper.WorkflowExtraMapper;
import com.xjrsoft.module.workflow.mapper.WorkflowFormRelationMapper;
import com.xjrsoft.module.workflow.mapper.WorkflowRecordMapper;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
* @title: 物品申购
* @Author dzx
* @Date: 2024-02-19
* @Version 1.0
*/
@Service
@AllArgsConstructor
public class WfSubscriptionServiceImpl extends MPJBaseServiceImpl<WfSubscriptionMapper, WfSubscription> implements IWfSubscriptionService {
    private final WfSubscriptionMapper wfSubscriptionMapper;

    private final WfSubscriptionListMapper wfSubscriptionListMapper;

    private IFileService fileService;

    private WorkflowRecordMapper workflowRecordMapper;

    private WorkflowExtraMapper workflowExtraMapper;

    private WorkflowFormRelationMapper workflowFormRelationMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean add(WfSubscription wfSubscription) {
        wfSubscriptionMapper.insert(wfSubscription);
        for (WfSubscriptionList wfSubscriptionList : wfSubscription.getWfSubscriptionListList()) {
            wfSubscriptionList.setParentId(wfSubscription.getId());
            wfSubscriptionListMapper.insert(wfSubscriptionList);
        }

        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean update(WfSubscription wfSubscription) {
        wfSubscriptionMapper.updateById(wfSubscription);
        //********************************* WfSubscriptionList  增删改  开始 *******************************************/
        {
            // 查出所有子级的id
            List<WfSubscriptionList> wfSubscriptionListList = wfSubscriptionListMapper.selectList(Wrappers.lambdaQuery(WfSubscriptionList.class).eq(WfSubscriptionList::getParentId, wfSubscription.getId()).select(WfSubscriptionList::getId));
            List<Long> wfSubscriptionListIds = wfSubscriptionListList.stream().map(WfSubscriptionList::getId).collect(Collectors.toList());
            //原有子表单 没有被删除的主键
            List<Long> wfSubscriptionListOldIds = wfSubscription.getWfSubscriptionListList().stream().map(WfSubscriptionList::getId).filter(Objects::nonNull).collect(Collectors.toList());
            //找到需要删除的id
            List<Long> wfSubscriptionListRemoveIds = wfSubscriptionListIds.stream().filter(item -> !wfSubscriptionListOldIds.contains(item)).collect(Collectors.toList());

            for (WfSubscriptionList wfSubscriptionList : wfSubscription.getWfSubscriptionListList()) {
                //如果不等于空则修改
                if (wfSubscriptionList.getId() != null) {
                    wfSubscriptionListMapper.updateById(wfSubscriptionList);
                }
                //如果等于空 则新增
                else {
                    //已经不存在的id 删除
                    wfSubscriptionList.setParentId(wfSubscription.getId());
                    wfSubscriptionListMapper.insert(wfSubscriptionList);
                }
            }
            //已经不存在的id 删除
            if(wfSubscriptionListRemoveIds.size() > 0){
                wfSubscriptionListMapper.deleteBatchIds(wfSubscriptionListRemoveIds);
            }
        }
        //********************************* WfSubscriptionList  增删改  结束 *******************************************/

        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean delete(List<Long> ids) {
        wfSubscriptionMapper.deleteBatchIds(ids);
        wfSubscriptionListMapper.delete(Wrappers.lambdaQuery(WfSubscriptionList.class).in(WfSubscriptionList::getParentId, ids));

        return true;
    }

    @Override
    public Page<WfSubscriptionPageVo> getPage(Page<WfSubscriptionPageVo> page, WfSubscriptionPageDto dto) {
        Page<WfSubscriptionPageVo> voPage = wfSubscriptionMapper.getPage(page, dto);
        List<WfSubscriptionList> wfSubscriptionList = wfSubscriptionListMapper.selectList(
                new QueryWrapper<WfSubscriptionList>().lambda().orderByAsc(WfSubscriptionList::getId)
        );
        Map<Long, String> flowMap = new HashMap<>();
        for (WfSubscriptionList subscriptionList : wfSubscriptionList) {
            if(flowMap.containsKey(subscriptionList.getParentId())){
                continue;
            }
            flowMap.put(subscriptionList.getParentId(), subscriptionList.getNameOfThePurchasedItem());
        }
        for (WfSubscriptionPageVo record : voPage.getRecords()) {
            List<File> list = fileService.list(Wrappers.lambdaQuery(File.class).eq(File::getFolderId, record.getFolderId()));
            record.setFileInfos(list);
            record.setFlowName(flowMap.get(Long.valueOf(record.getId())));
        }
        return voPage;
    }

    @Override
    public WfSubscriptionListInfoVo getSubscriptionList(Long id) {
        WfSubscriptionListInfoVo info = wfSubscriptionMapper.getInfoById(id);
        List<WfSubscriptionList> subscriptionListList = wfSubscriptionListMapper.selectList(
            new QueryWrapper<WfSubscriptionList>().lambda().eq(WfSubscriptionList::getParentId, id)
        );
        info.setSubscriptionList(BeanUtil.copyToList(subscriptionListList, WfSubscriptionListVo.class));

        List<WorkflowRecord> recordList = workflowRecordMapper.selectList(
            new MPJLambdaWrapper<WorkflowRecord>()
            .select(WorkflowRecord.class, x -> VoToColumnUtil.fieldsToColumns(WorkflowRecordVo.class).contains(x.getProperty()))
            .innerJoin(WorkflowFormRelation.class, WorkflowFormRelation::getProcessId, WorkflowRecord::getProcessId)
            .eq(WorkflowFormRelation::getFormKeyValue, id)
        );
        info.setWorkflowRecordList(BeanUtil.copyToList(recordList, WorkflowRecordVo.class));
        List<WorkflowFormRelation> relations = workflowFormRelationMapper.selectList(new QueryWrapper<WorkflowFormRelation>().lambda().eq(WorkflowFormRelation::getFormKeyValue, id));

        if(!relations.isEmpty()){
            info.setProcessId(relations.get(0).getProcessId());
        }


        //查询最后一个节点的taskId
        List<WorkflowExtra> taskList = workflowExtraMapper.selectList(
            new QueryWrapper<WorkflowExtra>().lambda()
            .eq(WorkflowExtra::getProcessId, info.getProcessId())
            .orderByDesc(WorkflowExtra::getStartTime)
        );
        if(!taskList.isEmpty()){
            info.setTaskId(taskList.get(0).getTaskId());
        }

        return info;
    }

    @Override
    public List<WfSubscriptionExcelVo> getList(WfSubscriptionPageDto dto) {
        List<WfSubscriptionList> wfSubscriptionList = wfSubscriptionListMapper.selectList(
                new QueryWrapper<WfSubscriptionList>().lambda().orderByAsc(WfSubscriptionList::getId)
        );
        Map<Long, String> flowMap = new HashMap<>();
        for (WfSubscriptionList subscriptionList : wfSubscriptionList) {
            if(flowMap.containsKey(subscriptionList.getParentId())){
                continue;
            }
            flowMap.put(subscriptionList.getParentId(), subscriptionList.getNameOfThePurchasedItem());
        }
        List<WfSubscriptionPageVo> list = wfSubscriptionMapper.getList(dto);
        List<WfSubscriptionExcelVo> result = new ArrayList<>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        for (WfSubscriptionPageVo record : list) {
            WfSubscriptionExcelVo excelVo = BeanUtil.toBean(record, WfSubscriptionExcelVo.class);
            if(record.getShenQingRiQi4752() != null){
                excelVo.setApplyDate(sdf.format(record.getShenQingRiQi4752()));
            }

            excelVo.setFlowName(flowMap.get(Long.valueOf(record.getId())));
            result.add(excelVo);
        }
        return result;
    }

    @Override
    public Boolean dataHandle(Long formId) {
        WfSubscription wfSubscription = this.getById(formId);

        if(wfSubscription != null){

            Date shenQingRiQi = wfSubscription.getShenQingRiQi4752();
            LocalDate localDate = shenQingRiQi.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();

            String year = String.valueOf(localDate.getYear());

            //获取当前内存中的最大编号
            LambdaQueryWrapper<WfSubscription> wfSubscriptionLambdaQueryWrapper = new LambdaQueryWrapper<>();
            wfSubscriptionLambdaQueryWrapper
                    .select(WfSubscription.class, x -> VoToColumnUtil.fieldsToColumns(WfSubscription.class).contains(x.getProperty()))
                    .likeRight(WfSubscription::getNumber, year)
                    .orderByDesc(WfSubscription::getNumber)
                    .last("limit 1");
            WfSubscription wfSubscriptionMax = this.getOne(wfSubscriptionLambdaQueryWrapper);
            if(wfSubscriptionMax != null){
                String number = wfSubscriptionMax.getNumber();

                WfSubscription wfSubscriptionNew = new WfSubscription();

                int num = Integer.parseInt(number);
                num = num + 1;
                wfSubscriptionNew.setNumber(String.valueOf(num));

                wfSubscriptionNew.setId(wfSubscription.getId());
                wfSubscriptionNew.setStatus(1);

                return this.updateById(wfSubscriptionNew);
            }else{
                WfSubscription wfSubscriptionNew = new WfSubscription();
                wfSubscriptionNew.setNumber(year + "001");
                wfSubscriptionNew.setId(wfSubscription.getId());
                wfSubscriptionNew.setStatus(1);

                return this.updateById(wfSubscriptionNew);
            }
        }
        return true;
    }
}
