package com.ruoyi.project.business.service.impl;

import com.ruoyi.common.enums.DelFlag;
import com.ruoyi.common.enums.ProjectStatus;
import com.ruoyi.common.enums.SerialNumberPrefix;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.*;
import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.framework.redis.RedisCache;
import com.ruoyi.project.business.domain.TcAccount;
import com.ruoyi.project.business.domain.TcProject;
import com.ruoyi.project.business.domain.TcProjectForRelated;
import com.ruoyi.project.business.domain.vo.lead.LeadRes;
import com.ruoyi.project.business.domain.vo.selectParam.ProjectParam;
import com.ruoyi.project.business.enums.MessageTypeEnum;
import com.ruoyi.project.business.mapper.TcAccountMapper;
import com.ruoyi.project.business.mapper.TcLeadMapper;
import com.ruoyi.project.business.mapper.TcProjectMapper;
import com.ruoyi.project.business.service.ITcAccountService;
import com.ruoyi.project.business.service.ITcLeadService;
import com.ruoyi.project.business.service.ITcProjectService;
import com.ruoyi.project.common.domain.Message;
import com.ruoyi.project.common.service.ISseEmitterService;
import com.ruoyi.project.system.mapper.SysUserMapper;
import org.springframework.context.MessageSource;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.temporal.ChronoField;
import java.util.*;
import java.util.stream.Collectors;

import static com.ruoyi.project.business.enums.account.AccountStatusEnum.CONVERTED_PROJECT;

/**
 * 项目管理Service业务层处理
 *
 * @author ruoyi
 * @date 2024-04-10
 */
@Service
public class TcProjectServiceImpl implements ITcProjectService
{
    @Resource
    private TcProjectMapper tcProjectMapper;

    @Resource
    private RedisCache redisCache;

    @Resource
    private ITcAccountService tcAccountService;

    @Resource
    private SysUserMapper sysUserMapper;

    @Resource
    private ISseEmitterService sseEmitterService;

    @Resource
    private ITcLeadService tcLeadService;

    @Resource
    private TcLeadMapper tcLeadMapper;
    
    @Resource
    private TcAccountMapper tcAccountMapper;
    /**
     * 查询项目管理
     *
     * @param projectId 项目管理主键
     * @return 项目管理
     */
    @Override
    public TcProject selectTcProjectByProjectId(Long projectId)
    {
        // 校验数据是否已被删除
        TcProject tcProject = tcProjectMapper.selectTcProjectByProjectId(projectId);
        if (DelFlag.YES.getCode().equals(tcProject.getDelFlag())) {
            throw new ServiceException(MessageUtils.message("business.data.deleted"));
        }
        // 查询客户关联线索
        List<LeadRes> tcLeadList = tcLeadMapper.selectLeadListByProjectId(projectId);
        tcProject.setLeadList(tcLeadList);
        tcProject.setLeadIds(tcLeadList.stream().map(LeadRes::getLeadId).collect(Collectors.toList()));
        return tcProject;
    }

    /**
     * 查询关联项目
     *
     * @return 项目集合
     */
    @Override
    public List<TcProjectForRelated> selectProjectListByLoginId()
    {
        Long loginId = SecurityUtils.getUserId();
        return tcProjectMapper.selectProjectListByLoginId(loginId);
    }

    public List<TcProjectForRelated> selectProjectListByProjectId(TcProject tcProject){
        return tcProjectMapper.selectProjectListByProjectId(tcProject);
    }

    public List<TcProjectForRelated> selectProjectListByQuery(TcProject tcProject){
        Long loginId = SecurityUtils.getUserId();
        tcProject.setLoginId(loginId);
        SpecialCharacterEscaper.escapeSpecialCharacters(tcProject, TcProject::getQuery);
        return tcProjectMapper.selectProjectListByQuery(tcProject);
    }
    /**
     * 查询需要提醒的项目
     *
     * @param cycle 项目跟踪周期
     * @return 项目集合
     */
    @Override
    public List<TcProject> selectProjectListByCycle(Long cycle) {
        return tcProjectMapper.selectProjectListByCycle(cycle);

    }

