package com.ruoyi.system.service.zb.impl;

import com.github.pagehelper.PageInfo;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.bean.BeanCopyUtil;
import com.ruoyi.common.zqt.ZQTPageUtil;
import com.ruoyi.system.domain.zb.*;
import com.ruoyi.system.domain.zb.vo.*;
import com.ruoyi.system.mapper.system.SysUserMapper;
import com.ruoyi.system.mapper.zb.ZbReportRecordMapper;
import com.ruoyi.system.mapper.zb.ZbReportRelationshipMapper;
import com.ruoyi.system.mapper.zb.ZbWeekReportMapper;
import com.ruoyi.system.service.md.JbTodoService;
import com.ruoyi.system.service.zb.ReportRecordService;
import com.ruoyi.system.service.zb.WeekReportService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

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

/**
 * * Author: brenda
 * * 2025/1/10
 **/
@Service
public class ReportRecordServiceImpl implements ReportRecordService {

    @Autowired
    private ZbReportRecordMapper reportRecordMapper;
    @Autowired
    private ZbReportRelationshipMapper reportRelationshipMapper;
    @Autowired
    private SysUserMapper sysUserMapper;
    @Autowired
    private JbTodoService todoService;
    @Autowired
    private WeekReportService weekReportService;
    @Autowired
    private ZbWeekReportMapper weekReportMapper;

    @Override
    public int getReportFilledCount(String reportId, List<String> userIds) {
        ZbReportRecordExample example = new ZbReportRecordExample();
        ZbReportRecordExample.Criteria criteria = example.createCriteria();
        criteria.andReportIdEqualTo(reportId);
        if(!CollectionUtils.isEmpty(userIds)){
            criteria.andUserIdIn(userIds);
        }
        return (int)reportRecordMapper.countByExample(example);
    }

    @Override
    public ReportFinishedItem finishCondition(String reportId, String userId) {
        ReportFinishedItem item = new ReportFinishedItem();
        List<String> finishedList = new ArrayList<>();
        List<String> finishedIdList = new ArrayList<>();
        List<String> unFinishedList = new ArrayList<>();
        List<String> canSeeUserList = weekReportService.canSeeUserList(userId, reportId);
        if(CollectionUtils.isEmpty(canSeeUserList)){
            return item;
        }
        ZbReportRecordExample example = new ZbReportRecordExample();
        ZbReportRecordExample.Criteria criteria = example.createCriteria();
        criteria.andReportIdEqualTo(reportId);
        criteria.andUserIdIn(canSeeUserList);
        List<ZbReportRecord> reportRecordList = reportRecordMapper.selectByExample(example);
        if(!CollectionUtils.isEmpty(reportRecordList)){
            for(ZbReportRecord reportRecord : reportRecordList){
                SysUser sysUser = sysUserMapper.selectUserById(reportRecord.getUserId());
                if(sysUser != null){
                   finishedList.add(sysUser.getNickName());
                   finishedIdList.add(sysUser.getUserId());
                }
            }
        }
        item.setFinishedList(finishedList);
        canSeeUserList.removeAll(finishedIdList);
        if(!CollectionUtils.isEmpty(canSeeUserList)){
            for(String us: canSeeUserList){
                SysUser sysUser = sysUserMapper.selectUserById(us);
                if(sysUser != null){
                    unFinishedList.add(sysUser.getNickName());
                }
            }
        }
        item.setUnFinishedList(unFinishedList);
        return item;
    }

    @Override
    public List<ReportRecordItem> getFinishedUser(String reportId, List<String> userIds) {
        List<ReportRecordItem> list = new ArrayList<>();
        ZbReportRecordExample example = new ZbReportRecordExample();
        ZbReportRecordExample.Criteria criteria = example.createCriteria();
        criteria.andReportIdEqualTo(reportId);
        criteria.andUserIdIn(userIds);
        example.setOrderByClause("submit_time desc");
        List<ZbReportRecord> reportRecordList = reportRecordMapper.selectByExampleWithBLOBs(example);
        if(!CollectionUtils.isEmpty(reportRecordList)){
            list = convertToItem(reportRecordList);
        }
        return list;
    }

