package com.ruoyi.oa.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.dm.model.v20151123.SingleSendMailRequest;
import com.aliyuncs.dm.model.v20151123.SingleSendMailResponse;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.profile.DefaultProfile;
import com.lark.oapi.Client;
import com.lark.oapi.service.mail.v1.model.MailAddress;
import com.lark.oapi.service.mail.v1.model.Message;
import com.lark.oapi.service.mail.v1.model.SendUserMailboxMessageReq;
import com.lark.oapi.service.mail.v1.model.SendUserMailboxMessageResp;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.domain.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import com.ruoyi.oa.domain.bo.OaEmailAccountBo;
import com.ruoyi.oa.domain.vo.OaEmailAccountVo;
import com.ruoyi.oa.domain.OaEmailAccount;
import com.ruoyi.oa.mapper.OaEmailAccountMapper;
import com.ruoyi.oa.service.IOaEmailAccountService;
import com.ruoyi.oa.domain.request.EmailSendRequest;
import com.ruoyi.oa.utils.EmailUtil;
import com.ruoyi.oa.config.DynamicMailConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.client.RestTemplate;
import com.ruoyi.oa.mapper.OaFurnitureTableMapper;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Collection;

/**
 * 发件人邮箱账号管理Service业务层处理
 *
 * @author Joshi
 * @date 2025-07-10
 */
@RequiredArgsConstructor
@Service
public class OaEmailAccountServiceImpl implements IOaEmailAccountService {

    private final OaEmailAccountMapper baseMapper;
    
    @Autowired
    private EmailUtil emailUtil;

    @Autowired
    private OaFurnitureTableMapper oaFurnitureTableMapper;

    @Autowired
    private DynamicMailConfig dynamicMailConfig;

    /**
     * 查询发件人邮箱账号管理
     */
    @Override
    public OaEmailAccountVo queryById(Long emailId){
        return baseMapper.selectVoById(emailId);
    }

