/*
 * Author: wangjian
 * 生成ServiceImpl
 */
package com.tofly.gpsboot.service.maintain.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.tofly.api.DepartmentClient;
import com.tofly.common.oauth.util.SecurityUtils;
import com.tofly.gpsboot.common.Constant;
import com.tofly.gpsboot.common.system.AuditSateEnum;
import com.tofly.gpsboot.common.system.AuditTypeEnum;
import com.tofly.gpsboot.common.system.ReportSateEnum;
import com.tofly.gpsboot.exception.BusinessException;
import com.tofly.gpsboot.mapper.maintain.RepairplanyearMapper;
import com.tofly.gpsboot.service.comm.IAuditService;
import com.tofly.gpsboot.service.comm.IDisposeDateService;
import com.tofly.gpsboot.service.maintain.RepairplanyearService;
import com.tofly.gpsboot.service.maintain.RepairplanyeardetailService;
import com.tofly.gpsboot.util.DateTimeUtil;
import com.tofly.pojo.User;
import com.tofly.pojo.comm.Audit;
import com.tofly.pojo.comm.vo.AuditVo;
import com.tofly.pojo.maintain.Repairplanyear;
import com.tofly.pojo.maintain.Repairplanyeardetail;
import com.tofly.pojo.maintain.vo.ExcelExportRepairBasePlan;
import com.tofly.pojo.maintain.vo.ExcelExportRepairPlan;
import com.tofly.pojo.maintain.vo.ExcelExportRepairPlanDetail;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

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


/**
 * 抢维修年度计划记录信息表
 *
 * @author admin
 * @date Tue Nov 02 00:00:00 CST 2021
 */
@Service("repairplanyearService")
public class RepairplanyearServiceImpl extends ServiceImpl<RepairplanyearMapper, Repairplanyear> implements RepairplanyearService {

    @Autowired
    private DepartmentClient departmentClient;
    @Autowired
    private IAuditService iAuditService;
    @Autowired
    private RepairplanyeardetailService repairplanyeardetailService;
    @Autowired
    private IDisposeDateService iDisposeDateService;

    @Override
    public Page<Repairplanyear> getInfoPage(Page page, Repairplanyear dto) {
        // 审批状态 , 分割查询
        String planState = dto.getPlanState();

        QueryWrapper<Repairplanyear> wrapper = new QueryWrapper<>();

        // 当前部门下用户才有权限
        Long departmentId = SecurityUtils.getUser().getDepartmentId();
        Set<Long> userIdList = departmentClient.getDeptUserList(String.valueOf(departmentId)).getResult().stream().map(User::getId).collect(Collectors.toSet());
        if (!StringUtils.isEmpty(planState)) {
            List<String> longList = Arrays.stream(planState.split(Constant.CSV)).collect(Collectors.toList());
            wrapper.in("PLAN_STATE", longList);
            dto.setPlanState(null);
        }
        // 获取当前用户列表创建的年计划id列表
        Set<Long> userPlanIdList = this.list(new QueryWrapper<Repairplanyear>().lambda().in(Repairplanyear::getCreateUser, userIdList)).stream().map(Repairplanyear::getId).collect(Collectors.toSet());
        if (userPlanIdList.size() > 0) {
            wrapper.in("ID", userPlanIdList);
        } else {
            return null;
        }
        String years = dto.getYears();
        if (!StringUtils.isEmpty(years)) {
            List<String> yearList = Arrays.stream(years.split(Constant.CSV)).collect(Collectors.toList());
            wrapper.in("YEAR", yearList);
        }
        wrapper.orderByDesc("YEAR");
        wrapper.setEntity(dto);
        return this.page(page, wrapper);

    }

    @Override
    public Page<Repairplanyear> getAuditList(Page page, Repairplanyear dto) {
        // 审批状态 , 分割查询
        String planState = dto.getPlanState();

        QueryWrapper<Repairplanyear> wrapper = new QueryWrapper<>();
        if (!StringUtils.isEmpty(planState)) {
            List<String> longList = Arrays.stream(planState.split(Constant.CSV)).collect(Collectors.toList());
            wrapper.in("PLAN_STATE", longList);
            dto.setPlanState(null);
        }
        // 只获取用户审核的数据
        Set<Long> collect = iAuditService.list(new QueryWrapper<Audit>().lambda().eq(Audit::getAuditUser, SecurityUtils.getUserId()).eq(Audit::getAuditType, AuditTypeEnum.AUDIT_TYPE_REPAIR_YEAR_PLAN.getCode())).stream().map(Audit::getAuditPlanId).collect(Collectors.toSet());
        if (collect.size() > 0) {
            wrapper.in("ID", collect);
        } else {
            return null;
        }
        String years = dto.getYears();
        if (!StringUtils.isEmpty(years)) {
            List<String> yearList = Arrays.stream(years.split(Constant.CSV)).collect(Collectors.toList());
            wrapper.in("YEAR", yearList);
        }
        wrapper.orderByDesc("YEAR");
        wrapper.setEntity(dto);
        return this.page(page, wrapper);
    }