    private List<ReportRecordItem> convertToItem(List<ZbReportRecord> reportRecordList){
        List<ReportRecordItem> itemList = new ArrayList<>();
        for(ZbReportRecord reportRecord : reportRecordList){
            ReportRecordItem item = BeanCopyUtil.toBean(reportRecord, ReportRecordItem.class);
            item.setHasFilled(1);
            SysUser sysUser = sysUserMapper.selectUserById(item.getUserId());
            if(sysUser != null){
                item.setUserName(sysUser.getNickName());
                if(sysUser.getDept() != null){
                    item.setDepName(sysUser.getDept().getDeptName());
                }
                item.setSort(sysUser.getSort());
                itemList.add(item);
            }
        }
        return itemList;
    }

    @Override
    public PageInfo<ReportRecordItem> pageFinishedUser(String reportId, List<String> userIds) {
        if(CollectionUtils.isEmpty(userIds)){
            return new PageInfo<>();
        }
        ZbReportRecordExample example = new ZbReportRecordExample();
        ZbReportRecordExample.Criteria criteria = example.createCriteria();
        criteria.andReportIdEqualTo(reportId);
        criteria.andUserIdIn(userIds);
        example.setOrderByClause("submit_time desc");
        List<ZbReportRecord> reportRecordList = reportRecordMapper.selectByExampleWithBLOBs(example);
        List<ReportRecordItem> itemList = new ArrayList<>();
        if(!CollectionUtils.isEmpty(reportRecordList)){
            itemList = convertToItem(reportRecordList);
        }
        PageInfo<ReportRecordItem> pageInfo = ZQTPageUtil.build(reportRecordList, itemList);
        return pageInfo;
    }

    @Override
    @Transactional
    public void save(ZbReportRecord zbReportRecord) {
        if(StringUtils.isNotBlank(zbReportRecord.getId())){
            ZbReportRecord reportRecord = reportRecordMapper.selectByPrimaryKey(zbReportRecord.getId());
            reportRecord.setContent(zbReportRecord.getContent());
            reportRecord.setUpdateTime(new Date());
            reportRecordMapper.updateByPrimaryKeyWithBLOBs(reportRecord);
        }else{
            zbReportRecord.setId(UUID.randomUUID().toString());
            reportRecordMapper.insert(zbReportRecord);
            //完成待办
            ZbReportRelationshipExample reportRelationshipExample = new ZbReportRelationshipExample();
            ZbReportRelationshipExample.Criteria criteria = reportRelationshipExample.createCriteria();
            criteria.andReportIdEqualTo(zbReportRecord.getReportId());
            criteria.andFillFlagEqualTo((byte)1);
            criteria.andUserIdEqualTo(zbReportRecord.getUserId());
            List<ZbReportRelationship> reportRelationshipList = reportRelationshipMapper.selectByExample(reportRelationshipExample);
            if(!CollectionUtils.isEmpty(reportRelationshipList)){
                ZbReportRelationship reportRelationship = reportRelationshipList.get(0);
                if(StringUtils.isNotBlank(reportRelationship.getTodoId())){
                    todoService.workUserStatus(1, Integer.parseInt(reportRelationship.getTodoId()), 0, zbReportRecord.getUserId());
                }
            }
        }
    }