    /**
     * 查询项目管理列表
     *
     * @param tcProject 项目管理
     * @return 项目管理
     */
    @Override
    public List<TcProject> selectTcProjectList(ProjectParam tcProject)
    {
        if (StringUtils.isNotEmpty(tcProject.getProjectNo())) {
            tcProject.setProjectNo(tcProject.getProjectNo().replaceAll("%", "/%").replaceAll("_", "/_"));
        }
        if (StringUtils.isNotEmpty(tcProject.getProjectName())) {
            tcProject.setProjectName(tcProject.getProjectName().replaceAll("%", "/%").replaceAll("_", "/_"));
        }
        if (StringUtils.isNotEmpty(tcProject.getCity())) {
            tcProject.setCity(tcProject.getCity().replaceAll("%", "/%").replaceAll("_", "/_"));
        }
        if (StringUtils.isNotEmpty(tcProject.getOwnerName())) {
            tcProject.setOwnerName(tcProject.getOwnerName().replaceAll("%", "/%").replaceAll("_", "/_"));
        }
//        tcProject.setPermissionChar(SecurityUtils.getPermissionCharSea());
        tcProject.setPermissionChar(SecurityUtils.getPermissionCharIns());
        // 代理商销售经理的场合
        if (SecurityUtils.hasRole("agent_sales")) {
            tcProject.setLoginUserId(SecurityUtils.getUserId());
            tcProject.setPermission(SecurityUtils.getPermissionCharIns());
        }
        return tcProjectMapper.selectTcProjectList(tcProject);
    }

    public List<TcProject> selectTcProjectListExport(ProjectParam tcProject)
    {
        if (StringUtils.isNotEmpty(tcProject.getProjectNo())) {
            tcProject.setProjectNo(tcProject.getProjectNo().replaceAll("%", "/%").replaceAll("_", "/_"));
        }
        if (StringUtils.isNotEmpty(tcProject.getProjectName())) {
            tcProject.setProjectName(tcProject.getProjectName().replaceAll("%", "/%").replaceAll("_", "/_"));
        }
        if (StringUtils.isNotEmpty(tcProject.getCity())) {
            tcProject.setCity(tcProject.getCity().replaceAll("%", "/%").replaceAll("_", "/_"));
        }
        if (StringUtils.isNotEmpty(tcProject.getOwnerName())) {
            tcProject.setOwnerName(tcProject.getOwnerName().replaceAll("%", "/%").replaceAll("_", "/_"));
        }
//        tcProject.setPermissionChar(SecurityUtils.getPermissionCharSea());
        tcProject.setPermissionChar(SecurityUtils.getPermissionCharIns());
        // 代理商销售经理的场合
        if (SecurityUtils.hasRole("agent_sales")) {
            tcProject.setLoginUserId(SecurityUtils.getUserId());
            tcProject.setPermission(SecurityUtils.getPermissionCharIns());
        }
        return tcProjectMapper.selectTcProjectListExport(tcProject);
    }

    /**
     * 新增项目管理
     *
     * @param tcProject 项目管理
     * @return 结果
     */
    @Override
    public int insertTcProject(TcProject tcProject)
    {
        // 获取权限字段串
        String permissionChar = tcAccountService.getPermissionChar(tcProject.getAreaId());
        // 校验项目名称是否重复
        if (tcProjectMapper.selectCountByProjectName(tcProject.getProjectName(), permissionChar, null) > 0) {
            throw new ServiceException(MessageUtils.message("project.name.repeat"));
        }
        tcProject.setPermissionChar(permissionChar);
        // 业务编号采番规则，使用RedisCache.generateSerialNumber(SerialNumberPrefix.业务)方法
        String projectNo = redisCache.generateSerialNumber(SerialNumberPrefix.PRJ.getPrefix());
        tcProject.setProjectNo(projectNo);
        // 查询负责人的所有代理商
        if (tcProject.getOwnerAgent() == null) {
            tcProject.setOwnerAgent(sysUserMapper.selectDeptIdById(tcProject.getOwner()));
        }
        Long agentId = SecurityUtils.getDeptId();
        if (agentId == 0) {
            tcProject.setStatus(ProjectStatus.Third.getCode());
        } else {
            tcProject.setStatus(ProjectStatus.First.getCode());
        }
        Date now = DateUtils.getNowDate();
        tcProject.setCreateBy(SecurityUtils.getUserId().toString());
        tcProject.setCreateTime(now);
        tcProject.setUpdateTime(now);
        int result = tcProjectMapper.insertTcProject(tcProject);
//        if (tcProject.getLeadId() != null) {
//            tcLeadService.convertProject(tcProject.getLeadId(), tcProject.getProjectId());
//        }
       
        
        // 跟新客户状态
        if (tcProject.getAccountId() != null) {
            TcAccount tcAccount = tcAccountService.selectTcAccountByAccountId(tcProject.getAccountId());
            tcAccount.setStatus(CONVERTED_PROJECT.getCode());
            // tcAccountService.updateTcAccount(tcAccount);
            tcAccountMapper.updateTcAccount(tcAccount);
        }
        // 线索信息绑定项目
        if (tcProject.getLeadIds() != null && !tcProject.getLeadIds().isEmpty()) {
            for (Long leadId : tcProject.getLeadIds()) {
                tcLeadService.convertProject(leadId, tcProject.getProjectId());
            }
        }
        return result;
    }