    @Override
    public Page<Repairplanyear> getAllList(Page page, Repairplanyear dto) {
        // 审批状态 , 分割查询
        String planState = dto.getPlanState();

        QueryWrapper<Repairplanyear> wrapper = new QueryWrapper<>();

        // 当前部门下用户才有权限
        Long departmentId = SecurityUtils.getUser().getDepartmentId();
        Set<Long> userIdList = departmentClient.getDeptUserList(String.valueOf(departmentId)).getResult().stream().map(User::getId).collect(Collectors.toSet());
        if (!StringUtils.isEmpty(planState)) {
            List<String> longList = Arrays.stream(planState.split(Constant.CSV)).collect(Collectors.toList());
            wrapper.in("PLAN_STATE", longList);
            dto.setPlanState(null);
        }
        // 获取当前用户列表创建的年计划id列表
        Set<Long> userPlanIdList = this.list(new QueryWrapper<Repairplanyear>().lambda().in(Repairplanyear::getCreateUser, userIdList)).stream().map(Repairplanyear::getId).collect(Collectors.toSet());
        Set<Long> collect = iAuditService.list(new QueryWrapper<Audit>().lambda().eq(Audit::getAuditUser, SecurityUtils.getUserId()).eq(Audit::getAuditType, AuditTypeEnum.AUDIT_TYPE_REPAIR_YEAR_PLAN.getCode())).stream().map(Audit::getAuditPlanId).collect(Collectors.toSet());
        userPlanIdList.addAll(collect);
        if (userPlanIdList.size() > 0) {
            wrapper.in("ID", userPlanIdList);
        } else {
            return null;
        }
        String years = dto.getYears();
        if (!StringUtils.isEmpty(years)) {
            List<String> yearList = Arrays.stream(years.split(Constant.CSV)).collect(Collectors.toList());
            wrapper.in("YEAR", yearList);
        }
        wrapper.orderByDesc("YEAR");
        wrapper.setEntity(dto);
        return this.page(page, wrapper);
    }

