/*
 * Author: Zev
 * 生成ServiceImpl
 */
package com.tofly.gpsboot.service.paln.month.impl;

import com.alibaba.fastjson.JSON;

import com.alibaba.fastjson.JSONArray;
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.api.UserClent;
import com.tofly.common.oauth.util.SecurityUtils;
import com.tofly.gpsboot.common.Constant;

import com.tofly.gpsboot.common.system.*;
import com.tofly.gpsboot.service.config.InspecttypeService;
import com.tofly.gpsboot.util.DateTimeUtil;
import com.tofly.pojo.comm.vo.AuditVo;
import com.tofly.pojo.maintain.vo.ExcelExportRepairBasePlan;
import com.tofly.pojo.plan.dto.PlanmouthDto;
import com.tofly.pojo.plan.vo.PlanVo;
import com.tofly.pojo.plan.vo.PlanyeardetailVo;
import com.tofly.gpsboot.exception.BusinessException;
import com.tofly.gpsboot.mapper.plan.PlanmouthMapper;
import com.tofly.gpsboot.service.comm.IAuditService;
import com.tofly.gpsboot.service.comm.IDisposeDateService;
import com.tofly.gpsboot.service.paln.task.PlanService;
import com.tofly.gpsboot.service.paln.year.PlanyearService;
import com.tofly.gpsboot.service.paln.year.PlanyeardetailService;
import com.tofly.pojo.User;
import com.tofly.pojo.comm.Audit;
import com.tofly.pojo.plan.Plan;
import com.tofly.pojo.plan.Planmouth;
import com.tofly.gpsboot.service.paln.month.PlanmouthService;

import com.tofly.pojo.plan.Planyear;
import com.tofly.pojo.plan.Planyeardetail;
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;


/**
 * 巡检月度计划记录信息表：TF_YWPN_PLANMOUTH_W
 *
 * @author admin
 * @date Thu Mar 18 00:00:00 CST 2021
 */
@Service("planmouthService")
public class PlanmouthServiceImpl extends ServiceImpl<PlanmouthMapper, Planmouth> implements PlanmouthService {

    @Autowired
    private PlanService planService;

    @Autowired
    private PlanyeardetailService planyeardetailService;
    @Autowired
    private IAuditService iAuditService;

    @Autowired
    private DepartmentClient departmentClient;
    @Autowired
    private IDisposeDateService iDisposeDateService;
    @Autowired
    private PlanyearService planyearService;
    @Autowired
    private InspecttypeService inspecttypeService;


    @Override
    public Page<Planmouth> getInfoPage(Page page, PlanmouthDto parDto) {
        // 审批状态 , 分割查询
        String planState = parDto.getPlanState();
        Planmouth planmouth = JSONObject.parseObject(JSON.toJSONString(parDto), Planmouth.class);

        // 当前部门下用户才有权限
        Long departmentId = SecurityUtils.getUser().getDepartmentId();
        Set<Long> userIdList = departmentClient.getDeptUserList(departmentId).getResult().stream().map(User::getId).collect(Collectors.toSet());

        QueryWrapper<Planmouth> wrapper = new QueryWrapper();

        if (!StringUtils.isEmpty(planState)) {
            List<String> longList = Arrays.stream(planState.split(Constant.CSV)).collect(Collectors.toList());
            wrapper.in("PLAN_STATE", longList);
            planmouth.setPlanState(null);
        }
        // 获取当前用户列表创建的年计划id列表
        Set<Long> userPlanIdList = this.list(new QueryWrapper<Planmouth>().lambda().in(Planmouth::getCreateUser, userIdList)).stream().map(Planmouth::getId).collect(Collectors.toSet());
        if (userPlanIdList.size() > 0) {
            wrapper.in("ID", userPlanIdList);
        } else {
            return null;
        }
        String years = parDto.getYears();
        if (!StringUtils.isEmpty(years)) {
            List<String> yearList = Arrays.stream(years.split(Constant.CSV)).map(String::trim)
                    .collect(Collectors.toList());
            wrapper.in("YEAR", yearList);
            planmouth.setYear(null);
        }
        String months = parDto.getMonths();
        if (!StringUtils.isEmpty(months)) {
            List<String> monthList = Arrays.stream(months.split(Constant.CSV)).map(String::trim)
                    .collect(Collectors.toList());
            wrapper.in("MOUTH", monthList);
            planmouth.setMouth(null);
        }

        wrapper.setEntity(planmouth);
        wrapper.orderByDesc("YEAR").orderByDesc("MOUTH");
        return this.page(page, wrapper);
    }

