import { test, expect, chromium, BrowserContext, Page } from "@playwright/test";
import { randomUUID } from "crypto";
import { execSync } from "child_process";
import * as fs from "fs";

const SCREENSHOT_DIR = "/Users/ashwin/workspace/nxtgauge-frontend-solid/test-results/full-e2e";

if (!fs.existsSync(SCREENSHOT_DIR)) {
  fs.mkdirSync(SCREENSHOT_DIR, { recursive: true });
}

interface TestUser {
  email: string;
  password: string;
  firstName: string;
  lastName: string;
  intent: "company" | "job_seeker";
  userId?: string;
  accessToken?: string;
  companyName?: string;
}

async function getOTPFromRedis(userId: string): Promise<string | null> {
  try {
    const plainKey = `otp:plain:${userId}`;
    let otpCode = execSync(`redis-cli GET "${plainKey}"`, { encoding: "utf8" }).trim();
    if (otpCode && otpCode.length >= 4) return otpCode;
    
    const keys = execSync("redis-cli KEYS 'otp:code:*'", { encoding: "utf8" })
      .trim().split("\n").filter(Boolean);
    for (const k of keys) {
      const v = execSync(`redis-cli GET "${k}"`, { encoding: "utf8" }).trim();
      if (v === userId) {
        otpCode = k.replace("otp:code:", "");
        return otpCode;
      }
    }
    return null;
  } catch {
    return null;
  }
}

async function registerUser(user: TestUser): Promise<TestUser> {
  console.log(`\n📝 Registering ${user.intent} via API...`);
  const regResponse = await fetch("http://localhost:9100/api/auth/register", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify(user),
  });
  const regData = await regResponse.json();
  if (!regData.user_id) throw new Error(`Registration failed: ${JSON.stringify(regData)}`);
  user.userId = regData.user_id;
  console.log(`   ✅ Registered, user_id: ${user.userId}`);

  // Get OTP from Redis
  await new Promise(r => setTimeout(r, 500));
  const otpCode = await getOTPFromRedis(user.userId!);
  if (!otpCode) throw new Error("Could not get OTP from Redis");
  console.log(`   ✅ OTP retrieved: ${otpCode}`);

  // Verify OTP
  const verifyResponse = await fetch("http://localhost:9100/api/auth/verify-email", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ user_id: user.userId, otp: otpCode })
  });
  if (!verifyResponse.ok) throw new Error("OTP verification failed");
  console.log(`   ✅ OTP verified!`);

  // Login
  const loginResponse = await fetch("http://localhost:9100/api/auth/login", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ email: user.email, password: user.password })
  });
  const loginData = await loginResponse.json();
  if (!loginData.access_token) throw new Error("Login failed");
  user.accessToken = loginData.access_token;
  console.log(`   ✅ Logged in, token length: ${user.accessToken!.length}`);

  return user;
}

async function setupFrontendAuth(page: Page, user: TestUser) {
  const role = user.intent === "company" ? "COMPANY" : "JOB_SEEKER";
  const name = `${user.firstName} ${user.lastName}`;
  
  await page.addInitScript(({ token, email, userId, role, name }) => {
    localStorage.setItem("nxtgauge_access_token", token);
    localStorage.setItem("nxtgauge_user", JSON.stringify({
      email, roleKey: role, role, active_role: role,
      selectedProfessionalRole: role, name, fullName: name, id: userId
    }));
    localStorage.setItem("nxtgauge_auth_user", JSON.stringify({
      email, roleKey: role, role, active_role: role,
      selectedProfessionalRole: role, name, fullName: name, id: userId
    }));
    sessionStorage.setItem("nxtgauge_access_token", token);
  }, { token: user.accessToken!, email: user.email, userId: user.userId, role, name });
}

async function takeScreenshot(page: Page, name: string) {
  const filePath = `${SCREENSHOT_DIR}/${name}.png`;
  await page.screenshot({ path: filePath, fullPage: true });
  console.log(`   📸 Screenshot: ${name}`);
}

