package com.jeeplus.test.cw.projectReportArchive.service;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.druid.sql.dialect.odps.ast.OdpsStatisticClause;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.jeeplus.core.query.QueryWrapperGenerator;
import com.jeeplus.flowable.service.FlowTaskService;
import com.jeeplus.sys.domain.User;
import com.jeeplus.sys.mapper.UserMapper;
import com.jeeplus.sys.service.dto.UserDTO;
import com.jeeplus.sys.utils.StringUtils;
import com.jeeplus.sys.utils.UserUtils;
import com.jeeplus.test.cw.common.CommonUtils;
import com.jeeplus.test.cw.projectRecords.domain.CwProjectRecords;
import com.jeeplus.test.cw.projectReport.mapper.CwProjectInfoMapper;
import com.jeeplus.test.cw.projectReportArchive.domain.CwProjectReportArchive;
import com.jeeplus.test.cw.projectReportArchive.domain.CwProjectReportArchiveFile;
import com.jeeplus.test.cw.projectReportArchive.mapper.CwProjectReportArchiveFileMapper;
import com.jeeplus.test.cw.projectReportArchive.mapper.CwProjectReportArchiveMapper;
import com.jeeplus.test.cw.projectReportArchive.mapper.CwProjectReportArchiveReportMapper;
import com.jeeplus.test.cw.projectRecords.mapper.CwProjectRecordsMapper;
import com.jeeplus.test.cw.projectReportArchive.service.dto.CwProjectReportArchiveDTO;
import com.jeeplus.test.cw.projectReportArchive.service.dto.ReportDTO;
import com.jeeplus.test.cw.projectReportArchive.service.mapstruct.CwProjectReportArchiveWrapper;
import com.jeeplus.test.mould.service.SerialnumTplService;
import com.jeeplus.test.oss.domain.WorkAttachment;
import com.jeeplus.test.oss.mapper.OssServiceMapper;
import com.jeeplus.test.oss.service.OssService;
import com.jeeplus.test.workContract.service.dto.WorkAttachmentDto;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

@Service
@Transactional
public class CwProjectReportArchiveService extends ServiceImpl<CwProjectReportArchiveMapper, CwProjectReportArchive> {

    @Resource
    private CwProjectReportArchiveMapper cwProjectReportArchiveMapper;
    @Resource
    private CwProjectReportArchiveReportMapper cwProjectReportArchiveReportMapper;
    @Resource
    private CwProjectReportArchiveFileMapper cwProjectReportArchiveFileMapper;
    @Resource
    private CwProjectRecordsMapper cwProjectRecordsMapper;
    @Resource
    private OssService ossService;
    @Resource
    private OssServiceMapper ossServiceMapper;
    @Resource
    private UserMapper userMapper;
    @Resource
    private CwProjectInfoMapper cwProjectInfoMapper;
    @Resource
    private SerialnumTplService serialnumTplService;
    @Resource
    private FlowTaskService flowTaskService;

