package com.fjhx.mail.service.message.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.fjhx.common.constant.SourceConstant;
import com.fjhx.mail.config.MailServiceConfig;
import com.fjhx.mail.entity.enterprise.po.EnterpriseDomain;
import com.fjhx.mail.entity.enterprise.po.EnterpriseMailbox;
import com.fjhx.mail.entity.message.dto.DeleteBatchMailDto;
import com.fjhx.mail.entity.message.dto.DeleteMailDto;
import com.fjhx.mail.entity.message.dto.SendDto;
import com.fjhx.mail.entity.message.dto.SetSeenDto;
import com.fjhx.mail.entity.personal.po.PersonalMailbox;
import com.fjhx.mail.service.enterprise.EnterpriseDomainService;
import com.fjhx.mail.service.enterprise.EnterpriseMailboxService;
import com.fjhx.mail.service.enterprise.EnterpriseMessageService;
import com.fjhx.mail.service.message.InfoService;
import com.fjhx.mail.service.personal.PersonalMailboxService;
import com.fjhx.mail.service.personal.PersonalMessageService;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.system.service.ISysDeptService;
import com.ruoyi.system.service.ISysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

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

@Service
public class InfoServiceImpl implements InfoService {

    @Autowired
    private ISysDeptService sysDeptService;

    @Autowired
    private ISysUserService sysUserService;

    @Autowired
    private PersonalMailboxService personalMailboxService;

    @Autowired
    private EnterpriseMailboxService enterpriseMailboxService;

    @Autowired
    private EnterpriseDomainService enterpriseDomainService;

    @Autowired
    private EnterpriseMessageService enterpriseMessageService;

    @Autowired
    private PersonalMessageService personalMessageService;

    @Override
    public List<SysUser> getUserList() {

        DynamicDataSourceContextHolder.push(SourceConstant.BASE);

        Long userId = SecurityUtils.getUserId();

        List<SysDept> sysDeptList = sysDeptService.list(Wrappers.<SysDept>lambdaQuery()
                .and(q -> q.eq(SysDept::getDirectorId, userId).or().eq(SysDept::getLeaderId, userId)));

        if (sysDeptList.size() == 0) {
            return new ArrayList<>();
        }

        Set<Long> deptSet = new HashSet<>();
        List<SysDept> list = sysDeptService.list();
        Map<Long, List<SysDept>> parentDeptMap = list.stream().collect(Collectors.groupingBy(SysDept::getParentId));

        for (SysDept sysDept : sysDeptList) {
            Long deptId = sysDept.getDeptId();

            if (Objects.equals(sysDept.getDirectorId(), userId)) {
                subordinateDeptId(deptId, deptSet, parentDeptMap);
            } else {
                deptSet.add(deptId);
            }
        }

        List<SysUser> sysUserList = sysUserService.list(Wrappers.<SysUser>lambdaQuery().in(SysUser::getDeptId, deptSet));
        sysUserList.forEach(item -> item.setPassword(null));

        DynamicDataSourceContextHolder.poll();
        return sysUserList;
    }

    @Override
    public String sendMail(SendDto dto) {
        String sendMail = getUrl("sendMail", dto.getType(), dto.getMailboxId());
        return HttpUtil.post(sendMail, JSON.toJSONString(dto));
    }

    @Override
    public void deleteMail(DeleteMailDto dto) {
        if (dto.getType().equals(1)) {
            personalMessageService.removeById(dto.getId());
        } else {
            enterpriseMessageService.removeById(dto.getId());
        }
    }

    @Override
    public List<SysUser> getExistMailUserList() {
        List<SysUser> userList = getUserList();

        if (userList.size() == 0) {
            return userList;
        }

        List<Long> userIdList = userList.stream().map(SysUser::getUserId).collect(Collectors.toList());

        List<Long> existMailUserIdList = new ArrayList<>();

        List<Long> enterpriseUserId = enterpriseMailboxService.listObject(EnterpriseMailbox::getUserId,
                q -> q.in(EnterpriseMailbox::getUserId, userIdList));

        List<Long> personalUserId = personalMailboxService.listObject(PersonalMailbox::getUserId,
                q -> q.in(PersonalMailbox::getUserId, userIdList));

        existMailUserIdList.addAll(enterpriseUserId);
        existMailUserIdList.addAll(personalUserId);

        return userList.stream()
                .filter(item -> existMailUserIdList.contains(item.getUserId()))
                .collect(Collectors.toList());

    }

    @Override
    public void deleteBatchMail(DeleteBatchMailDto dto) {
        if (dto.getType().equals(1)) {
            personalMessageService.removeBatchByIds(dto.getIdList());
        } else {
            enterpriseMessageService.removeBatchByIds(dto.getIdList());
        }
    }

    @Override
    public JSONObject setSeen(SetSeenDto dto) {
        String url = getUrl("setSeen", dto.getType(), dto.getMailboxId());
        String post = HttpUtil.post(url, JSON.toJSONString(dto));
        return JSONObject.parseObject(post);
    }

    private void subordinateDeptId(Long deptId, Set<Long> deptSet, Map<Long, List<SysDept>> parentDeptMap) {
        deptSet.add(deptId);

        // 获取子部门
        List<SysDept> sysDeptList = parentDeptMap.get(deptId);
        if (ObjectUtil.isEmpty(sysDeptList)) {
            return;
        }

        for (SysDept sysDept : sysDeptList) {
            subordinateDeptId(sysDept.getDeptId(), deptSet, parentDeptMap);
        }

    }

    private String getUrl(String prefix, Integer type, Long mailboxId) {
        String urlPrefix;

        StringJoiner urlJoiner = new StringJoiner("/");
        urlJoiner.add(prefix);

        if (type == 1) {
            PersonalMailbox personalMailbox = personalMailboxService.getById(mailboxId);
            if (personalMailbox == null) {
                throw new ServiceException("未找到个人邮箱");
            }

            urlJoiner.add(personalMailbox.getSendHost());
            urlJoiner.add(personalMailbox.getMailUser());
            urlJoiner.add(personalMailbox.getMailPassword());

            if (Objects.equals(personalMailbox.getType(), 2)) {
                urlPrefix = MailServiceConfig.abroadUrlPrefix;
            } else {
                urlPrefix = MailServiceConfig.urlPrefix;
            }
        } else {
            EnterpriseMailbox enterpriseMailbox = enterpriseMailboxService.getById(mailboxId);
            if (enterpriseMailbox == null) {
                throw new ServiceException("未找到企业邮箱");
            }
            EnterpriseDomain enterpriseDomain = enterpriseDomainService.getById(enterpriseMailbox.getDomainId());
            if (enterpriseDomain == null) {
                throw new ServiceException("未找到企业邮箱配置");
            }
            urlJoiner.add(enterpriseDomain.getSendHost());
            urlJoiner.add(enterpriseMailbox.getMailUserPrefix() + "@" + enterpriseDomain.getDomainName());
            urlJoiner.add(enterpriseMailbox.getMailPassword());

            if (Objects.equals(enterpriseDomain.getType(), 2)) {
                urlPrefix = MailServiceConfig.abroadUrlPrefix;
            } else {
                urlPrefix = MailServiceConfig.urlPrefix;
            }
        }

        return urlPrefix + urlJoiner;
    }


}