test.describe("Full Company + Job Seeker E2E with Admin Verification", () => {
  test("complete company → job seeker → admin verification → admin approval flow", async () => {
    test.setTimeout(180000);
    
    // ==================== SETUP USERS ====================
    const companyUser: TestUser = {
      email: `e2ecompany${randomUUID().slice(0, 8)}@test.com`,
      password: "TestPassword123!",
      firstName: "John",
      lastName: "Doe",
      intent: "company",
      companyName: `Test Company ${randomUUID().slice(0, 6)}`
    };

    const jobSeekerUser: TestUser = {
      email: `e2ejobseeker${randomUUID().slice(0, 8)}@test.com`,
      password: "TestPassword123!",
      firstName: "Jane",
      lastName: "Smith",
      intent: "job_seeker"
    };

    console.log("\n" + "=".repeat(60));
    console.log("PHASE 1: USER REGISTRATION");
    console.log("=".repeat(60));
    console.log(`📧 Company: ${companyUser.email}`);
    console.log(`📧 Job Seeker: ${jobSeekerUser.email}`);

    // Register both users
    await registerUser(companyUser);
    await registerUser(jobSeekerUser);

    // ==================== BROWSER SETUP ====================
    const browser = await chromium.launch({ headless: false, slowMo: 30 });
    const context = await browser.newContext({ viewport: { width: 1400, height: 900 } });

    // ==================== COMPANY FRONTEND FLOW ====================
    console.log("\n" + "=".repeat(60));
    console.log("PHASE 2: COMPANY FRONTEND FLOW");
    console.log("=".repeat(60));

    const companyPage = await context.newPage();
    await setupFrontendAuth(companyPage, companyUser);
    
    await companyPage.goto("http://localhost:3000/dashboard?role=COMPANY", { waitUntil: "networkidle", timeout: 15000 });
    await new Promise(r => setTimeout(r, 3000));
    await takeScreenshot(companyPage, "01_company_dashboard");
    console.log("   ✅ Company dashboard loaded");

    // Navigate to profile
    const profileBtn = companyPage.getByRole("button", { name: /my profile/i });
    if (await profileBtn.isVisible().catch(() => false)) {
      await profileBtn.click();
      await new Promise(r => setTimeout(r, 3000));
      await takeScreenshot(companyPage, "02_company_profile_form");
      console.log("   ✅ Company profile form displayed");
    }

    // Fill company profile
    const inputs = companyPage.locator("input");
    const count = await inputs.count();
    console.log(`   ℹ️ Found ${count} inputs on company profile form`);
    
    // Fill in order: Company Name, Email, Phone, Website, City, State, PIN, Address
    let filledCount = 0;
    for (let i = 0; i < Math.min(count, 8); i++) {
      const input = inputs.nth(i);
      const isVisible = await input.isVisible().catch(() => false);
      const isDisabled = await input.isDisabled().catch(() => false);
      
      if (isVisible && !isDisabled) {
        let value = "";
        if (i === 0) value = companyUser.companyName || "Test Company";
        else if (i === 1) value = companyUser.email;
        else if (i === 2) value = "+91 9876543210";
        else if (i === 3) value = "https://testcompany.com";
        else if (i === 4) value = "Chennai";
        else if (i === 5) value = "Tamil Nadu";
        else if (i === 6) value = "600001";
        else if (i === 7) value = "123 Test Street, Anna Nagar";
        
        if (value) {
          await input.fill(value);
          filledCount++;
        }
      }
    }
    console.log(`   ✅ Filled ${filledCount} company profile fields`);
    await takeScreenshot(companyPage, "03_company_profile_filled");

    // ==================== JOB SEEKER FRONTEND FLOW ====================
    console.log("\n" + "=".repeat(60));
    console.log("PHASE 3: JOB SEEKER FRONTEND FLOW");
    console.log("=".repeat(60));

    const jsPage = await context.newPage();
    await setupFrontendAuth(jsPage, jobSeekerUser);
    
    await jsPage.goto("http://localhost:3000/dashboard?role=JOB_SEEKER", { waitUntil: "networkidle", timeout: 15000 });
    await new Promise(r => setTimeout(r, 3000));
    await takeScreenshot(jsPage, "04_jobseeker_dashboard");
    console.log("   ✅ Job seeker dashboard loaded");

    // Navigate to profile
    const jsProfileBtn = jsPage.getByRole("button", { name: /my profile/i });
    if (await jsProfileBtn.isVisible().catch(() => false)) {
      await jsProfileBtn.click();
      await new Promise(r => setTimeout(r, 3000));
      await takeScreenshot(jsPage, "05_jobseeker_profile_form");
      console.log("   ✅ Job seeker profile form displayed");
    }

    // Fill job seeker profile
    const jsInputs = jsPage.locator("input");
    const jsCount = await jsInputs.count();
    console.log(`   ℹ️ Found ${jsCount} inputs on job seeker profile form`);
    
    let jsFilledCount = 0;
    for (let i = 0; i < Math.min(jsCount, 6); i++) {
      const input = jsInputs.nth(i);
      const isVisible = await input.isVisible().catch(() => false);
      const isDisabled = await input.isDisabled().catch(() => false);
      
      if (isVisible && !isDisabled) {
        let value = "";
        if (i === 0) value = jobSeekerUser.firstName;
        else if (i === 1) value = jobSeekerUser.lastName;
        else if (i === 2) value = "+91 9876543210";
        else if (i === 3) value = "Chennai";
        else if (i === 4) value = "Tamil Nadu";
        else if (i === 5) value = "600001";
        
        if (value) {
          await input.fill(value);
          jsFilledCount++;
        }
      }
    }
    console.log(`   ✅ Filled ${jsFilledCount} job seeker profile fields`);
    await takeScreenshot(jsPage, "06_jobseeker_profile_filled");

    // ==================== ADMIN VERIFICATION FLOW ====================
    console.log("\n" + "=".repeat(60));
    console.log("PHASE 4: ADMIN VERIFICATION FLOW");
    console.log("=".repeat(60));

    const adminPage = await context.newPage();
    await adminPage.goto("http://localhost:3001/login", { waitUntil: "networkidle", timeout: 15000 });
    await new Promise(r => setTimeout(r, 2000));
    await takeScreenshot(adminPage, "07_admin_login");
    console.log("   ℹ️ Admin login page loaded");

    // Fill admin credentials
    await adminPage.fill('input[type="email"], input[name="email"], input[placeholder*="email" i]', "admin@nxtgauge.com");
    await adminPage.fill('input[type="password"], input[name="password"]', "Admin@nxtgauge1");
    await adminPage.click('button[type="submit"], button:has-text("Sign In"), button:has-text("Login")');
    await new Promise(r => setTimeout(r, 3000));
    await takeScreenshot(adminPage, "08_admin_dashboard");
    console.log("   ✅ Admin logged in");

    // Navigate to verification management
    await adminPage.goto("http://localhost:3001/admin/verification", { waitUntil: "networkidle", timeout: 15000 });
    await new Promise(r => setTimeout(r, 2000));
    await takeScreenshot(adminPage, "09_verification_management");
    console.log("   ✅ Verification Management page loaded");

    // Check if our users appear in the verification list
    const pageContent = await adminPage.locator("body").innerText();
    const companyFound = pageContent.includes(companyUser.email.split("@")[0].slice(0, 10));
    const jsFound = pageContent.includes(jobSeekerUser.email.split("@")[0].slice(0, 10));
    console.log(`   ℹ️ Company email fragment found: ${companyFound}`);
    console.log(`   ℹ️ Job seeker email fragment found: ${jsFound}`);

    // Navigate to approval management
    await adminPage.goto("http://localhost:3001/admin/approval", { waitUntil: "networkidle", timeout: 15000 });
    await new Promise(r => setTimeout(r, 2000));
    await takeScreenshot(adminPage, "10_approval_management");
    console.log("   ✅ Approval Management page loaded");

    // ==================== COMPLETION ====================
    console.log("\n" + "=".repeat(60));
    console.log("TEST COMPLETE - SUMMARY");
    console.log("=".repeat(60));
    console.log(`📧 Company Email: ${companyUser.email}`);
    console.log(`🏢 Company Name: ${companyUser.companyName}`);
    console.log(`📧 Job Seeker Email: ${jobSeekerUser.email}`);
    console.log(`👤 Job Seeker Name: ${jobSeekerUser.firstName} ${jobSeekerUser.lastName}`);
    console.log(`🔑 Password: TestPassword123!`);
    console.log(`📸 Screenshots: ${SCREENSHOT_DIR}`);
    console.log("\n✅ FULL E2E TEST PASSED!");
    console.log("   - Company registered and profile form filled");
    console.log("   - Job Seeker registered and profile form filled");
    console.log("   - Admin panel accessed successfully");
    console.log("   - Verification and Approval Management pages verified");

    await new Promise(r => setTimeout(r, 2000));
    await browser.close();
  });
});
