package com.xunmei.core.resumption.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xunmei.common.core.constant.SecurityConstants;
import com.xunmei.common.core.domain.IdName;
import com.xunmei.common.core.vo.IdNameVo;
import com.xunmei.common.core.web.page.TableDataInfo;
import com.xunmei.core.resumption.domain.AppResumptionTaskDataRemarkimg;
import com.xunmei.core.resumption.domain.Protection;
import com.xunmei.core.resumption.domain.Resumption;
import com.xunmei.core.resumption.dto.resumptionRecord.ResumptionNFCDto;
import com.xunmei.core.resumption.dto.resumptionRecord.ResumptionRecordPageDto;
import com.xunmei.core.resumption.dto.resumptionRecord.ResumptionRoleDto;
import com.xunmei.core.resumption.mapper.AppPlanMapper;
import com.xunmei.core.resumption.mapper.AppResumptionTaskDataRemarkimgMapper;
import com.xunmei.core.resumption.mapper.ProtectionMapper;
import com.xunmei.core.resumption.mapper.ResumptionRecordMapper;
import com.xunmei.core.resumption.service.AppPlanService;
import com.xunmei.core.resumption.service.IResumptionRecordService;
import com.xunmei.core.resumption.vo.resumptionRecord.*;
import com.xunmei.system.api.Eto.RoleConditionEto;
import com.xunmei.system.api.RemoteOrgService;
import com.xunmei.system.api.RemoteRoleService;
import com.xunmei.system.api.domain.Org;
import io.netty.util.internal.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundValueOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author jingyuanchao
 * @since 2022-05-11
 */
@Slf4j
@Service
public class ResumptionRecordServiceImpl extends ServiceImpl<ResumptionRecordMapper, Resumption> implements IResumptionRecordService {
    @Resource
    private RemoteOrgService orgService;
    //    @Resource
//    private OrgRepository orgRepository;
//    @Autowired
//    IFileService fileService;
//    @Resource
//    private ObjectMapper objectMapper;
    @Resource
    private AppResumptionTaskDataRemarkimgMapper taskDataRemarkimgMapper;
    @Resource
    private RedisTemplate<String, String> redisTemplate;

    @Resource
    private RemoteRoleService roleService;
    @Resource
    private AppPlanService appPlanService;

    @Resource
    AppPlanMapper appPlanMapper;

