package com.corewing.app.util;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.SpringBootTest;

import javax.mail.*;
import java.util.Properties;

/**
 * SMTP 连接诊断测试
 * 用于排查邮件发送问题
 */
@SpringBootTest
public class SmtpConnectionTest {

    @Value("${spring.mail.host}")
    private String host;

    @Value("${spring.mail.port}")
    private int port;

    @Value("${spring.mail.username}")
    private String username;

    @Value("${spring.mail.password}")
    private String password;

    /**
     * 测试 SMTP 服务器连接和认证
     */
    @Test
    public void testSmtpConnection() {
        System.out.println("========== SMTP 连接诊断 ==========");
        System.out.println("📧 邮件服务器配置信息：");
        System.out.println("   SMTP 服务器: " + host);
        System.out.println("   SMTP 端口: " + port);
        System.out.println("   发件人邮箱: " + username);
        System.out.println("   授权码长度: " + (password != null ? password.length() : 0) + " 位");
        System.out.println("   授权码（隐藏中间部分）: " + maskPassword(password));
        System.out.println();

        // 测试 465 端口（SSL）
        if (port == 465) {
            testSslConnection();
        }
        // 测试 587 端口（STARTTLS）
        else if (port == 587) {
            testStartTlsConnection();
        }
        // 测试 25 端口（无加密或 STARTTLS）
        else if (port == 25) {
            testPort25Connection();
        } else {
            System.out.println("❓ 未知的端口: " + port);
        }
    }

    /**
     * 测试 SSL 连接（465 端口）
     */
    private void testSslConnection() {
        System.out.println("🔐 正在测试 SSL 连接（端口 465）...");
        System.out.println();

        Properties props = new Properties();
        props.put("mail.smtp.host", host);
        props.put("mail.smtp.port", port);
        props.put("mail.smtp.auth", "true");
        props.put("mail.smtp.ssl.enable", "true");
        props.put("mail.smtp.ssl.required", "true");
        props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
        props.put("mail.smtp.socketFactory.port", port);
        props.put("mail.smtp.socketFactory.fallback", "false");
        props.put("mail.smtp.timeout", "10000");
        props.put("mail.smtp.connectiontimeout", "10000");

        testConnection(props);
    }

    /**
     * 测试 STARTTLS 连接（587 端口）
     */
    private void testStartTlsConnection() {
        System.out.println("🔐 正在测试 STARTTLS 连接（端口 587）...");
        System.out.println();

        Properties props = new Properties();
        props.put("mail.smtp.host", host);
        props.put("mail.smtp.port", port);
        props.put("mail.smtp.auth", "true");
        props.put("mail.smtp.starttls.enable", "true");
        props.put("mail.smtp.starttls.required", "true");
        props.put("mail.smtp.ssl.enable", "false");
        props.put("mail.smtp.timeout", "10000");
        props.put("mail.smtp.connectiontimeout", "10000");

        testConnection(props);
    }

    /**
     * 测试端口 25 连接
     */
    private void testPort25Connection() {
        System.out.println("🔓 正在测试端口 25 连接...");
        System.out.println();

        Properties props = new Properties();
        props.put("mail.smtp.host", host);
        props.put("mail.smtp.port", port);
        props.put("mail.smtp.auth", "true");
        props.put("mail.smtp.timeout", "10000");
        props.put("mail.smtp.connectiontimeout", "10000");

        testConnection(props);
    }

    /**
     * 执行连接测试
     */
    private void testConnection(Properties props) {
        Session session = Session.getInstance(props, new Authenticator() {
            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(username, password);
            }
        });

        // 开启调试模式
        session.setDebug(true);

        Transport transport = null;
        try {
            System.out.println("⏳ 正在连接到 SMTP 服务器...");
            transport = session.getTransport("smtp");
            transport.connect(host, username, password);

            System.out.println();
            System.out.println("========================================");
            System.out.println("✅ SMTP 连接成功！");
            System.out.println("========================================");
            System.out.println("📝 诊断结果：");
            System.out.println("   ✓ 服务器地址正确");
            System.out.println("   ✓ 端口配置正确");
            System.out.println("   ✓ 用户名正确");
            System.out.println("   ✓ 授权码正确");
            System.out.println();
            System.out.println("💡 邮件配置没有问题，可以正常发送邮件了！");

        } catch (AuthenticationFailedException e) {
            System.out.println();
            System.out.println("========================================");
            System.out.println("❌ 认证失败！");
            System.out.println("========================================");
            System.out.println("📝 错误原因：用户名或密码（授权码）错误");
            System.out.println();
            System.out.println("💡 解决方案：");
            System.out.println("   1. 检查邮箱地址是否正确: " + username);
            System.out.println("   2. 确认是否使用授权码而非登录密码");
            System.out.println("   3. 登录邮箱管理后台，查找「SMTP设置」或「客户端授权密码」");
            System.out.println("   4. 确认是否需要先开启 SMTP 服务");
            System.out.println("   5. 重新生成授权码并更新到 application.properties");
            System.out.println();
            System.out.println("🔗 常见企业邮箱 SMTP 设置：");
            System.out.println("   • 腾讯企业邮箱: smtp.exmail.qq.com:465 (SSL)");
            System.out.println("   • 阿里企业邮箱: smtp.qiye.aliyun.com:465 (SSL)");
            System.out.println("   • 网易企业邮箱: smtp.qiye.163.com:465 (SSL)");
            System.out.println();
            System.out.println("⚠️  详细错误信息: " + e.getMessage());

        } catch (MessagingException e) {
            System.out.println();
            System.out.println("========================================");
            System.out.println("❌ 连接失败！");
            System.out.println("========================================");
            System.out.println("📝 错误类型：" + e.getClass().getSimpleName());
            System.out.println();
            System.out.println("💡 可能的原因：");
            System.out.println("   1. SMTP 服务器地址错误: " + host);
            System.out.println("   2. 端口号错误或被防火墙封禁: " + port);
            System.out.println("   3. 网络连接问题");
            System.out.println("   4. SSL/TLS 配置不匹配");
            System.out.println();
            System.out.println("🔧 建议尝试：");
            System.out.println("   • 如果当前是 465 端口，尝试改为 587 + STARTTLS");
            System.out.println("   • 检查防火墙是否封禁了邮件端口");
            System.out.println("   • 联系邮箱服务商确认正确的 SMTP 配置");
            System.out.println();
            System.out.println("⚠️  详细错误信息: " + e.getMessage());

        } catch (Exception e) {
            System.out.println();
            System.out.println("========================================");
            System.out.println("❌ 未知错误！");
            System.out.println("========================================");
            System.out.println("⚠️  错误信息: " + e.getMessage());
            e.printStackTrace();

        } finally {
            if (transport != null && transport.isConnected()) {
                try {
                    transport.close();
                } catch (MessagingException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 隐藏密码中间部分
     */
    private String maskPassword(String password) {
        if (password == null || password.length() <= 4) {
            return "****";
        }
        int showChars = Math.min(2, password.length() / 4);
        String start = password.substring(0, showChars);
        String end = password.substring(password.length() - showChars);
        int maskLength = password.length() - (showChars * 2);
        String mask = "*".repeat(maskLength);
        return start + mask + end;
    }
}