    @Override
    public Page<Repairplanyear> getNeedAuditList(Page page, Repairplanyear dto) {
        // 审批状态 , 分割查询
        String planState = dto.getPlanState();

        QueryWrapper<Repairplanyear> wrapper = new QueryWrapper<>();
        if (!StringUtils.isEmpty(planState)) {
            List<String> longList = Arrays.stream(planState.split(Constant.CSV)).collect(Collectors.toList());
            wrapper.in("PLAN_STATE", longList);
            dto.setPlanState(null);
        }
        // 只获取用户审核的数据 待审核的
        Set<Long> collect = iAuditService.list(new QueryWrapper<Audit>().lambda()
                .eq(Audit::getAuditUser, SecurityUtils.getUserId())
                .eq(Audit::getAuditType, AuditTypeEnum.AUDIT_TYPE_REPAIR_YEAR_PLAN.getCode())
                .eq(Audit::getAuditState, AuditSateEnum.AUDIT_UNCOMMITTED.getCode())).stream().map(Audit::getAuditPlanId).collect(Collectors.toSet());
        if (collect.size() > 0) {
            wrapper.in("ID", collect);
        } else {
            return null;
        }
        String years = dto.getYears();
        if (!StringUtils.isEmpty(years)) {
            List<String> yearList = Arrays.stream(years.split(Constant.CSV)).collect(Collectors.toList());
            wrapper.in("YEAR", yearList);
        }
        wrapper.orderByDesc("YEAR");
        wrapper.setEntity(dto);
        return this.page(page, wrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Repairplanyear savaYearPlanInfo(Repairplanyear dto) throws BusinessException {
        // 判断当前部门下是否已存在年,若存在则不允许新增
        if (this.checkYear(dto.getYear())) {
            // 判断当前详情计划传入是否为空值
            List<Repairplanyeardetail> details = dto.getDetails();
            if (null != details && details.size() > 0) {
                // 上报状态数据库默认值设为 0 未上报 审核意见数据库默认值设为 0 未审核 是否接收查看数据库默认值设为 0：未查看
                this.save(dto);
                Long id = dto.getId();
                details.forEach(info -> {
                    info.setYearId(id);
                    repairplanyeardetailService.save(info);
                });
                return dto;
            } else {
                throw new BusinessException(Constant.PLAN_YEAR_DETAIL_NULL_CODE, Constant.PLAN_YEAR_DETAIL_NULL);
            }


        } else {
            throw new BusinessException(Constant.TASK_ADD_YEAR_NOT_CODE, Constant.TASK_ADD_YEAR_NOT);
        }
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateYearPlanInfo(Repairplanyear parDto) throws BusinessException {
        if (!iDisposeDateService.isDisposePermissions(parDto.getCreateUser())) {
            throw new BusinessException(Constant.IS_DISPOSE_PERMISSIONS_NULL_CODE, Constant.IS_DISPOSE_PERMISSIONS_NULL);

        }

        // 判断当前年计划上报状态是否未上报
        if (!ReportSateEnum.REPORT_UNCOMMITTED.getCode().equals(parDto.getIssubmit())) {
            throw new BusinessException(Constant.PLAN_UPDATE_REPORT_UNCOMMITTED_CODE, Constant.PLAN_UPDATE_REPORT_UNCOMMITTED);
        }

        this.updateById(parDto);
        List<Repairplanyeardetail> details = parDto.getDetails();
        repairplanyeardetailService.removeByIds(repairplanyeardetailService.list(new QueryWrapper<Repairplanyeardetail>().lambda().eq(Repairplanyeardetail::getYearId, parDto.getId())).stream().map(Repairplanyeardetail::getId).collect(Collectors.toList()));
        details.forEach(info -> {
            info.setYearId(parDto.getId());
            repairplanyeardetailService.save(info);
        });


    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteYearPlanInfo(List<Long> idList) throws BusinessException {

        List<Repairplanyear> planYearList = this.list(new QueryWrapper<Repairplanyear>().lambda().in(Repairplanyear::getId, idList));

        planYearList.forEach(info -> {
            if (!iDisposeDateService.isDisposePermissions(info.getCreateUser())) {
                throw new BusinessException(Constant.IS_DISPOSE_PERMISSIONS_NULL_CODE, Constant.IS_DISPOSE_PERMISSIONS_NULL);

            }
            // 判断当前年计划上报状态是否是未上报
            if (!ReportSateEnum.REPORT_UNCOMMITTED.getCode().equals(info.getIssubmit())) {
                throw new BusinessException(Constant.PLAN_DELETE_REPORT_UNCOMMITTED_CODE, Constant.PLAN_DELETE_REPORT_UNCOMMITTED);
            }
            List<Repairplanyeardetail> list = repairplanyeardetailService.list(new QueryWrapper<Repairplanyeardetail>().lambda().in(Repairplanyeardetail::getYearId, idList));
            if (Optional.ofNullable(list).isPresent()) {
                List<Long> ids = list.stream().map(Repairplanyeardetail::getId).collect(Collectors.toList());
                repairplanyeardetailService.removeByIds(ids);
            }
            this.removeByIds(idList);
        });

    }

    /**
     * 判断当前部门下是否可以新增年
     *
     * @param year
     * @return
     */
    private Boolean checkYear(String year) {
        Long departmentId = SecurityUtils.getUser().getDepartmentId();
        Set<Long> userIdList = departmentClient.getDeptUserList(String.valueOf(departmentId)).getResult().stream().map(User::getId).collect(Collectors.toSet());
        List<Repairplanyear> list = this.list(new QueryWrapper<Repairplanyear>().lambda().eq(Repairplanyear::getYear, year).in(Repairplanyear::getCreateUser, userIdList));
        return null == list || list.size() <= 0;
    }

    @Override
    public List<Map<String, Object>> getExportData(String dto, String templateFlag) {
        List<Map<String, Object>> returnMap = new ArrayList<>();
        Map<String, Object> parentMap = new HashMap<>(12);
        // 只导出数据,没有模板
        Repairplanyear repairplanyear = JSONObject.parseObject(dto, Repairplanyear.class);
        Long id = repairplanyear.getId();
        if (!StringUtils.isEmpty(id)) {
            Repairplanyear po = this.getById(id);
            ExcelExportRepairBasePlan basePlan = new ExcelExportRepairBasePlan();
            // 增加年/备注/计划制定人/上报时间
            basePlan.setYear(po.getYear());
            basePlan.setNote(po.getNote());
            basePlan.setCreateUserName(po.getCreateUserName());
            Date submitTime = po.getSubmitTime();
            if(null!=submitTime){
                basePlan.setSubmitTime(DateTimeUtil.getLocalDateTime(DateTimeUtil.fromLong2LocalDateTime(po.getSubmitTime().getTime()), DateTimeUtil.FULL_FORMAT));
            }
            // 获取当前年计划审批链
            List<AuditVo> auditVoList = po.getAuditVoList();
            if (null != auditVoList) {
                // 增加部门审核意见/部门审核说明/部门审批人/部门审批时间/分管审核意见/分管审核说明/分管审批人/分管审批时间
                auditVoList.forEach(info -> {
                    Date auditTime = info.getAuditTime();
                    if (0 == info.getAuditLevel()) {
                        basePlan.setAuditDeptResult(info.getAuditStateName());
                        basePlan.setAuditDeptNote(info.getAuditNote());
                        basePlan.setAuditDeptUser(info.getAuditUserName());
                        if(null!=auditTime){
                            basePlan.setAuditDeptTime(DateTimeUtil.getLocalDateTime(DateTimeUtil.fromLong2LocalDateTime(auditTime.getTime()), DateTimeUtil.FULL_FORMAT));
                        }
                    } else {
                        basePlan.setAuditChargeResult(info.getAuditStateName());
                        basePlan.setAuditChargeNote(info.getAuditNote());
                        basePlan.setAuditChargeUser(info.getAuditUserName());
                        if(null!=auditTime) {
                            basePlan.setAuditChargeTime(DateTimeUtil.getLocalDateTime(DateTimeUtil.fromLong2LocalDateTime(auditTime.getTime()), DateTimeUtil.FULL_FORMAT));
                        }
                        }
                });
            }
            // 增加基础信息
            List<ExcelExportRepairBasePlan> basePlanList = new ArrayList<>();
            basePlanList.add(basePlan);
            parentMap.put("base", basePlanList);
            List<Repairplanyeardetail> details = po.getDetails();
            if (null != details) {
                List<ExcelExportRepairPlan> planList = new ArrayList<>();
                // 按照维修类型分组
                Map<String, List<Repairplanyeardetail>> collect = details.stream().collect(Collectors.groupingBy(Repairplanyeardetail::getTypeName, Collectors.toList()));
                collect.forEach((k, v) -> {
                    ExcelExportRepairPlan exportRepairPlan = new ExcelExportRepairPlan();
                    exportRepairPlan.setTypeName(k);
                    List<ExcelExportRepairPlanDetail> detailList = JSON.parseArray(JSON.toJSONString(v), ExcelExportRepairPlanDetail.class);
                    Map<String, String> dateMap = detailList.stream().filter(info -> {
                        if (StringUtils.isEmpty(info.getPlanContent())) {
                            info.setPlanContent("");
                        }
                        return true;

                    }).collect(Collectors.toMap(ExcelExportRepairPlanDetail::getMonth, ExcelExportRepairPlanDetail::getPlanContent));
                    dateMap.forEach((n, m) -> {
                        if ("1".equals(n)) {
                            exportRepairPlan.setOne(m);
                        } else if ("2".equals(n)) {
                            exportRepairPlan.setTwo(m);
                        } else if ("3".equals(n)) {
                            exportRepairPlan.setThree(m);
                        } else if ("4".equals(n)) {
                            exportRepairPlan.setFour(m);
                        } else if ("5".equals(n)) {
                            exportRepairPlan.setFive(m);
                        } else if ("6".equals(n)) {
                            exportRepairPlan.setSix(m);
                        } else if ("7".equals(n)) {
                            exportRepairPlan.setSeven(m);
                        } else if ("8".equals(n)) {
                            exportRepairPlan.setEight(m);
                        } else if ("9".equals(n)) {
                            exportRepairPlan.setNine(m);
                        } else if ("10".equals(n)) {
                            exportRepairPlan.setTen(m);
                        } else if ("11".equals(n)) {
                            exportRepairPlan.setEleven(m);
                        } else {
                            exportRepairPlan.setTwelve(m);
                        }
                    });
                    planList.add(exportRepairPlan);
                });

                // 增加详情
                parentMap.put("list", planList);

            }
        } else {
            throw new BusinessException(Constant.EXCEL_EXPORT_REPAIR_YEAR_PLAN_ID_NULL_ERROR_CODE, Constant.EXCEL_EXPORT_REPAIR_YEAR_PLAN_ID_NULL_ERROR);
        }
        returnMap.add(parentMap);
        return returnMap;
    }

    @Override
    public Boolean excelDataStorage(List<Object> dataList) {
        return null;
    }
}