    @Override
    public TableDataInfo selectList(ResumptionRecordPageDto pageDto) {
        Page<ResumptionRecordPageVo> page = pageDto.getPageDto();

        Boolean isPage = Boolean.FALSE;

        String strDate = DateUtil.format(new Date(), "yyyy-MM-dd");
 /*       String orgKey = "resumptionRecordOrgList" + strDate;
        Object objOrg = redisTemplate.opsForValue().get(orgKey);
        List<Org> orgList = null;
        if (ObjectUtil.isNotEmpty(objOrg)) {
            orgList = JSON.parseArray(objOrg.toString(), Org.class);
        } else {
            orgList = orgService.all();
            if (CollectionUtils.isNotEmpty(orgList)) {
                this.redisTemplate.opsForValue().set(orgKey, JSON.toJSONString(orgList));
                //设置过期时间24小时
                this.redisTemplate.expire(orgKey, 24, TimeUnit.HOURS);
            }
        }*/
        if(pageDto.getCheckSub()){
            List<Long> orgList = orgService.selectCheckSubOrgIdList(pageDto.getOrgId(), SecurityConstants.INNER);
            pageDto.setOrgIdList(orgList);
            pageDto.setOrgId(null);
        }

//        if (pageDto.getCheckSub() && ObjectUtil.isNotEmpty(pageDto.getOrgId())) {
//            final Org org = orgService.find(pageDto.getOrgId());
//            pageDto.setOrgId(null);
//            List<Long> orgIds = new ArrayList<>();
//            orgList.forEach(org1 -> {
//                if (org1.getPath().contains(org.getPath())) {
//                    orgIds.add(org1.getId());
//                }
//            });
//            pageDto.setOrgIdList(orgIds);
//        }
        final HashMap<String, Object> hashMap = new HashMap<>();
        Set<Integer> ymdQuarters = new HashSet<>();
        Boolean isTime = Boolean.FALSE;
        if (ObjectUtil.isNotNull(pageDto.getRange()) && ObjectUtil.isAllNotEmpty(pageDto.getRange()[0], pageDto.getRange()[1])) {
            isTime = Boolean.TRUE;
            Date[] range = pageDto.getRange();
            Date startDate = DateUtil.date(range[0]);
            Date endDate = DateUtil.date(range[1]);
            Calendar startCalendar = Calendar.getInstance();
            Calendar endCalendar = Calendar.getInstance();
            startCalendar.setTime(startDate);
            endCalendar.setTime(endDate);
            int startYear = DateUtil.year(startDate);
            int endYear = DateUtil.year(endDate);
            //计算startDate和endDate相差多少个月
            int yearDiff = endCalendar.get(Calendar.YEAR) - startCalendar.get(Calendar.YEAR);
            int monthDiff = endCalendar.get(Calendar.MONTH) - startCalendar.get(Calendar.MONTH);
            int totalMonths = yearDiff * 12 + monthDiff;
            if (totalMonths < 0) {
                throw new RuntimeException("开始时间不能大于结束时间");
            }
            for (int i = 0; i <= totalMonths; i++) {
                ymdQuarters.add(DateUtil.quarter(DateUtil.offsetMonth(startDate, i)));
            }
            hashMap.put("startYear", startYear);
            hashMap.put("endYear", endYear);
            hashMap.put("startDate", DateUtil.formatDate(startDate));
            hashMap.put("endDate", DateUtil.formatDate(endDate));
            switch (pageDto.getExecuteCycle()) {
                case 1:
                case 2:
                 /*   hashMap.put("startDate", DateUtil.formatDate(startDate));
                    hashMap.put("endDate", DateUtil.formatDate(endDate));*/
                    break;
                case 3:
                    //每周履职
                    startCalendar.setMinimalDaysInFirstWeek(6);
                    int startWeek = startCalendar.get(Calendar.WEEK_OF_YEAR);
                    hashMap.put("startWeek", String.valueOf(startWeek));
                    //hashMap.put("endWeek", String.valueOf(endWeek));
                    break;
                case 4:
                    //每月履职
                    int startMonth = startCalendar.get(Calendar.MONTH) + 1;
                    int endMonth = endCalendar.get(Calendar.MONTH) + 1;
                   /* hashMap.put("startMonth", String.valueOf(startMonth));
                    hashMap.put("endMonth", String.valueOf(endMonth));*/
                    hashMap.put("startMonth", DateUtil.format(startCalendar.getTime(), "yyyy-MM-dd"));
                    hashMap.put("endMonth", DateUtil.format(endCalendar.getTime(), "yyyy-MM-dd"));
                    break;
                case 5:
                    //每季度履职
                    int startQuarter = getCurrentQuarter(startDate);
                    int endQuarter = getCurrentQuarter(endDate);
                    hashMap.put("startQuarter", String.valueOf(startQuarter));
                    hashMap.put("endQuarter", String.valueOf(endQuarter));
                    break;
                case 6:
                    //每半年履职
                    int startHalfYear = getCurrentHalfYear(startDate);
                    int endHalfYear = getCurrentHalfYear(endDate);
                    hashMap.put("startHalfYear", String.valueOf(startHalfYear));
                    hashMap.put("endHalfYear", String.valueOf(endHalfYear));
                    break;
                default:
                    break;
            }
        }

//        if (isPage) {
//            RESUMPTIONOVERVIEWLOG.info("履职记录查询,查询条件: pageDto: {},hashMap:{},isTime:{}", JSON.toJSONString(pageDto), JSON.toJSONString(hashMap), isTime);
        page = baseMapper.selectPageByCondition(page, pageDto, hashMap, isTime, ymdQuarters);
        dealData(page.getRecords());
        return TableDataInfo.success(page);
//        } else {
////            RESUMPTIONOVERVIEWLOG.info("履职记录导出,查询条件: pageDto: {},hashMap:{}", JSON.toJSONString(pageDto), JSON.toJSONString(hashMap));
//            final List<ResumptionRecordPageVo> list = resumptionRecordMapper.selectListByCondition(pageDto, hashMap, isTime, ymdQuarters);
//            dealData(list, orgList, strDate);
//            return list;
//        }
    }


