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

import com.github.pagehelper.PageInfo;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.bean.BeanCopyUtil;
import com.ruoyi.common.utils.uuid.UUID;
import com.ruoyi.common.zqt.ZQTPageUtil;
import com.ruoyi.system.domain.md.dto.JbReceiver;
import com.ruoyi.system.domain.md.dto.JbWorkBean;
import com.ruoyi.system.domain.other.BsCommon;
import com.ruoyi.system.domain.other.BsCommonExample;
import com.ruoyi.system.domain.zb.*;
import com.ruoyi.system.domain.zb.enums.WeekReportTypeEnum;
import com.ruoyi.system.domain.zb.request.WeekReportSaveRequest;
import com.ruoyi.system.domain.zb.vo.*;
import com.ruoyi.system.mapper.system.SysUserMapper;
import com.ruoyi.system.mapper.zb.*;
import com.ruoyi.system.service.md.JbTodoService;
import com.ruoyi.system.service.other.BsCommonService;
import com.ruoyi.system.service.zb.ReportRecordService;
import com.ruoyi.system.service.zb.WeekReportService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;


/**
 * * Author: brenda
 * * 2025/1/10
 **/
@Service
public class WeekReportServiceImpl implements WeekReportService {

    @Autowired
    private ZbWeekReportMapper weekReportMapper;
    @Autowired
    private ZbReportRelationshipMapper reportRelationshipMapper;
    @Autowired
    private ReportRecordService reportRecordService;
    @Autowired
    private ZbAutoRecordMapper autoRecordMapper;
    @Autowired
    private SysUserMapper sysUserMapper;
    @Autowired
    private WeekReportExtMapper weekReportExtMapper;
    @Autowired
    private ZbReportRecordMapper zbReportRecordMapper;
    @Autowired
    private BsCommonService bsCommonService;
    @Value("${app.msg.pcUrl}")
    private String gridPcUrl;
    @Value("${app.msg.appUrl}")
    private String gridAppUrl;
    @Resource
    private JbTodoService todoService;

    @Override
    @Transactional
    public String save(WeekReportSaveRequest request) {
        String id = UUID.randomUUID().toString();
        request.setId(id);
        request.setValid((byte)1);
        if(request.getAutoFlag() == 1){
            request.setType(WeekReportTypeEnum.AUTO.getCode());
        }else{
            request.setType(WeekReportTypeEnum.MANUAL.getCode());
        }
        if(StringUtils.isBlank(request.getDictId())){
            throw new ServiceException("未选择适配人员！");
        }
        //配置要填写的人员
        setDictUser(request.getDictId(), id, request.getLeaderFillFlag() == 1, null);

        ZbReportRelationshipExample example = new ZbReportRelationshipExample();
        ZbReportRelationshipExample.Criteria criteria = example.createCriteria();
        criteria.andReportIdEqualTo(id);
        criteria.andFillFlagEqualTo((byte)1);
        List<ZbReportRelationship> relationshipList = reportRelationshipMapper.selectByExample(example);
        int count = relationshipList.size();
        request.setFillCount(count);
        if(request.getPublishFlag() == 0){
            //草稿
            request.setStatus(0);
        }else{
            //发布
            request.setStatus(1);
            //自动发布的逻辑
            if(request.getAutoFlag() == 1 && !request.isScheduled()){
                ZbAutoRecord zbAutoRecord = new ZbAutoRecord();
                zbAutoRecord.setCreateTime(new Date());
                zbAutoRecord.setLastReportId(id);
                zbAutoRecord.setReportId(id);
                zbAutoRecord.setLastWeek(request.getWeek());
                zbAutoRecord.setYear(request.getYear());
                zbAutoRecord.setValid((byte)1);
                autoRecordMapper.insert(zbAutoRecord);
            }
            if(!CollectionUtils.isEmpty(relationshipList)){
                sendTodo(relationshipList, id, request.getTitle(), request.getCreateUser());
            }
        }
        weekReportMapper.insert(request);
        return id;
    }

