/*
 * Author: Zev
 * 生成ServiceImpl
 */
package com.tofly.gpsboot.service.paln.year.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.util.DateTimeUtil;
import com.tofly.pojo.comm.vo.AuditVo;
import com.tofly.pojo.maintain.vo.ExcelExportRepairBasePlan;
import com.tofly.pojo.maintain.vo.ExcelExportRepairPlan;
import com.tofly.pojo.maintain.vo.ExcelExportRepairPlanDetail;
import com.tofly.pojo.plan.dto.PlanyearDto;
import com.tofly.pojo.plan.dto.PlanyeardetailDto;
import com.tofly.pojo.plan.vo.PlanyearVo;
import com.tofly.gpsboot.exception.BusinessException;
import com.tofly.gpsboot.mapper.plan.PlanyearMapper;
import com.tofly.gpsboot.service.comm.IAuditService;
import com.tofly.gpsboot.service.comm.IDisposeDateService;
import com.tofly.gpsboot.service.paln.year.PlanyeardetailService;
import com.tofly.pojo.User;
import com.tofly.pojo.comm.Audit;
import com.tofly.pojo.plan.Planyear;
import com.tofly.gpsboot.service.paln.year.PlanyearService;
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_PLANYEAR_W
 *
 * @author admin
 * @date Thu Mar 18 00:00:00 CST 2021
 */
@Service("planyearService")
public class PlanyearServiceImpl extends ServiceImpl<PlanyearMapper, Planyear> implements PlanyearService {

    @Autowired
    private PlanyeardetailService planyeardetailService;

    @Autowired
    private UserClent userClent;

    @Autowired
    private IAuditService iAuditService;

    @Autowired
    private DepartmentClient departmentClient;

    @Autowired
    private IDisposeDateService iDisposeDateService;

    @Autowired
    private PlanyearMapper planyearMapper;

    @Override
    public List<PlanyearVo> viewConversion(List<Planyear> infoList) {
        List<PlanyearVo> infoVoList = new ArrayList<>();
        infoList.forEach(info -> {
            PlanyearVo baseInfo = JSON.parseObject(JSON.toJSONString(info), PlanyearVo.class);
            // 添加上报人名称 转换上报状态/计划状态
            Long submitUser = info.getSubmitUser();
            if (null != submitUser && 0 != submitUser) {
                User userSubmit = userClent.getById(submitUser).getResult();
                if (null != userSubmit) {
                    baseInfo.setSubmitUserName(userSubmit.getRealName());
                }

            }
            baseInfo.setPlanStateName(AuditSateEnum.getCodeForValue(info.getPlanState()));
            // 返回当前审批链
            List<Audit> list = iAuditService.list(new QueryWrapper<Audit>().lambda().eq(Audit::getAuditPlanId, info.getId()).eq(Audit::getAuditType, AuditTypeEnum.AUDIT_TYPE_YEAR_PLAN.getCode()));
            if (null != list && list.size() > 0) {
                baseInfo.setAuditVoList(iAuditService.viewConversion(list));
            }
            User reslut = userClent.getById(baseInfo.getCreateUser()).getResult();
            if (null != reslut) {
                baseInfo.setCreateUserName(reslut.getRealName());

            }
            baseInfo.setIssubmitName(IsSubmitEnum.getCodeForValue(info.getIssubmit()));
            infoVoList.add(baseInfo);
        });
        return infoVoList;
    }


