
const BASE_URL = "http://localhost:5001";
const MAILHOG_API = "http://localhost:8025/api/v2";

let cookie = "";

async function request(method: string, path: string, body?: any) {
    const headers: any = { "Content-Type": "application/json" };
    if (cookie) headers["Cookie"] = cookie;

    const res = await fetch(`${BASE_URL}${path}`, {
        method,
        headers,
        body: body ? JSON.stringify(body) : undefined,
    });

    const setCookie = res.headers.get("set-cookie");
    if (setCookie) {
        cookie = setCookie.split(";")[0];
    }

    const text = await res.text();
    try {
        const data = JSON.parse(text);
        return { status: res.status, data };
    } catch {
        return { status: res.status, data: text };
    }
}

async function getLatestEmail(toEmail: string) {
    try {
        const res = await fetch(`${MAILHOG_API}/messages`);
        const data = await res.json();
        // MailHog returns { total: number, count: number, start: number, items: [...] }
        // items are sorted newest first usually in MailHog UI, but API might vary.
        // Let's filter by 'To' and take the first one.
        const messages = data.items;
        for (const msg of messages) {
            // Headers is an object like { "To": ["<email>"], ... }
            // Content.Headers.To
            const toHeader = msg.Content.Headers.To?.[0];
            if (toHeader && toHeader.includes(toEmail)) {
                return msg;
            }
        }
        return null;
    } catch (e) {
        console.error("Failed to fetch from MailHog:", e);
        return null;
    }
}

async function run() {
    console.log("📧 Testing Email Flow...");

    const timestamp = Date.now();
    const username = `email_user_${timestamp}`;
    const email = `test_${timestamp}@example.com`;
    const password = "password123";
    const newPassword = "newpassword456";

    // 1. Register User
    console.log(`\n1. Registering user: ${username} (${email})`);
    let res = await request("POST", "/api/register", { username, password, email });
    if (res.status === 201 || res.status === 200) {
        console.log("✅ Registration successful");
    } else {
        console.error("❌ Registration failed:", res.data);
        process.exit(1);
    }

    // 2. Request Password Reset
    console.log("\n2. Requesting Password Reset...");
    // Logout first just in case
    await request("POST", "/api/logout");
    cookie = ""; // Clear cookie

    res = await request("POST", "/api/auth/forgot-password", { email });
    if (res.status === 200) {
        console.log("✅ Reset request sent:", res.data.message);
    } else {
        console.error("❌ Reset request failed:", res.data);
        process.exit(1);
    }

    // 3. Check MailHog
    console.log("\n3. Checking MailHog for email...");
    // Wait a bit for email to arrive
    await new Promise(r => setTimeout(r, 2000));

    const emailMsg = await getLatestEmail(email);
    if (emailMsg) {
        console.log("✅ Email found!", emailMsg.Content.Headers.Subject[0]);
    } else {
        console.error("❌ Email NOT found in MailHog!");
        process.exit(1);
    }

    // 4. Extract Token
    // We expect a link like: http://localhost:5001/reset-password?token=...
    // In text body: msg.Content.Body
    let body = emailMsg.Content.Body;

    // Simple QP decoding for test
    body = body.replace(/=\r\n/g, '').replace(/=\n/g, '').replace(/=3D/g, '=');

    console.log("DEBUG BODY DECODED:", body);

    const match = body.match(/token=([a-zA-Z0-9-]+)/);
    if (!match) {
        console.error("❌ Token not found in email body!");
        console.log("Body:", body);
        process.exit(1);
    }
    const token = match[1];
    console.log("✅ Token extracted:", token);

    // 5. Reset Password
    console.log("\n5. Resetting Password...");
    res = await request("POST", "/api/auth/reset-password", { token, newPassword });
    if (res.status === 200) {
        console.log("✅ Password reset successful");
    } else {
        console.error("❌ Password reset failed:", res.data);
        process.exit(1);
    }

    // 6. Login with New Password
    console.log("\n6. Logging in with NEW password...");
    res = await request("POST", "/api/login", { username, password: newPassword });
    if (res.status === 200) {
        console.log("✅ Login successful with new password!");
    } else {
        console.error("❌ Login failed:", res.data);
        process.exit(1);
    }

    // 7. Login with OLD Password (should fail)
    console.log("\n7. Verifying OLD password fails...");
    res = await request("POST", "/api/login", { username, password });
    if (res.status === 401) {
        console.log("✅ Old password rejected correctly.");
    } else {
        console.error("❌ Old password SHOULD fail but got:", res.status);
    }

    console.log("\n🎉 Full Email Flow Test Passed!");
}

run();