    /**
     * 修改项目管理
     *
     * @param tcProject 项目管理
     * @return 结果
     */
    @Override
    public int updateTcProject(TcProject tcProject)
    {
        // 获取权限字段串
        String permissionChar = tcAccountService.getPermissionChar(tcProject.getAreaId());
        // 校验项目名称是否重复
        if (tcProjectMapper.selectCountByProjectName(tcProject.getProjectName(), permissionChar, tcProject.getProjectId()) > 0) {
            throw new ServiceException(MessageUtils.message("project.name.repeat"));
        }
        // 判断是否需要推送消息
        boolean flag = false;
        List<Long> oldIds = new ArrayList<>();
        List<Long> newIds = new ArrayList<>();
        TcProject oldProject = tcProjectMapper.selectTcProjectByProjectId(tcProject.getProjectId());
        if (!Objects.equals(oldProject.getOwner(), tcProject.getOwner())) {
            flag = true;
            oldIds.add(oldProject.getOwner());
            newIds.add(tcProject.getOwner());
        }
        tcProject.setPermissionChar(permissionChar);
        // 查询负责人的所有代理商
        if (tcProject.getOwnerAgent() == null) {
            tcProject.setOwnerAgent(sysUserMapper.selectDeptIdById(tcProject.getOwner()));
        }
        // 如果处于审批不通过状态：02，更新后转为待审批状态：01
        if (ProjectStatus.Second.getCode().equals(tcProject.getStatus())) {
            tcProject.setStatus(ProjectStatus.First.getCode());
        }
        tcProject.setUpdateBy(SecurityUtils.getUserId().toString());
        tcProject.setUpdateTime(DateUtils.getNowDate());
        // 不考虑非空全部修改
        int result = tcProjectMapper.updateTcProjectAll(tcProject);
        if (flag) {
            Object[] args = new String[1];
            args[0] = tcProject.getProjectName();
            MessageSource oldSource = SpringUtils.getBean(MessageSource.class);
            String messageContentOld = oldSource.getMessage("project.owner.message.old", args, new Locale("zh","CN"));
            String messageContentUSOld = oldSource.getMessage("project.owner.message.old", args, new Locale("en","US"));
            String messageContentRUOld = oldSource.getMessage("project.owner.message.old", args, new Locale("ru","RU"));
            String messageContentESOld = oldSource.getMessage("project.owner.message.old", args, new Locale("es","ES"));
            Message messageForOld = new Message();
            messageForOld.setMessageType(MessageTypeEnum.PROJECT.getValue());
            messageForOld.setMessageContent(messageContentOld);
            messageForOld.setMessageContentUS(messageContentUSOld);
            messageForOld.setMessageContentRU(messageContentRUOld);
            messageForOld.setMessageContentES(messageContentESOld);

            MessageSource newSource = SpringUtils.getBean(MessageSource.class);
            String messageContentNew = newSource.getMessage("project.owner.message.new", args, new Locale("zh","CN"));
            String messageContentUSNew = newSource.getMessage("project.owner.message.new", args, new Locale("en","US"));
            String messageContentRUNew = newSource.getMessage("project.owner.message.new", args, new Locale("ru","RU"));
            String messageContentESNew = newSource.getMessage("project.owner.message.new", args, new Locale("es","ES"));
            Message messageForNew = new Message();
            messageForNew.setMessageType(MessageTypeEnum.PROJECT.getValue());
            messageForNew.setMessageContent(messageContentNew);
            messageForNew.setMessageContentUS(messageContentUSNew);
            messageForNew.setMessageContentRU(messageContentRUNew);
            messageForNew.setMessageContentES(messageContentESNew);
            sseEmitterService.sendSaveMessage(newIds, messageForNew);
            sseEmitterService.sendSaveMessage(oldIds, messageForOld);
        }
        return result;
    }