    @Override
    public Page<PlanyearVo> getInfoPage(Page page, PlanyearDto parDto) {
        // 审批状态 , 分割查询
        String planState = parDto.getPlanState();
        Planyear planyear = JSONObject.parseObject(JSON.toJSONString(parDto), Planyear.class);
        QueryWrapper<Planyear> 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);
            planyear.setPlanState(null);
        }
        // 获取当前用户列表创建的年计划id列表
        Set<Long> userPlanIdList = this.list(new QueryWrapper<Planyear>().lambda().in(Planyear::getCreateUser, userIdList)).stream().map(Planyear::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)).collect(Collectors.toList());
            wrapper.in("YEAR", yearList);
        }
        wrapper.orderByDesc("YEAR");
        wrapper.setEntity(planyear);
        Page infoPageList = this.page(page, wrapper);
        infoPageList.setRecords(this.viewConversion(infoPageList.getRecords()));
        return infoPageList;
    }

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


        if (!StringUtils.isEmpty(planState)) {
            List<String> longList = Arrays.stream(planState.split(Constant.CSV)).collect(Collectors.toList());
            wrapper.in("PLAN_STATE", longList);
            planyear.setPlanState(null);
        }
        // 由于分管经理不属于当前部门,根据当前登录用户需要获取相关计划id列表
        Set<Long> collect = iAuditService.list(new QueryWrapper<Audit>().lambda().eq(Audit::getAuditUser, SecurityUtils.getUserId()).eq(Audit::getAuditType, AuditTypeEnum.AUDIT_TYPE_YEAR_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)).collect(Collectors.toList());
            wrapper.in("YEAR", yearList);
        }
        wrapper.orderByDesc("YEAR");
        wrapper.setEntity(planyear);
        Page infoPageList = this.page(page, wrapper);
        infoPageList.setRecords(this.viewConversion(infoPageList.getRecords()));
        return infoPageList;
    }

    @Override
    public Page<PlanyearVo> getAllList(Page page, PlanyearDto parDto) {
        // 审批状态 , 分割查询
        String planState = parDto.getPlanState();
        Planyear planyear = JSONObject.parseObject(JSON.toJSONString(parDto), Planyear.class);
        QueryWrapper<Planyear> 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);
            planyear.setPlanState(null);
        }
        // 获取当前用户列表创建的年计划id列表
        Set<Long> userPlanIdList = this.list(new QueryWrapper<Planyear>().lambda().in(Planyear::getCreateUser, userIdList)).stream().map(Planyear::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_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 = parDto.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(planyear);
        Page infoPageList = this.page(page, wrapper);
        infoPageList.setRecords(this.viewConversion(infoPageList.getRecords()));
        return infoPageList;
    }

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

        if (!StringUtils.isEmpty(planState)) {
            List<String> longList = Arrays.stream(planState.split(Constant.CSV)).collect(Collectors.toList());
            wrapper.in("PLAN_STATE", longList);
            planyear.setPlanState(null);
        }
        // 由于分管经理不属于当前部门,根据当前登录用户需要获取相关计划id列表
        Set<Long> collect = iAuditService.list(new QueryWrapper<Audit>().lambda()
                .eq(Audit::getAuditUser, SecurityUtils.getUserId())
                .eq(Audit::getAuditType, AuditTypeEnum.AUDIT_TYPE_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 = parDto.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(planyear);
        Page infoPageList = this.page(page, wrapper);
        infoPageList.setRecords(this.viewConversion(infoPageList.getRecords()));
        return infoPageList;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public PlanyearDto savaYearPlanInfo(PlanyearDto parDto) throws BusinessException {
        // 判断当前部门下是否已存在年,若存在则不允许新增
        if (this.checkYear(parDto.getYear())) {
            // 判断当前详情计划传入是否为空值
            if (null != parDto.getPlanyeardetailDtoList() && parDto.getPlanyeardetailDtoList().size() > 0) {
                // JSON转换
                Planyear planyear = JSON.parseObject(JSON.toJSONString(parDto), Planyear.class);
                // 上报状态数据库默认值设为 0 未上报 审核意见数据库默认值设为 0 未审核 是否接收查看数据库默认值设为 0：未查看
                this.save(planyear);

                Long id = planyear.getId();
                List<Planyeardetail> planetoids = JSONArray.parseArray(JSON.toJSONString(parDto.getPlanyeardetailDtoList()), Planyeardetail.class);
                planetoids.forEach(info -> {
                    info.setYearId(id);
                    planyeardetailService.save(info);

                });
                parDto.setId(planyear.getId());
                parDto.setCreateUser(planyear.getCreateUser());
                return parDto;
            } 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
    public PlanyearVo getYearPlanInfo(Long id) throws BusinessException {
        Planyear info = this.getById(id);
        Optional.ofNullable(info).orElseThrow(() -> new BusinessException(Constant.PLAN_YEAR_NULL_CODE, Constant.PLAN_YEAR_NULL));
        PlanyearVo planyearVo = JSON.parseObject(JSON.toJSONString(info), PlanyearVo.class);
        List<Planyeardetail> list = planyeardetailService.list(new QueryWrapper<Planyeardetail>().lambda().eq(Planyeardetail::getYearId, info.getId()));
        planyearVo.setPlanyeardetailList(list);
        return planyearVo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateYearPlanInfo(PlanyearDto 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);
        }
        Planyear planyear = JSON.parseObject(JSON.toJSONString(parDto), Planyear.class);
        this.updateById(planyear);
        List<PlanyeardetailDto> planyeardetailDtoList = parDto.getPlanyeardetailDtoList();

        planyeardetailService.removeByIds(planyeardetailService.list(new QueryWrapper<Planyeardetail>().lambda().eq(Planyeardetail::getYearId, planyear.getId())).stream().map(Planyeardetail::getId).collect(Collectors.toList()));
        if (null != planyeardetailDtoList && planyeardetailDtoList.size() > 0) {
            List<Planyeardetail> planyeardetailList = JSONArray.parseArray(JSON.toJSONString(planyeardetailDtoList), Planyeardetail.class);
            planyeardetailList.forEach(info -> {
                info.setYearId(parDto.getId());
                planyeardetailService.save(info);
            });
        }

    }

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

        List<Planyear> planYearList = this.list(new QueryWrapper<Planyear>().lambda().in(Planyear::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<Planyeardetail> list = planyeardetailService.list(new QueryWrapper<Planyeardetail>().lambda().in(Planyeardetail::getYearId, idList));
            this.removeByIds(idList);
            if (Optional.ofNullable(list).isPresent()) {
                List<Long> ids = list.stream().map(Planyeardetail::getYearId).collect(Collectors.toList());
                planyeardetailService.removeByIds(ids);
            }
        });

    }

    /**
     * 判断当前部门下是否可以新增年
     *
     * @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<Planyear> list = this.list(new QueryWrapper<Planyear>().lambda().eq(Planyear::getYear, year).in(Planyear::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);
        // 只导出数据,没有模板
        Planyear repairplanyear = JSONObject.parseObject(dto, Planyear.class);
        Long id = repairplanyear.getId();
        if (!StringUtils.isEmpty(id)) {
            PlanyearVo po = planyearMapper.getPlanYearVoList(id).get(0);
            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<Planyeardetail> details = po.getPlanyeardetailList();
            if (null != details) {
                List<ExcelExportRepairPlan> planList = new ArrayList<>();
                // 按照维修类型分组
                Map<String, List<Planyeardetail>> collect = details.stream().filter(i -> null != i.getInspectTypeId()).collect(Collectors.groupingBy(Planyeardetail::getInspectTypeName, 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_INSPECTION_YEAR_PLAN_ID_NULL_ERROR_CODE, Constant.EXCEL_EXPORT_INSPECTION_YEAR_PLAN_ID_NULL_ERROR);
        }
        returnMap.add(parentMap);
        return returnMap;
    }

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