    /**
     * 项目归档列表信息
     * @param page
     * @param cwProjectReportArchiveDTO
     * @return
     * @throws Exception
     */
    public IPage<CwProjectReportArchiveDTO> findList(Page<CwProjectReportArchiveDTO> page, CwProjectReportArchiveDTO cwProjectReportArchiveDTO) throws Exception{
        QueryWrapper<CwProjectReportArchive> queryWrapper = QueryWrapperGenerator.buildQueryCondition ( CwProjectReportArchiveWrapper.INSTANCE.toEntity(cwProjectReportArchiveDTO), CwProjectReportArchive.class );
        queryWrapper.eq("cw_pa.del_flag","0");
//        queryWrapper.orderByDesc("cw_pa.create_date");
        if (ObjectUtil.isNotEmpty(cwProjectReportArchiveDTO)) {
            if (ObjectUtil.isNotEmpty(cwProjectReportArchiveDTO.getCwProjectRecordsDTO())){
                // 项目名称
                if (StringUtils.isNotBlank(cwProjectReportArchiveDTO.getCwProjectRecordsDTO().getProjectName())){
                    List<CwProjectRecords> cwProjectRecords = cwProjectRecordsMapper.selectList(new QueryWrapper<CwProjectRecords>().lambda().like(CwProjectRecords::getProjectName, cwProjectReportArchiveDTO.getCwProjectRecordsDTO().getProjectName()));
                    List<String> ids = cwProjectRecords.stream().map(CwProjectRecords::getId).collect(Collectors.toList()).stream().distinct().collect(Collectors.toList());
                    if(CollectionUtil.isNotEmpty(ids)) {
                        queryWrapper.in("cw_pa.project_id",ids);
                    }else{
                        return new Page<>();
                    }
                }
                // 项目经理1
                if (StringUtils.isNotBlank(cwProjectReportArchiveDTO.getCwProjectRecordsDTO().getProjectMasterName())){
                    List<User> userList = userMapper.selectList(new QueryWrapper<User>().lambda().like(User::getName, cwProjectReportArchiveDTO.getCwProjectRecordsDTO().getProjectMasterName()));
                    List<String> userIdList = userList.stream().map(User::getId).collect(Collectors.toList()).stream().distinct().collect(Collectors.toList());
                    if (CollectionUtil.isNotEmpty(userIdList)){
                        List<CwProjectRecords> cwProjectRecords = cwProjectRecordsMapper.selectList(new QueryWrapper<CwProjectRecords>().lambda().in(CwProjectRecords::getProjectMasterId, userIdList));
                        List<String> projectIds = cwProjectRecords.stream().map(CwProjectRecords::getId).collect(Collectors.toList()).stream().distinct().collect(Collectors.toList());
                        if (CollectionUtil.isNotEmpty(projectIds)){
                            queryWrapper.in("cw_pa.project_id",projectIds);
                        }else{
                            return new Page<>();
                        }
                    }else{
                        return new Page<>();
                    }
                }
                // 项目经理2
                if (StringUtils.isNotBlank(cwProjectReportArchiveDTO.getCwProjectRecordsDTO().getRealHeaderName())){
                    List<User> userList = userMapper.selectList(new QueryWrapper<User>().lambda().like(User::getName, cwProjectReportArchiveDTO.getCwProjectRecordsDTO().getRealHeaderName()));
                    List<String> userIdList = userList.stream().map(User::getId).collect(Collectors.toList()).stream().distinct().collect(Collectors.toList());
                    if (CollectionUtil.isNotEmpty(userIdList)){
                        List<CwProjectRecords> cwProjectRecords = cwProjectRecordsMapper.selectList(new QueryWrapper<CwProjectRecords>().lambda().in(CwProjectRecords::getRealHeader, userIdList));
                        List<String> projectIds = cwProjectRecords.stream().map(CwProjectRecords::getId).collect(Collectors.toList()).stream().distinct().collect(Collectors.toList());
                        if (CollectionUtil.isNotEmpty(projectIds)){
                            queryWrapper.in("cw_pa.project_id",projectIds);
                        }else{
                            return new Page<>();
                        }
                    }else{
                        return new Page<>();
                    }
                }
                // 创建时间
                if (ArrayUtil.isNotEmpty(cwProjectReportArchiveDTO.getCreateDates())){
                    queryWrapper.between("cw_pa.create_date", cwProjectReportArchiveDTO.getCreateDates()[0], cwProjectReportArchiveDTO.getCreateDates()[1]);
                }
                // 归档时间
                if (ArrayUtil.isNotEmpty(cwProjectReportArchiveDTO.getAuditDates())){
                    queryWrapper.between("cw_pa.audit_date", cwProjectReportArchiveDTO.getAuditDates()[0], cwProjectReportArchiveDTO.getAuditDates()[1]);
                }
                // 创建人
                if (ObjectUtil.isNotEmpty(cwProjectReportArchiveDTO.getCreateBy())){
                    if (StringUtils.isNotBlank(cwProjectReportArchiveDTO.getCreateBy().getName())){
                        List<User> userList = userMapper.selectList(new QueryWrapper<User>().lambda().like(User::getName, cwProjectReportArchiveDTO.getCreateBy().getName()));
                        List<String> ids = userList.stream().map(User::getId).collect(Collectors.toList()).stream().distinct().collect(Collectors.toList());
                        if (CollectionUtil.isNotEmpty(ids)){
                            queryWrapper.in("cw_pa.create_by",ids);
                        }else{
                            return new Page<>();
                        }
                    }
                }
                // 报告文号
                if (StringUtils.isNotBlank(cwProjectReportArchiveDTO.getReportNo())) {
                    queryWrapper.like("cw_prnl.report_no",cwProjectReportArchiveDTO.getReportNo());
                }

            }
        }
        String isBmzr = "0";
        StringBuilder officeIds = new StringBuilder();
        UserDTO userDTO = UserUtils.getCurrentUserDTO();
        List<String> manageOfficeIdList= Lists.newArrayList();

        if (StringUtils.isBlank(cwProjectReportArchiveDTO.getArchiveSta())) {
            cwProjectReportArchiveDTO.setArchiveSta("");
        }
        IPage<CwProjectReportArchiveDTO> list = cwProjectReportArchiveMapper.findList(page, userDTO, isBmzr, officeIds.toString(), queryWrapper, cwProjectReportArchiveDTO.getArchiveSta());
        List<CwProjectReportArchiveDTO> records = list.getRecords();
        if (null != records && records.size()>0){
            //循环查询出来的数据
            for (CwProjectReportArchiveDTO info : records) {
                //如果归档日期为空，则表示该报告还未归档
                if(null == info.getAuditDate()){
                    //如果归档日期差大于60天，表示超期未归档
                    if(info.getArchiveDay()>60){
                        info.setArchiveSta("超期未归档");
                        long n = (info.getArchiveDay()) / 60;
                        String money = Long.toString(n * 200);
                        info.setOverdueDay(String.valueOf(info.getArchiveDay() - 60));
                        info.setFineMoney(money);
                    }else{
                        //如果归档日期差小于等于60天，表示暂时未归档
                        info.setArchiveSta("暂时未归档");
                        info.setOverdueDay(String.valueOf(info.getArchiveDay() - 60));
                        info.setFineMoney("0");
                    }
                } else {
                    //如果归档日期不为空，则表示该报告已归档

                    //如果归档日期差大于60天，表示已超期归档
                    if(info.getArchiveDay()>60){
                        info.setArchiveSta("已超期归档");
                        long n = (info.getArchiveDay()) / 60;
                        String money = Long.toString(n * 200);
                        info.setOverdueDay(String.valueOf(info.getArchiveDay() - 60));
                        info.setFineMoney(money);
                    }else{
                        //如果归档日期差小于等于60天，表示已按时归档
                        info.setArchiveSta("已按时归档");
                        info.setOverdueDay(String.valueOf(info.getArchiveDay() - 60));
                        info.setFineMoney("0");
                    }
                }
                // 报告归档
                if (StringUtils.isNotBlank(info.getTaskId()) && StringUtils.isNotBlank(info.getStatus())) {
                    if ("2".equals(info.getStatus())) { // “审核中”的数据要获取数据审核人
                        info.setAuditUserIds(flowTaskService.getTaskAuditUsers(info.getTaskId()));  // 获取数据审核人
                    }
                }
            }
        }
        return list;
    }