    private void setDictUser(String dictId, String reportId, boolean leaderNeedFill, String bsCommonParentId){
        BsCommon bsCommon = bsCommonService.selectByPrimaryKey(dictId);
        if(bsCommon == null){
            throw new ServiceException("组织架构不存在！");
        }
        BsCommonExample commonExample = new BsCommonExample();
        BsCommonExample.Criteria commonC = commonExample.createCriteria();
        commonC.andIsValidEqualTo("1");
        commonC.andParentIdEqualTo(bsCommon.getId());
        commonC.andCodeNotEqualTo("week_report_zhidu");
        List<BsCommon> bsCommonList = bsCommonService.selectByExample(commonExample);
        if(CollectionUtils.isEmpty(bsCommonList)){
            return;
        }
        for(BsCommon common : bsCommonList){
            if(StringUtils.isBlank(common.getYlzd1())){
                continue;
            }
            boolean leaderFlag = common.getCode().contains("leader");
            String[] userIds = common.getYlzd1().split(",");
            for(String user : userIds){
                SysUser sysUser = sysUserMapper.selectUserById(user);
                if(sysUser != null){
                    ZbReportRelationship reportRelationship = new ZbReportRelationship();
                    reportRelationship.setId(UUID.randomUUID().toString());
                    reportRelationship.setUserId(sysUser.getUserId());
                    reportRelationship.setUserName(sysUser.getNickName());
                    if(sysUser.getDept() != null){
                        reportRelationship.setDepId(sysUser.getDeptId().toString());
                        reportRelationship.setDepName(sysUser.getDept().getDeptName());
                    }
                    reportRelationship.setReportId(reportId);
                    if(StringUtils.isNotBlank(bsCommonParentId)){
                        reportRelationship.setBsCommonParentId(bsCommonParentId);
                    }
                    reportRelationship.setBsCommonId(common.getId());
                    reportRelationship.setFillFlag((byte)1);
                    if(leaderFlag){
                        if(!leaderNeedFill){
                            reportRelationship.setFillFlag((byte)0);
                        }
                    }
                    reportRelationship.setLeaderFlag(leaderFlag?(byte)1:(byte)0);
                    reportRelationshipMapper.insert(reportRelationship);
                }
            }
            setDictUser(common.getId(), reportId, leaderNeedFill, common.getId());
        }
    }

    private void sendTodo(List<ZbReportRelationship> relationshipList, String id, String title, String creator){
        List<JbReceiver> receiverList = new ArrayList<>();
        for(ZbReportRelationship reportRelationship : relationshipList){
            JbReceiver receiver = new JbReceiver();
            receiver.setUid(reportRelationship.getUserId());
            receiverList.add(receiver);
        }
        //发待办
        JbWorkBean daiBan = new JbWorkBean();
        daiBan.setName(title);//待办标题
        daiBan.setLevel(1);// 级别
        daiBan.setCreatedby(creator);//发送人用户ID
        daiBan.setReceiver(receiverList);
        daiBan.setContent(title);//待办内容"
        String pcUri =gridPcUrl+"/weeklydetail?id="+id;
        daiBan.setPcurl(pcUri);
        Integer todoId = todoService.save(daiBan);
        for(ZbReportRelationship reportRelationship : relationshipList){
            reportRelationship.setTodoId(todoId.toString());
            reportRelationshipMapper.updateByPrimaryKey(reportRelationship);
        }
    }