    @Override
    public Page<Planmouth> getAuditList(Page page, PlanmouthDto parDto) {
        // 审批状态 , 分割查询
        String planState = parDto.getPlanState();
        Planmouth planmouth = JSONObject.parseObject(JSON.toJSONString(parDto), Planmouth.class);
        QueryWrapper<Planmouth> wrapper = new QueryWrapper();

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

    @Override
    public Page<Planmouth> getAllList(Page page, PlanmouthDto parDto) {
        // 审批状态 , 分割查询
        String planState = parDto.getPlanState();
        Planmouth planmouth = JSONObject.parseObject(JSON.toJSONString(parDto), Planmouth.class);

        // 当前部门下用户才有权限
        Long departmentId = SecurityUtils.getUser().getDepartmentId();
        Set<Long> userIdList = departmentClient.getDeptUserList(departmentId).getResult().stream().map(User::getId).collect(Collectors.toSet());

        QueryWrapper<Planmouth> wrapper = new QueryWrapper();

        if (!StringUtils.isEmpty(planState)) {
            List<String> longList = Arrays.stream(planState.split(Constant.CSV)).collect(Collectors.toList());
            wrapper.in("PLAN_STATE", longList);
            planmouth.setPlanState(null);
        }
        // 获取当前用户列表创建的年计划id列表
        Set<Long> userPlanIdList = this.list(new QueryWrapper<Planmouth>().lambda().in(Planmouth::getCreateUser, userIdList)).stream().map(Planmouth::getId).collect(Collectors.toSet());

        // 由于分管经理不属于当前部门,根据当前登录用户需要获取相关计划id列表
        Set<Long> collect = iAuditService.list(new QueryWrapper<Audit>().lambda().eq(Audit::getAuditUser, SecurityUtils.getUserId()).eq(Audit::getAuditType, AuditTypeEnum.AUDIT_TYPE_MONTHLY_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 = parDto.getYears();
        if (!StringUtils.isEmpty(years)) {
            List<String> yearList = Arrays.stream(years.split(Constant.CSV)).map(String::trim)
                    .collect(Collectors.toList());
            wrapper.in("YEAR", yearList);
            planmouth.setYear(null);
        }
        String months = parDto.getMonths();
        if (!StringUtils.isEmpty(months)) {
            List<String> monthList = Arrays.stream(months.split(Constant.CSV)).map(String::trim)
                    .collect(Collectors.toList());
            wrapper.in("MOUTH", monthList);
            planmouth.setMouth(null);
        }
        wrapper.setEntity(planmouth);
        wrapper.orderByDesc("YEAR").orderByDesc("MOUTH");
        return this.page(page, wrapper);
    }

    @Override
    public Page<Planmouth> getNeedAuditList(Page page, PlanmouthDto parDto) {
        // 审批状态 , 分割查询
        String planState = parDto.getPlanState();
        Planmouth planmouth = JSONObject.parseObject(JSON.toJSONString(parDto), Planmouth.class);
        QueryWrapper<Planmouth> wrapper = new QueryWrapper();

        if (!StringUtils.isEmpty(planState)) {
            List<String> longList = Arrays.stream(planState.split(Constant.CSV)).collect(Collectors.toList());
            wrapper.in("PLAN_STATE", longList);
            planmouth.setPlanState(null);
        }
        // 只获取用户审核的数据 待审核的
        Set<Long> collect = iAuditService.list(new QueryWrapper<Audit>().lambda()
                .eq(Audit::getAuditUser, SecurityUtils.getUserId())
                .eq(Audit::getAuditType, AuditTypeEnum.AUDIT_TYPE_MONTHLY_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 = parDto.getYears();
        if (!StringUtils.isEmpty(years)) {
            List<String> yearList = Arrays.stream(years.split(Constant.CSV)).map(String::trim)
                    .collect(Collectors.toList());
            wrapper.in("YEAR", yearList);
            planmouth.setYear(null);
        }
        String months = parDto.getMonths();
        if (!StringUtils.isEmpty(months)) {
            List<String> monthList = Arrays.stream(months.split(Constant.CSV)).map(String::trim)
                    .collect(Collectors.toList());
            wrapper.in("MOUTH", monthList);
            planmouth.setMouth(null);
        }
        wrapper.setEntity(planmouth);
        wrapper.orderByDesc("YEAR").orderByDesc("MOUTH");
        return this.page(page, wrapper);
    }

    @Override
    public Long savaMonthPlanInfo(PlanmouthDto parDto) throws BusinessException {
        // 判断当前部门下是否已存在年-月-类型相同,若存在则不允许新增
        if (this.checkMonth(parDto.getYear(), parDto.getMouth(),parDto.getMaintenanceFlag())) {
            // JSON转换
            Planmouth planmouth = JSON.parseObject(JSON.toJSONString(parDto), Planmouth.class);
            this.save(planmouth);
            return planmouth.getId();
        }
        throw new BusinessException(Constant.TASK_ADD_YEAR_MONTH_NOT_CODE, Constant.TASK_ADD_YEAR_MONTH_NOT);
    }

    @Override
    public Planmouth getMonthPlanInfo(Long id) throws BusinessException {
        Planmouth info = this.getById(id);
        Optional.ofNullable(info).orElseThrow(() -> new BusinessException(Constant.PLAN_MONTH_NULL_CODE, Constant.PLAN_MONTH_NULL));
        // 返回月计划对应的任务相关信息
        List<Plan> planVoList = planService.list(new QueryWrapper<Plan>().lambda().eq(Plan::getMouthId, info.getId()));
        info.setPlanVoList(planVoList);
        return info;

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateMonthPlanInfo(PlanmouthDto parDto) throws BusinessException {

        if (!iDisposeDateService.isDisposePermissions(parDto.getSubmitUser())) {
            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(JSON.parseObject(JSON.toJSONString(parDto), Planmouth.class));
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteMonthPlanInfo(List<Long> idList) throws BusinessException {
        List<Planmouth> planMouthList = this.list(new QueryWrapper<Planmouth>().lambda().in(Planmouth::getId, idList));

        planMouthList.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<Plan> planList = planService.list(new QueryWrapper<Plan>().lambda().in(Plan::getMouthId, idList));
        if (Optional.ofNullable(planList).isPresent()) {
            planService.removeByIds(planList.stream().map(Plan::getId).collect(Collectors.toList()));
        }
        this.removeByIds(idList);

    }

    @Override
    public PlanyeardetailVo getPlanYearDetail(String yearMonth, String monthId) {
        String[] split = yearMonth.split(Constant.DATE_SEPARATION);
        if (2 == split.length) {
            if (!StringUtils.isEmpty(monthId)) {
                Planmouth planmouth = this.getById(Long.valueOf(monthId));
                // 由于分管经理不属于当前部门,根据当前登录用户需要获取相关计划id列表
                Set<Long> collect = iAuditService.list(new QueryWrapper<Audit>().lambda().eq(Audit::getAuditUser, planmouth.getCreateUser()).eq(Audit::getAuditType, AuditTypeEnum.AUDIT_TYPE_YEAR_PLAN.getCode())).stream().map(Audit::getAuditPlanId).collect(Collectors.toSet());
                if (collect.size() > 0) {
                    PlanyeardetailVo planyeardetailVo = getPlanYearDetailVo(split, collect);
                    if (planyeardetailVo != null) {
                        return planyeardetailVo;
                    }
                }

            } else {
                // 当前部门下用户才有权限
                Long departmentId = SecurityUtils.getUser().getDepartmentId();
                Set<Long> userIdList = departmentClient.getDeptUserList(departmentId).getResult().stream().map(User::getId).collect(Collectors.toSet());
                // 获取当前用户列表创建的年计划id列表
                Set<Long> userPlanIdList = planyearService.list(new QueryWrapper<Planyear>().lambda().in(Planyear::getCreateUser, userIdList)).stream().map(Planyear::getId).collect(Collectors.toSet());

                PlanyeardetailVo planyeardetailVo = getPlanYearDetailVo(split, userPlanIdList);
                if (planyeardetailVo != null) {
                    return planyeardetailVo;
                }
            }


        } else {
            throw new BusinessException(Constant.PLAN_YEAR_MONTH_PARA_ERROR_CODE, Constant.PLAN_YEAR_MONTH_PARA_ERROR);
        }
        return null;
    }

    private PlanyeardetailVo getPlanYearDetailVo(String[] split, Set<Long> userPlanIdList) {
        if (null != userPlanIdList && userPlanIdList.size() > 0) {
            List<Planyeardetail> list = planyeardetailService.list(new QueryWrapper<Planyeardetail>().lambda().in(Planyeardetail::getYearId, userPlanIdList).eq(Planyeardetail::getYear, split[0]).eq(Planyeardetail::getMonth, split[1]));
            if (null != list && list.size() > 0) {
                Planyeardetail planyeardetail = list.get(0);
                // 填充年计划是否审批状态给前端
                Long yearId = planyeardetail.getYearId();
                Planyear byId = planyearService.getById(yearId);
                PlanyeardetailVo planyeardetailVo = JSONObject.parseObject(JSON.toJSONString(planyeardetail), PlanyeardetailVo.class);
                planyeardetailVo.setPlanYearState(byId.getPlanState());
                Long inspectTypeId = planyeardetailVo.getInspectTypeId();
                if (null != inspectTypeId) {
                    planyeardetailVo.setInspectTypeName(inspecttypeService.getById(inspectTypeId).getName());
                }
                return planyeardetailVo;
            }
        }

        return null;
    }

    private Boolean checkMonth(String year, String month,String maintenanceFlag) {
        Long departmentId = SecurityUtils.getUser().getDepartmentId();
        Set<Long> userIdList = departmentClient.getDeptUserList(departmentId).getResult().stream().map(User::getId).collect(Collectors.toSet());
        List<Planmouth> list = this.list(new QueryWrapper<Planmouth>().lambda().eq(Planmouth::getYear, year).eq(Planmouth::getMouth, month).eq(Planmouth::getMaintenanceFlag,maintenanceFlag).in(Planmouth::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);
        Planmouth planmouth = JSON.parseObject(dto, Planmouth.class);
        Planmouth po = this.getMonthPlanInfo(planmouth.getId());

        if (null != po) {
            ExcelExportRepairBasePlan basePlan = new ExcelExportRepairBasePlan();
            // 增加年/月/年备注/计划制定人/上报时间
            basePlan.setYear(po.getYear());
            basePlan.setMonth(po.getMouth());
//            Repairplanyear repairplanyear = repairplanyearService.getById(repairplan.getYearId());
//            basePlan.setNote(repairplanyear.getNote());
            basePlan.setCreateUserName(po.getCreateUserName());
            Date submitTime = po.getSubmitTime();
            if (null != submitTime) {
                basePlan.setSubmitTime(DateTimeUtil.getLocalDateTime(DateTimeUtil.fromLong2LocalDateTime(submitTime.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<Plan> details = po.getPlanVoList();
            if (null != details) {
                // 增加详情
                parentMap.put("list", details);

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

    }

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