    /**
     * 查询审计报告信息列表
     * @param page
     * @param reportDTO
     * @return
     * @throws Exception
     */
    public IPage<ReportDTO> findReportList(Page<ReportDTO> page, ReportDTO reportDTO) throws Exception{
        String repId = "";
        if (ObjectUtil.isNotEmpty(reportDTO)) {
            if (StringUtils.isNotBlank(reportDTO.getAchiveId())) {
                CwProjectReportArchive byId = this.getById(reportDTO.getAchiveId());
                if (ObjectUtil.isNotEmpty(byId)) {
                    if (StringUtils.isNotBlank(byId.getReportId())) {
                        repId = byId.getReportId();
                    }
                }
            }
        }
        String finalRepId = repId;
        List<String> reportIds = this.list().stream().filter(item -> {
            if (StringUtils.isNotBlank(item.getReportId())) {
                if (StringUtils.isNotBlank(finalRepId)) {
                    if (item.getReportId().equals(finalRepId)) {
                        return false;
                    }
                }
                return true;
            }
            return false;
        }).map(CwProjectReportArchive::getReportId).collect(Collectors.toList()).stream().distinct().collect(Collectors.toList());
        QueryWrapper<ReportDTO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("cw_pr.del_flag","0");
        queryWrapper.orderByDesc("cw_pr.create_date");
        queryWrapper.eq("cw_pr.status", "5");
        if (CollectionUtil.isNotEmpty(reportIds)) {
            queryWrapper.notIn("cw_pr.id",reportIds);
        }
        if (ObjectUtil.isNotEmpty(reportDTO)) {
            if (StringUtils.isNotBlank(reportDTO.getProjectId())) {
                queryWrapper.eq("cw_pr.project_id",reportDTO.getProjectId());
            }
            if (StringUtils.isNotBlank(reportDTO.getReportNo())) {
                queryWrapper.like("cw_prnl.report_no",reportDTO.getReportNo());
            }
        }
        return cwProjectReportArchiveMapper.findReportList(page, queryWrapper);
    }