    @Override
    @Transactional
    public void update(WeekReportSaveRequest request) {
        ZbWeekReport weekReport = weekReportMapper.selectByPrimaryKey(request.getId());
        if(weekReport == null){
            throw new ServiceException("对象不存在");
        }
        if(weekReport.getStatus() == 1){
            throw new ServiceException("只有草稿状态的可以编辑！");
        }
        weekReport.setWeek(request.getWeek());
        weekReport.setYear(request.getYear());
        weekReport.setEndDate(request.getEndDate());
        weekReport.setLeaderFillFlag(request.getLeaderFillFlag());
        if(request.getAutoFlag() == 1){
            weekReport.setType(WeekReportTypeEnum.AUTO.getCode());
        }else{
            weekReport.setType(WeekReportTypeEnum.MANUAL.getCode());
        }
        weekReport.setShowFlag(request.getShowFlag());
        weekReport.setTitle(request.getTitle());
        weekReport.setValid((byte)1);
        if(request.getPublishFlag() == 0){
            //草稿
            weekReport.setStatus(0);
        }else{
            //发布
            weekReport.setStatus(1);
            if(request.getAutoFlag() == 1){
                //将之前的自动发布记录停止,同一时间只有一个周报在发布中
                cancelAuto();
                ZbAutoRecord zbAutoRecord = new ZbAutoRecord();
                zbAutoRecord.setCreateTime(new Date());
                zbAutoRecord.setLastReportId(request.getId());
                zbAutoRecord.setReportId(request.getId());
                zbAutoRecord.setLastWeek(request.getWeek());
                zbAutoRecord.setYear(request.getYear());
                zbAutoRecord.setValid((byte)1);
                autoRecordMapper.insert(zbAutoRecord);
            }
        }
        ZbReportRelationshipExample example = new ZbReportRelationshipExample();
        ZbReportRelationshipExample.Criteria criteria = example.createCriteria();
        criteria.andReportIdEqualTo(request.getId());
        reportRelationshipMapper.deleteByExample(example);
        if(StringUtils.isBlank(request.getDictId())){
            throw new ServiceException("未选择适配人员！");
        }
        //配置要填写的人员
        setDictUser(request.getDictId(), request.getId(), request.getLeaderFillFlag() == 1, null);

        ZbReportRelationshipExample reportRelationshipExample = new ZbReportRelationshipExample();
        ZbReportRelationshipExample.Criteria relationshipExampleCriteria = reportRelationshipExample.createCriteria();
        relationshipExampleCriteria.andReportIdEqualTo(request.getId());
        relationshipExampleCriteria.andFillFlagEqualTo((byte)1);
        List<ZbReportRelationship> relationshipList = reportRelationshipMapper.selectByExample(reportRelationshipExample);
        int count = relationshipList.size();
        if(!CollectionUtils.isEmpty(relationshipList)){
            sendTodo(relationshipList, request.getId(), request.getTitle(), weekReport.getCreateUser());
        }
        weekReport.setFillCount(count);
        weekReportMapper.updateByPrimaryKey(weekReport);
    }

    @Override
    public PageInfo<WeekReportPageItem> page(String title, String year, String week, String userId) {
        ZbWeekReportExample example = new ZbWeekReportExample();
        ZbWeekReportExample.Criteria criteria = example.createCriteria();
        if(StringUtils.isNotBlank(title)){
            criteria.andTitleLike("%"+title+"%");
        }
        if(StringUtils.isNotBlank(year)){
            criteria.andYearEqualTo(year);
        }
        if(StringUtils.isNotBlank(week)){
            criteria.andWeekEqualTo(week);
        }
        criteria.andValidEqualTo((byte) 1);
        example.setOrderByClause("create_time desc");
        List<ZbWeekReport> reportList = weekReportMapper.selectByExample(example);
        List<String> configUserIds = new ArrayList<>();
        //只读负责人只看自己负责的哪些人
        if(isManager(userId)){
            List<BsCommon> managerCommonList = bsCommonService.getWgdxList("week_report_zhidu");
            if(!CollectionUtils.isEmpty(managerCommonList)){
                BsCommon managerCommon = managerCommonList.get(0);
                configUserIds = Arrays.asList(managerCommon.getYlzd1().split(","));
            }
        }
        List<WeekReportPageItem> list = new ArrayList<>();
        if(!CollectionUtils.isEmpty(reportList)){
            for(ZbWeekReport report : reportList){
                WeekReportPageItem item = BeanCopyUtil.toBean(report, WeekReportPageItem.class);
                if(!CollectionUtils.isEmpty(configUserIds)){
                    item.setFillCount(configUserIds.size());
                }
                item.setFinishCount(reportRecordService.getReportFilledCount(report.getId(), configUserIds));
                WeekReportTypeEnum typeEnum = WeekReportTypeEnum.getByCode(report.getType());
                item.setTypeValue(typeEnum == null?"":typeEnum.getValue());
                list.add(item);
            }
        }
        PageInfo<WeekReportPageItem> pageInfo = ZQTPageUtil.build(reportList, list);
        return pageInfo;
    }