    /**
     * 批量删除项目管理
     *
     * @param projectIds 需要删除的项目管理主键
     * @return 结果
     */
    @Override
    public int deleteTcProjectByProjectIds(Long[] projectIds)
    {
        return tcProjectMapper.deleteTcProjectByProjectIds(projectIds);
    }

    /**
     * 删除项目管理信息
     *
     * @param projectId 项目管理主键
     * @return 结果
     */
    @Override
    public int deleteTcProjectByProjectId(Long projectId)
    {
        return tcProjectMapper.deleteTcProjectByProjectId(projectId);
    }

    /**
     * 查询客户关联项目
     *
     * @param tcProject 项目
     * @return 结果
     */
    @Override
    public List<TcProjectForRelated> selectProjectListByAccount(TcProject tcProject) {
        return tcProjectMapper.selectProjectListByAccount(tcProject);
    }

    /**
     * 设为标杆项目
     *
     * @param tcProject 项目
     * @return 结果
     */
    @Override
    public int setModel(TcProject tcProject) {
        tcProject.setUpdateBy(SecurityUtils.getUserId().toString());
        tcProject.setUpdateTime(DateUtils.getNowDate());
        return tcProjectMapper.updateTcProject(tcProject);
    }

    /**
     * 延期/丢单
     *
     * @param tcProject 项目
     * @return 结果
     */
    @Override
    public int delayLost(TcProject tcProject) {
        if ("09".equals(tcProject.getStatus())) {
            tcProject.setStatus(ProjectStatus.Ninth.getCode());
        } else if ("10".equals(tcProject.getStatus())) {
            tcProject.setStatus(ProjectStatus.Tenth.getCode());
        }
        tcProject.setUpdateBy(SecurityUtils.getUserId().toString());
        tcProject.setUpdateTime(DateUtils.getNowDate());
        return tcProjectMapper.updateTcProject(tcProject);
    }

    /**
     * 审批
     *
     * @param tcProject 项目
     * @return 结果
     */
    @Override
    public int approve(TcProject tcProject) {
        if ("02".equals(tcProject.getStatus())) {
            tcProject.setStatus(ProjectStatus.Second.getCode());
        } else if ("03".equals(tcProject.getStatus())) {
            tcProject.setStatus(ProjectStatus.Third.getCode());
        }
        // 审批人
        tcProject.setAuditPerson(SecurityUtils.getUserId());
        tcProject.setUpdateBy(SecurityUtils.getUserId().toString());
        tcProject.setUpdateTime(DateUtils.getNowDate());
        return tcProjectMapper.updateTcProject(tcProject);
    }

    @Override
    public List<TcProject> getUnFollowedList(String unfollowedMode) {
        // unfollowedMode: 1-最近一周；2-最近一个月；3-最近三个月
        LocalDateTime startDate;
        LocalDateTime endDate = LocalDateTime.of(LocalDate.now(), LocalTime.MAX);

        switch (unfollowedMode) {
            case "1":
                startDate = LocalDate.now().minusDays(7).atStartOfDay();
                break;
            case "2":
                startDate = LocalDate.now().minusMonths(1).atStartOfDay();
                break;
            case "3":
                startDate = LocalDate.now().minusMonths(3).atStartOfDay();
                break;
            default:
                throw new IllegalArgumentException("unfollowedMode");
        }
        return tcProjectMapper.selectUnFollowedList(startDate, endDate, SecurityUtils.getPermissionCharIns());
    }

    @Override
    public int changeOwner(TcProject tcProject) {
        // 负责人与代理商脱钩
        // tcProject.setOwnerAgent(sysUserMapper.selectDeptIdById(tcProject.getOwner()));
        tcProject.setUpdateBy(SecurityUtils.getUserId().toString());
        tcProject.setUpdateTime(DateUtils.getNowDate());
        return tcProjectMapper.updateTcProject(tcProject);
    }

    @Override
    public List<TcProject> selectTcProjectListApp() {
        return tcProjectMapper.selectTcProjectListApp(SecurityUtils.getPermissionCharIns(), SecurityUtils.getUserId());
    }

    @Override
    public Integer existProjectByAgentIds(Long[] agentIds) {
        if (agentIds == null || agentIds.length == 0) {
           return null;
        }
        return tcProjectMapper.existProjectByAgentIds(agentIds);
    }
}