    @Override
    public List<ReportRecordWithDepItem> weekReportDetail(String reportId, String userId) {
        List<ReportRecordWithDepItem> depItemList = new ArrayList<>();
        List<String> canSeeUserList = weekReportService.canSeeUserList(userId, reportId);
        if(CollectionUtils.isEmpty(canSeeUserList)){
            return new ArrayList<>();
        }
        ZbReportRelationshipExample reportRelationshipExample = new ZbReportRelationshipExample();
        ZbReportRelationshipExample.Criteria criteria = reportRelationshipExample.createCriteria();
        criteria.andUserIdIn(canSeeUserList);
        criteria.andReportIdEqualTo(reportId);
        List<ZbReportRelationship> reportRelationshipList = reportRelationshipMapper.selectByExample(reportRelationshipExample);
        Map<String, List<ZbReportRelationship>> depMap = reportRelationshipList.stream().collect(Collectors.groupingBy(ZbReportRelationship::getDepId));
        for(Map.Entry<String, List<ZbReportRelationship>> depmap : depMap.entrySet()){
            List<ZbReportRelationship> zbReportRelationshipList = depmap.getValue();
            List<String> allUser = zbReportRelationshipList.stream().map(ZbReportRelationship::getUserId).distinct().collect(Collectors.toList());
            ReportRecordWithDepItem item = new ReportRecordWithDepItem();
            item.setDepId(zbReportRelationshipList.get(0).getDepId());
            item.setDepName(zbReportRelationshipList.get(0).getDepName());
            List<ReportRecordItem> hasFinished = getFinishedUser(reportId, allUser);
            if(!CollectionUtils.isEmpty(hasFinished)){
                List<String> hasFinishedList = hasFinished.stream().map(ReportRecordItem::getUserId).collect(Collectors.toList());
                allUser.removeAll(hasFinishedList);
                hasFinished.sort(Comparator.comparing(ReportRecordItem::getSort, Comparator.nullsLast(Integer::compare)));
            }
            List<ReportRecordItem> otherList = new ArrayList<>();
            for(String otherUserId : allUser){
                SysUser sysUser = sysUserMapper.selectUserById(otherUserId);
                if(sysUser != null){
                    ReportRecordItem item1 = new ReportRecordItem();
                    item1.setUserId(sysUser.getUserId());
                    item1.setUserName(sysUser.getNickName());
                    item1.setReportId(reportId);
                    item1.setSort(sysUser.getSort());
                    item1.setHasFilled(0);
                    item1.setSort(sysUser.getSort());
                    if(sysUser.getDept() != null){
                        item1.setDepName(sysUser.getDept().getDeptName());
                        item1.setDepId(sysUser.getDeptId().toString());
                    }
                    otherList.add(item1);
                }
            }
            if(!CollectionUtils.isEmpty(otherList)){
                otherList.sort(Comparator.comparing(ReportRecordItem::getSort, Comparator.nullsLast(Integer::compare)));
                hasFinished.addAll(otherList);
            }
            item.setRecordList(hasFinished);
            depItemList.add(item);
        }
        return depItemList;
    }

    @Override
    public ReportRecordAppDetail appReportDetail(SysUser user, String reportId) {
        ReportRecordAppDetail detail = new ReportRecordAppDetail();
        detail.setReportId(reportId);
        ZbWeekReport zbWeekReport = weekReportMapper.selectByPrimaryKey(reportId);
        Date nowDate = new Date();
        if(nowDate.after(zbWeekReport.getStartDate()) && nowDate.before(zbWeekReport.getEndDate())){
            ZbReportRelationshipExample reportRelationshipExample = new ZbReportRelationshipExample();
            ZbReportRelationshipExample.Criteria criteria = reportRelationshipExample.createCriteria();
            criteria.andReportIdEqualTo(reportId);
            criteria.andUserIdEqualTo(user.getUserId());
            criteria.andFillFlagEqualTo((byte)1);
            if(reportRelationshipMapper.countByExample(reportRelationshipExample) > 0){
                detail.setCanSubmit(true);
            }
            ZbReportRecordExample reportRecordExample = new ZbReportRecordExample();
            ZbReportRecordExample.Criteria reportC = reportRecordExample.createCriteria();
            reportC.andReportIdEqualTo(reportId);
            reportC.andUserIdEqualTo(user.getUserId());
            List<ZbReportRecord> recordList = reportRecordMapper.selectByExampleWithBLOBs(reportRecordExample);
            if(!recordList.isEmpty()){
                detail.setCanEdit(true);
                detail.setEditRecord(recordList.get(0));
            }
        }
        return detail;
    }
}