    private void dealData(List<ResumptionRecordPageVo> list) {
        if (list.size() < 1) {
            return;
        }
//        String roleKey = "resumptionRecordRoleList" + strDate;
//        BoundValueOperations<String, String> boundValueOps = redisTemplate.boundValueOps(roleKey);
//        String s = boundValueOps.get();
//        List<Role> roleList = null;
//        if (ObjectUtil.isNotEmpty(s)) {
//            roleList = JSON.parseArray(s, Role.class);
//        } else {
//            roleList = objectMapper.selectAllRole();
//            if (CollectionUtils.isNotEmpty(list)) {
//                boundValueOps.set(JSON.toJSONString(roleList));
//                boundValueOps.expireAt(DateUtil.endOfDay(new Date()));
//            }
//        }

   /*=    String planKey = "resumptionRecordPlanList"+strDate;
        BoundValueOperations<String, String> operations = redisTemplate.boundValueOps(planKey);
        String objPlan = operations.get();
        List<AppPlan> planList =null;
        if(ObjectUtil.isNotEmpty(objPlan)) {
            planList = JSON.parseArray(objPlan,AppPlan.class);
        }else{
            planList =objectMapper.selectAllPlan();
            if(CollectionUtils.isNotEmpty(list)){
                operations.set(JSON.toJSONString(list));
                operations.expireAt(DateUtil.endOfDay(new Date()));
            }
        }*/

        List<IdNameVo> planList = appPlanMapper.selectPlanNames(list.stream().map(i -> i.getPlanId()).distinct().collect(Collectors.toList()));
        List<IdNameVo> orgNames = orgService.getParentName(list.stream().map(i -> i.getOrgId()).distinct().collect(Collectors.toList()));
        List<IdNameVo> roleNames= roleService.getNames(RoleConditionEto
                .builder()
                .ids(list.stream().map(i -> i.getRoleId()).distinct().collect(Collectors.toList())).build());
        list.stream().filter(pageVo -> ObjectUtil.equal(pageVo.getStatus(), "1")).forEach(pageVo -> pageVo.setSubmitter(null));

        //List<Org> orgList = orgService.all();
        for (ResumptionRecordPageVo vo : list) {
            Optional<IdNameVo> org = orgNames.stream().filter(i -> ObjectUtil.equal(vo.getOrgId(), i.getId())).findFirst();
            if (org.isPresent()) {
                vo.setOrgName(org.get().getName());
                vo.setParentOrgName(org.get().getExtra());
            }
            Optional<IdNameVo> plan=planList.stream().filter(i -> ObjectUtil.equal(vo.getPlanId(), i.getId())).findFirst();
            if (plan.isPresent()) {
                vo.setPlanName(plan.get().getName());
            }

            Optional<IdNameVo>  role = roleNames.stream().filter(r -> r.getId().equals(vo.getRoleId())).findFirst();
            if (role.isPresent()) {
                vo.setRoleName(role.get().getName());
            }
        }
    }

//    @Override
//    public List<SecBookDtInst> selectSecBookDtInstList() {
//        return resumptionRecordMapper.selectSecBookDtInstList();
//
//    }