    /**
     * 查询发件人邮箱账号管理列表
     */
    @Override
    public TableDataInfo<OaEmailAccountVo> queryPageList(OaEmailAccountBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<OaEmailAccount> lqw = buildQueryWrapper(bo);
        Page<OaEmailAccountVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询发件人邮箱账号管理列表
     */
    @Override
    public List<OaEmailAccountVo> queryList(OaEmailAccountBo bo) {
        LambdaQueryWrapper<OaEmailAccount> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<OaEmailAccount> buildQueryWrapper(OaEmailAccountBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<OaEmailAccount> lqw = Wrappers.lambdaQuery();
        lqw.eq(StringUtils.isNotBlank(bo.getEmail()), OaEmailAccount::getEmail, bo.getEmail());
        lqw.eq(StringUtils.isNotBlank(bo.getPassword()), OaEmailAccount::getPassword, bo.getPassword());
        lqw.eq(StringUtils.isNotBlank(bo.getSmtpHost()), OaEmailAccount::getSmtpHost, bo.getSmtpHost());
        lqw.eq(bo.getSmtpPort() != null, OaEmailAccount::getSmtpPort, bo.getSmtpPort());
        lqw.eq(StringUtils.isNotBlank(bo.getAccessKey()), OaEmailAccount::getAccessKey, bo.getAccessKey());
        lqw.eq(StringUtils.isNotBlank(bo.getSecretKey()), OaEmailAccount::getSecretKey, bo.getSecretKey());
        lqw.eq(bo.getType() != null, OaEmailAccount::getType, bo.getType());
        return lqw;
    }

    /**
     * 新增发件人邮箱账号管理
     */
    @Override
    public Boolean insertByBo(OaEmailAccountBo bo) {
        OaEmailAccount add = BeanUtil.toBean(bo, OaEmailAccount.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setEmailId(add.getEmailId());
        }
        return flag;
    }

    /**
     * 修改发件人邮箱账号管理
     */
    @Override
    public Boolean updateByBo(OaEmailAccountBo bo) {
        OaEmailAccount update = BeanUtil.toBean(bo, OaEmailAccount.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(OaEmailAccount entity){
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除发件人邮箱账号管理
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    @Override
    public String sendBatchEmail(EmailSendRequest request) {
        OaEmailAccount account = baseMapper.selectById(request.getEmailAccountId());
        if (account == null) {
            return "发件人邮箱账号不存在";
        }
        
        // 输出SMTP服务器信息
        String smtpHost = dynamicMailConfig.getSmtpHostByEmail(account.getEmail(), account.getSmtpHost());
        System.out.println("使用邮箱: " + account.getEmail() + ", SMTP服务器: " + smtpHost);
        
        List<String> emailList = oaFurnitureTableMapper.selectEmailsByFurnitureIds(request.getFurnitureIds());
        int type = account.getType() == null ? -1 : account.getType().intValue();
        int success = 0, fail = 0;
        StringBuilder failList = new StringBuilder();
        // 处理附件：如果是http/https链接，先下载
        List<File> attachmentFiles = new ArrayList<>();
        try {
            if (request.getAttachmentPaths() != null && !request.getAttachmentPaths().isEmpty()) {
                for (String path : request.getAttachmentPaths()) {
                    if (path.startsWith("http://") || path.startsWith("https://")) {
                        attachmentFiles.add(EmailUtil.downloadUrlToTempFile(path));
                    } else {
                        attachmentFiles.add(new File(path));
                    }
                }
            }
            if (type == 0 || type == 1) {
                for (String to : emailList) {
                    try {
                        boolean isHtml = request.getContent() != null && 
                                (request.getContent().contains("<html") || 
                                 request.getContent().contains("<div") || 
                                 request.getContent().contains("<p>"));
                        boolean hasAttachments = !attachmentFiles.isEmpty();
                        boolean hasInlineImages = request.getInlineImagePaths() != null && !request.getInlineImagePaths().isEmpty();
                        if (hasAttachments && hasInlineImages) {
                            if (isHtml) {
                                String processedContent = emailUtil.processHtmlWithInlineImages(request.getContent(), request.getInlineImagePaths());
                                emailUtil.sendHtmlMailWithAttachmentsAndDynamicConfig(account, to, request.getSubject(), processedContent, toPathList(attachmentFiles));
                            } else {
                                emailUtil.sendMailWithAttachmentAndDynamicConfig(account, to, request.getSubject(), request.getContent(), attachmentFiles.get(0).getAbsolutePath());
                            }
                        } else if (hasAttachments) {
                            if (isHtml) {
                                emailUtil.sendHtmlMailWithAttachmentsAndDynamicConfig(account, to, request.getSubject(), request.getContent(), toPathList(attachmentFiles));
                            } else {
                                emailUtil.sendMailWithAttachmentAndDynamicConfig(account, to, request.getSubject(), request.getContent(), attachmentFiles.get(0).getAbsolutePath());
                            }
                        } else if (hasInlineImages) {
                            if (isHtml) {
                                emailUtil.sendHtmlMailWithInlineImagesAndDynamicConfig(account, to, request.getSubject(), request.getContent(), request.getInlineImagePaths());
                            } else {
                                emailUtil.sendMailWithDynamicConfig(account, to, request.getSubject(), request.getContent());
                            }
                        } else {
                            if (isHtml) {
                                emailUtil.sendHtmlMailWithDynamicConfig(account, to, request.getSubject(), request.getContent());
                            } else {
                                emailUtil.sendMailWithDynamicConfig(account, to, request.getSubject(), request.getContent());
                            }
                        }
                        success++;
                    } catch (Exception e) {
                        fail++;
                        failList.append(to).append(", ");
                    }
                }
            } else if (type == 2) {
                for (String to : emailList) {
                    try {
                        boolean result = sendAliyunMail(account, to, request.getSubject(), request.getContent());
                        if (result) {
                            success++;
                        } else {
                            fail++;
                            failList.append(to).append(", ");
                        }
                    } catch (Exception e) {
                        fail++;
                        failList.append(to).append(", ");
                    }
                }
            } else if (type == 3) {
                for (String to : emailList) {
                    try {
                        boolean result = sendFeishuMail(account, to, request.getSubject(), request.getContent());
                        if (result) {
                            success++;
                        } else {
                            fail++;
                            failList.append(to).append(", ");
                        }
                    } catch (Exception e) {
                        fail++;
                        failList.append(to).append(", ");
                    }
                }
            } else {
                return "不支持的邮箱类型";
            }
        } catch (Exception e) {
            return "附件处理失败：" + e.getMessage();
        } finally {
            // 删除所有临时文件
            for (File file : attachmentFiles) {
                if (file != null && file.exists() && file.getName().startsWith("mail_attach_")) {
                    file.delete();
                }
            }
        }
        if (success > 0 && request.getFurnitureIds() != null) {
            for (Long furnitureId : request.getFurnitureIds()) {
                oaFurnitureTableMapper.updateEmailSendInfo(furnitureId);
            }
        }
        return "发送成功" + success + "封，失败" + fail + "封" + (fail > 0 ? ("，失败邮箱：" + failList) : "");
    }

    // 辅助方法：File列表转路径列表
    private List<String> toPathList(List<File> files) {
        List<String> paths = new ArrayList<>();
        for (File f : files) {
            if (f != null) paths.add(f.getAbsolutePath());
        }
        return paths;
    }
    private boolean sendAliyunMail(OaEmailAccount account, String to, String subject, String content) {
        try {
            DefaultProfile profile = DefaultProfile.getProfile(
                    "cn-hangzhou",
                    account.getAccessKey(),
                    account.getSecretKey()
            );
            IAcsClient client = new DefaultAcsClient(profile);

            SingleSendMailRequest request = new SingleSendMailRequest();
            request.setAccountName(account.getEmail());
            request.setFromAlias("发件人昵称");
            request.setAddressType(1);
            request.setReplyToAddress(true);
            request.setToAddress(to);
            request.setSubject(subject);
            request.setHtmlBody(content);

            SingleSendMailResponse response = client.getAcsResponse(request);
            //打印这个响应
            System.out.println(response.getRequestId());
            return true;
        } catch (ClientException e) {
            // 打印日志 e.getErrCode() + e.getErrMsg()
            return false;
        }
    }
    private boolean sendFeishuMail(OaEmailAccount account, String to, String subject, String content) {
        try {
            // 1. 构建飞书Client
            Client client = Client.newBuilder(account.getAccessKey(), account.getSecretKey()).build();

            // 2. 构建收件人
            MailAddress[] toList = new MailAddress[]{
                    MailAddress.newBuilder().mailAddress(to).name(to).build()
            };

            // 3. 构建请求
            SendUserMailboxMessageReq req = SendUserMailboxMessageReq.newBuilder()
                    .userMailboxId("me") // 推荐用 "me"
                    .message(Message.newBuilder()
                            .subject(subject)
                            .to(toList)
                            .bodyHtml(content)
                            .build())
                    .build();

            // 4. 发送请求
            SendUserMailboxMessageResp resp = client.mail().v1().userMailboxMessage().send(req);

            // 5. 判断结果
            if (!resp.success()) {
                // 可加日志 resp.getCode(), resp.getMsg()
                return false;
            }
            return true;
        } catch (Exception e) {
            // 可加日志 e.getMessage()
            return false;
        }
    }
}