    @Override
    public WeekReportDetail simpleDetail(String reportId) {
        ZbWeekReport weekReport = weekReportMapper.selectByPrimaryKey(reportId);
        if(weekReport == null){
            throw new ServiceException("对象不存在");
        }
        WeekReportDetail detail = BeanCopyUtil.toBean(weekReport, WeekReportDetail.class);
        if(weekReport.getType().equals(WeekReportTypeEnum.AUTO.getCode())){
            detail.setAutoFlag(1);
        } else{
            detail.setAutoFlag(0);
        }
        if(StringUtils.isNotBlank(weekReport.getDictId())){
            BsCommon bsCommon = bsCommonService.selectByPrimaryKey(weekReport.getDictId());
            detail.setDictName(bsCommon == null?"":bsCommon.getName());
        }
        return detail;
    }

    @Override
    public WeekReportWithUserDetail reportWithUserDetail(String reportId, String userId) {
        ZbWeekReport weekReport = weekReportMapper.selectByPrimaryKey(reportId);
        if(weekReport == null){
            throw new ServiceException("对象不存在");
        }
        WeekReportWithUserDetail detail = BeanCopyUtil.toBean(weekReport, WeekReportWithUserDetail.class);
        WeekReportTypeEnum typeEnum = WeekReportTypeEnum.getByCode(detail.getType());
        detail.setTypeValue(typeEnum == null?"":typeEnum.getValue());
        //只读负责人只看自己负责的哪些人
        List<String> configUserIds = new ArrayList<>();
        if(isManager(userId)){
            List<BsCommon> managerCommonList = bsCommonService.getWgdxList("week_report_zhidu");
            if(!CollectionUtils.isEmpty(managerCommonList)){
                BsCommon managerCommon = managerCommonList.get(0);
                configUserIds = Arrays.asList(managerCommon.getYlzd1().split(","));
                detail.setFillCount(configUserIds.size());
            }
        }
        detail.setFinishedCount(reportRecordService.getReportFilledCount(reportId, configUserIds));
        return detail;
    }

    @Override
    public PageInfo<WeekReportPageItem> pageForApp(String userId, String title, int pageNum, int pageSize) {
        List<ZbWeekReport> weekReportList;
        if(isLeader(userId) || isManager(userId)){
            weekReportList = weekReportExtMapper.listByParamForApp(null, title);
        }else{
            weekReportList = weekReportExtMapper.listByParamForApp(userId, title);
        }
        List<WeekReportPageItem> reportPageItems = new ArrayList<>();
        if(!CollectionUtils.isEmpty(weekReportList)){
            for(ZbWeekReport report : weekReportList){
                WeekReportPageItem item = BeanCopyUtil.toBean(report, WeekReportPageItem.class);
                ZbReportRelationshipExample reportRelationshipExample = new ZbReportRelationshipExample();
                ZbReportRelationshipExample.Criteria criteria = reportRelationshipExample.createCriteria();
                criteria.andReportIdEqualTo(report.getId());
                criteria.andUserIdEqualTo(userId);
                criteria.andFillFlagEqualTo((byte)1);
                List<ZbReportRelationship> relationshipList = reportRelationshipMapper.selectByExample(reportRelationshipExample);
                if(!CollectionUtils.isEmpty(relationshipList)){
                    item.setHasFilled(0);
                    ZbReportRecordExample reportRecordExample = new ZbReportRecordExample();
                    ZbReportRecordExample.Criteria criteria1 = reportRecordExample.createCriteria();
                    criteria1.andReportIdEqualTo(report.getId());
                    criteria1.andUserIdEqualTo(userId);
                    if(zbReportRecordMapper.countByExample(reportRecordExample) > 0){
                        item.setHasFilled(1);
                    }
                }
                reportPageItems.add(item);
            }
        }
        PageInfo<WeekReportPageItem> pageInfo = ZQTPageUtil.build(weekReportList, reportPageItems);
        return pageInfo;
    }

    @Override
    public void cancelAuto() {
        ZbAutoRecordExample autoRecordExample = new ZbAutoRecordExample();
        ZbAutoRecordExample.Criteria criteria = autoRecordExample.createCriteria();
        criteria.andValidEqualTo((byte)1);
        List<ZbAutoRecord> recordList = autoRecordMapper.selectByExample(autoRecordExample);
        if(!CollectionUtils.isEmpty(recordList)){
            recordList.forEach( e ->{
                e.setValid((byte)0);
                autoRecordMapper.updateByPrimaryKeySelective(e);
            });
        }
    }