    /**
     * 查询报告是否已归档
     * @param reportId
     * @return
     */
    public boolean findReportUse(String reportId) {
        LambdaQueryWrapper<CwProjectReportArchive> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(CwProjectReportArchive::getReportId,reportId);
        queryWrapper.eq(CwProjectReportArchive::getDelFlag,"0");
        List<CwProjectReportArchive> list = this.list(queryWrapper);
        if (CollectionUtil.isEmpty(list)) {
            return false;
        }
        return true;
    }

    /**
     * 根据id查询项目详情
     * @param id
     * @return
     */
    public CwProjectReportArchiveDTO queryById(String id) {
        return cwProjectReportArchiveMapper.queryById(id);
    }

    /**
     * 保存项目归档信息以及其他相关信息
     * @param cwProjectReportArchiveDTO
     * @return
     * @throws Exception
     */
    public String saveForm(CwProjectReportArchiveDTO cwProjectReportArchiveDTO) throws Exception{
        UserDTO userDTO = UserUtils.getCurrentUserDTO();
        CwProjectReportArchive cwProjectReportArchive = CwProjectReportArchiveWrapper.INSTANCE.toEntity(cwProjectReportArchiveDTO);
        if (ObjectUtil.isNotEmpty(cwProjectReportArchive)) {
            if (StringUtils.isBlank(cwProjectReportArchive.getCreateBy())) {
                cwProjectReportArchive.setCreateBy(UserUtils.getCurrentUserDTO().getId());
            }
            if (StringUtils.isBlank(cwProjectReportArchive.getId())){
                String fileNumber = serialnumTplService.genSerialNum(userDTO.getCompanyDTO().getId(), CwProjectReportArchiveDTO.BIZ_CODE);
                cwProjectReportArchive.setFileNumber(fileNumber);
            }
        }
        this.saveOrUpdate(cwProjectReportArchive);
        if (ObjectUtil.isNotEmpty(cwProjectReportArchiveDTO)) {
            // 附件
            ossServiceMapper.delete(new QueryWrapper<WorkAttachment>().lambda().eq(WorkAttachment::getAttachmentId, cwProjectReportArchive.getId()));
            AtomicInteger sort = new AtomicInteger(1);
            cwProjectReportArchiveDTO.getWorkAttachmentDtoList().stream().forEach(item->{
                WorkAttachmentDto workAttachmentDto = new WorkAttachmentDto();
                workAttachmentDto.setName(item.getName());
                workAttachmentDto.setSize(item.getSize());
                workAttachmentDto.setUrl(item.getUrl());
                String fileId = ossService.saveFile(workAttachmentDto,userDTO, cwProjectReportArchive.getId(),"cw_project_report_archive",sort.get());
                sort.getAndIncrement();
                CwProjectReportArchiveFile cwProjectReportArchiveFile = new CwProjectReportArchiveFile();
                cwProjectReportArchiveFile.setWorkAttachmentId(fileId);
                cwProjectReportArchiveFile.setRemarks(item.getRemarks());
                cwProjectReportArchiveFile.setFileType(item.getFileType());
                cwProjectReportArchiveFileMapper.insert(cwProjectReportArchiveFile);
            });
        }
        return cwProjectReportArchive.getId();
    }

    /**
     * 保存项目归档信息
     * @param cwProjectReportArchiveDTO
     * @return
     * @throws Exception
     */
    public ResponseEntity save(CwProjectReportArchiveDTO cwProjectReportArchiveDTO) throws Exception{
        this.saveForm(cwProjectReportArchiveDTO);
        return ResponseEntity.ok("保存成功");
    }

    /**
     * 根据id删除项目归档信息
     * @param ids
     * @return
     */
    public ResponseEntity deleteByIds(String ids) {
        String idArray[] =ids.split(",");
        this.removeByIds (Lists.newArrayList (idArray));
        return ResponseEntity.ok ("删除成功");
    }

    /**
     * 修改状态
     * @param cwProjectReportArchiveDTO
     * @return
     */
    public String updateStatusById(CwProjectReportArchiveDTO cwProjectReportArchiveDTO) {
        CwProjectReportArchive cwProjectReportArchive = CwProjectReportArchiveWrapper.INSTANCE.toEntity(cwProjectReportArchiveDTO);
        this.update(cwProjectReportArchive, new QueryWrapper<CwProjectReportArchive>().lambda().eq(CwProjectReportArchive::getId, cwProjectReportArchive.getId()));
        return "操作成功";
    }
}