    @Override
    public List<ResumptionRecordInfoVo> selectInfo(String resumptionId,String ymd) {
//        final List<SecBookDtInst> secBookDtList = selectSecBookDtInstList();

        List<ResumptionRecordInfoVo> arrayList = new ArrayList<>();
        List<Long> ItemidList = baseMapper.selectItemIdList(resumptionId);
        //List<Long> ruleItemIdList = resumptionRecordMapper.selectRuleItemIdList(resumptionId);
        List<Long> ruleItemIdList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(ItemidList)) {
            ruleItemIdList = baseMapper.selectRuleItemIdListNew(ItemidList);
        }
        for (Long ruleItemId : ruleItemIdList) {
            ResumptionRecordInfoVo info = baseMapper.selectRuleItemInfo(ruleItemId);
            arrayList.add(info);
            List<AppResumptionDataInfoVo> dataInfoList = baseMapper.selectDataInfo(ruleItemId, resumptionId);
            info.setDataInfoList(dataInfoList);
        }
        final ArrayList<Long> list = new ArrayList<>();
        for (ResumptionRecordInfoVo infoVo : arrayList) {
            infoVo.getDataInfoList().stream().map(AppResumptionDataInfoVo::getDataId).forEach(list::add);
        }

        if (list.size() > 0) {
            //  final List<AppResumptionDataImg> dataImgList = dataImgMapper.selectList(new LambdaQueryWrapper<AppResumptionDataImg>().in(AppResumptionDataImg::getDataId, list));
            final List<AppResumptionTaskDataRemarkimg> taskDataRemarkimgList = taskDataRemarkimgMapper.selectList(new LambdaQueryWrapper<AppResumptionTaskDataRemarkimg>().in(AppResumptionTaskDataRemarkimg::getTaskDataId, list));

            for (ResumptionRecordInfoVo infoVo : arrayList) {
                for (AppResumptionDataInfoVo dataInfoVo : infoVo.getDataInfoList()) {
                    final List<AppResumptionTaskDataRemarkimg> imgList = taskDataRemarkimgList.stream().filter(appResumptionDataImg -> appResumptionDataImg.getTaskDataId().equals(dataInfoVo.getDataId())).collect(Collectors.toList());
                    dataInfoVo.setAppResumptionDataImgList(imgList);
                    final String executeResult = dataInfoVo.getExecuteResult();
                    if (StringUtils.isNotEmpty(executeResult)) {
//                        final Long dataTypeId = dataInfoVo.getDataTypeId();
//                        final SecBookDtInst secBookDtInst = secBookDtList.stream().filter(sec -> sec.getId().equals(dataTypeId)).findFirst().orElse(null);
//                        if (secBookDtInst != null) {
//                            final List<SecBookDtiInst> dataItemList = secBookDtInst.getDataItemList();
//                            final SecBookDtiInst secBookDtiInst = dataItemList.stream().filter(sec -> String.valueOf(sec.getDataItemValue()).equals(executeResult)).findFirst().orElse(null);
//                            dataInfoVo.setExecuteResult(secBookDtiInst == null ? "" : secBookDtiInst.getDataItemName());
//                            dataInfoVo.setExecuteFlag(secBookDtiInst == null ? "" : secBookDtiInst.getDataItemNumb());
//
//                        }
                    }

//                    final Set<String> keys = redisTemplate.keys("dict_config_check_type*");
//                    if (ObjectUtil.isNotNull(keys) && keys.size() > 0) {
//                        for (String key : keys) {
//                            final String code = key.split("_")[4];
//                            final String safeType = dataInfoVo.getSafeType();
//                            if (safeType == null) {
//                                continue;
//                            }
//                            if (dataInfoVo.getSafeType().equals(code)) {
//                                final String name = redisTemplate.opsForValue().get(key);
//                                dataInfoVo.setSafeType(name);
//                                break;
//                            }
//                        }
//                    }
                }
            }
        }
        return arrayList;
    }

    @Override
    public List<IdNameVo> selectResumptionRole(ResumptionRoleDto query) {
        if(ObjectUtil.isNotNull(query.getOrgId()) ){
            List<Long> upOrgIds=orgService.getUpOrgs(query.getOrgId());
            if(CollectionUtil.isNotEmpty(upOrgIds) && upOrgIds.size()>1){
                query.setUpOrgIds(upOrgIds); //顶级机构不用
            }
        }
        return baseMapper.selectResumptionRoles(query);
    }

    @Override
    public List<IdNameVo> selectResumptionPlan(ResumptionRoleDto query) {
        if(ObjectUtil.isNotNull(query.getOrgId()) ){
            List<Long> upOrgIds=orgService.getUpOrgs(query.getOrgId());
            if(CollectionUtil.isNotEmpty(upOrgIds) && upOrgIds.size()>1){
                query.setUpOrgIds(upOrgIds); //顶级机构不用
            }
        }
        final List<IdNameVo> list = baseMapper.selectResumptionPlan(query);
        return list;
    }

    @Override
    public List<NFCRecordVo> selectNFCRecord(ResumptionNFCDto dto) {
        return baseMapper.selectNFCRecord(dto);
    }


    @Override
    public void export(ResumptionRecordPageDto pageDto, HttpServletResponse response) throws Exception {
//        Org org = orgService.find(pageDto.getOrgId());
//        if (org == null) {
//            throw new RuntimeException("请选择机构再导出数据");
//        }
//        pageDto.setPage(null);
//        pageDto.setSize(null);
//        final List<ResumptionRecordPageVo> data = (List<ResumptionRecordPageVo>) this.selectList(pageDto);
//        if (data.size() == 0) {
//            throw new RuntimeException("暂无可用数据导出!");
//        }
//        String newFile = "【" + org.getName() + "】-履职记录" + DateHelper.getDateString(new Date()) + ".et";
//        InputStream stream = FileExportUtils.getTemplateExcel("ResumptionRecord");
//        ExcelReader er = ExcelUtil.getReader(stream);
//
//        ExcelWriter ew = er.getWriter();
//        int len = ew.getColumnCount();
//        int r = 1;
//        for (ResumptionRecordPageVo rowData : data) {
//            Row row = ew.getOrCreateRow(r);
//            for (int i = 0; i < len; i++) {
//                Cell cell = row.createCell(i);
//                switch (i) {
//                    case 0:
//                        cell.setCellValue(rowData.getPlanName());
//                        break;
//                    case 1:
//                        cell.setCellValue(DateHelper.toStr(rowData.getPlanStartTime()));
//                        break;
//                    case 2:
//                        cell.setCellValue(DateHelper.toStr(rowData.getPlanEndTime()));
//                        break;
//                    case 3:
//                        String status = StringUtil.EMPTY_STRING;
//                        switch (rowData.getStatus()) {
//                            case 0:
//                                status = "待履职";
//                                break;
//                            case 1:
//                                status = "按时完成";
//                                break;
//                            case 3:
//                                status = "未完成";
//                                break;
//                            case 5:
//                                status = "补登完成";
//                                break;
//                            default:
//                                break;
//                        }
//                        cell.setCellValue(status);
//                        break;
//                    case 4:
//                        cell.setCellValue(rowData.getParentOrgName());
//                        break;
//                    case 5:
//                        cell.setCellValue(rowData.getOrgName());
//                        break;
//                    case 6:
//                        cell.setCellValue(rowData.getRoleName());
//                        break;
//                    case 7:
//                        cell.setCellValue(DateHelper.toStr(rowData.getSubmitTime()));
//                        break;
//                    case 8:
//                        cell.setCellValue(rowData.getSubmitter());
//                        break;
//                    case 9:
//                        cell.setCellValue(rowData.getAbnormalDataNums());
//                        break;
//                    default:
//                        break;
//                }
//            }
//            r++;
//        }
//        ew.autoSizeColumnAll();
//        FileExportUtils.downloadExcelStream(response, ew, newFile);
    }

    private int getCurrentQuarter(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.MONTH) / 3 + 1;
    }

    private int getCurrentHalfYear(Date date) {
        return DateUtil.dayOfMonth(date) <= 6 ? 1 : 2;

    }
}