    @Override
    public boolean isLeader(String userId) {
        BsCommonExample example = new BsCommonExample();
        BsCommonExample.Criteria criteria = example.createCriteria();
        criteria.andIsValidEqualTo("1");
        criteria.andCodeLike("%leader%");
        List<BsCommon> bsCommonList = bsCommonService.selectByExample(example);
        if(!CollectionUtils.isEmpty(bsCommonList)){
            BsCommon bsCommon = bsCommonList.get(0);
            if(StringUtils.isNotBlank(bsCommon.getYlzd1())){
                List<String> userIds = Arrays.asList(bsCommon.getYlzd1().split(","));
                return userIds.contains(userId);
            }
        }
        return false;
    }

    @Override
    public List<String> canSeeUserList(String userId, String reportId) {
        if(userId.equals("1") || isLeader(userId)){
            //领导看全部
            ZbReportRelationshipExample example = new ZbReportRelationshipExample();
            ZbReportRelationshipExample.Criteria criteria = example.createCriteria();
            criteria.andFillFlagEqualTo((byte)1);
            criteria.andReportIdEqualTo(reportId);
            List<ZbReportRelationship> reportRelationshipList = reportRelationshipMapper.selectByExample(example);
            if(CollectionUtils.isEmpty(reportRelationshipList)){
                return null;
            }
            return reportRelationshipList.stream().map(ZbReportRelationship::getUserId).distinct().collect(Collectors.toList());
        }
        //只读负责人只读自己下面的child
        if(isManager(userId)){
            List<BsCommon> managerCommonList = bsCommonService.getWgdxList("week_report_zhidu");
            if(!CollectionUtils.isEmpty(managerCommonList)){
                BsCommon managerCommon = managerCommonList.get(0);
                return Arrays.asList(managerCommon.getYlzd1().split(","));
            }
        }
        ZbReportRelationshipExample example = new ZbReportRelationshipExample();
        ZbReportRelationshipExample.Criteria criteria = example.createCriteria();
        criteria.andUserIdEqualTo(userId);
        criteria.andFillFlagEqualTo((byte)1);
        criteria.andReportIdEqualTo(reportId);
        List<ZbReportRelationship> reportRelationshipList = reportRelationshipMapper.selectByExample(example);
        if(CollectionUtils.isEmpty(reportRelationshipList)){
            return null;
        }
        List<String> userIds = new ArrayList<>();
        for(ZbReportRelationship reportRelationship : reportRelationshipList){
            userIds.add(reportRelationship.getUserId());
            setChildUser(reportRelationship, reportId, userIds);
        }
        return userIds.stream().distinct().collect(Collectors.toList());
    }

    private void setChildUser(ZbReportRelationship reportRelationship, String reportId, List<String> userIds){
        ZbReportRelationshipExample reportRelationshipExample = new ZbReportRelationshipExample();
        ZbReportRelationshipExample.Criteria relationshipExampleCriteria = reportRelationshipExample.createCriteria();
        relationshipExampleCriteria.andBsCommonParentIdEqualTo(reportRelationship.getBsCommonId());
        relationshipExampleCriteria.andReportIdEqualTo(reportId);
        relationshipExampleCriteria.andFillFlagEqualTo((byte)1);
        List<ZbReportRelationship> relationshipList = reportRelationshipMapper.selectByExample(reportRelationshipExample);
        if(!CollectionUtils.isEmpty(relationshipList)){
            for(ZbReportRelationship zbReportRelationship : relationshipList){
                userIds.add(zbReportRelationship.getUserId());
                setChildUser(zbReportRelationship, reportId, userIds);
            }
        }
    }

    @Override
    public boolean isManager(String userId) {
        BsCommonExample example = new BsCommonExample();
        BsCommonExample.Criteria criteria = example.createCriteria();
        criteria.andIsValidEqualTo("1");
        criteria.andCodeEqualTo("week_report_zhidu");
        List<BsCommon> bsCommonList = bsCommonService.selectByExample(example);
        if(!CollectionUtils.isEmpty(bsCommonList)){
            BsCommon bsCommon = bsCommonList.get(0);
            if(StringUtils.isNotBlank(bsCommon.getYlzd1())){
                List<String> userIds = Arrays.asList(bsCommon.getYlzd1().split(","));
                return userIds.contains(userId);
            }
        }
        return false;
    }
}
