import { expect, test } from "@playwright/test";

type RoleCase = {
  roleKey: string;
  applicantName: string;
  type: "profile" | "job" | "requirement";
  route?: string;
  endpoint?: string;
  viewLabel?: string;
};

const roleCases: RoleCase[] = [
  { roleKey: "COMPANY", applicantName: "Nxtgauge Labs", type: "job" },
  { roleKey: "CUSTOMER", applicantName: "Arun Customer", type: "requirement" },
  { roleKey: "JOB_SEEKER", applicantName: "Jaya Jobseeker", type: "profile" },
  { roleKey: "PHOTOGRAPHER", applicantName: "Priya Photographer", type: "profile", route: "/admin/photographer", endpoint: "/api/admin/photographers", viewLabel: "View Profile" },
  { roleKey: "MAKEUP_ARTIST", applicantName: "Maya Makeup", type: "profile", route: "/admin/makeup-artist", endpoint: "/api/admin/makeup-artists", viewLabel: "View Profile" },
  { roleKey: "TUTOR", applicantName: "Tejas Tutor", type: "profile", route: "/admin/tutors", endpoint: "/api/admin/tutors", viewLabel: "View Profile" },
  { roleKey: "DEVELOPER", applicantName: "Dev Developer", type: "profile", route: "/admin/developers", endpoint: "/api/admin/developers", viewLabel: "View Profile" },
  { roleKey: "VIDEO_EDITOR", applicantName: "Vani Video", type: "profile", route: "/admin/video-editors", endpoint: "/api/admin/video-editors", viewLabel: "View Profile" },
  { roleKey: "UGC_CONTENT_CREATOR", applicantName: "Uma UGC", type: "profile", route: "/admin/ugc-content-creator", viewLabel: "View Profile" },
  { roleKey: "GRAPHIC_DESIGNER", applicantName: "Gita Graphic", type: "profile", route: "/admin/graphic-designers", endpoint: "/api/admin/graphic-designers", viewLabel: "View Profile" },
  { roleKey: "SOCIAL_MEDIA_MANAGER", applicantName: "Soma Social", type: "profile", route: "/admin/social-media-managers", endpoint: "/api/admin/social-media-managers", viewLabel: "View Profile" },
  { roleKey: "FITNESS_TRAINER", applicantName: "Farah Fitness", type: "profile", route: "/admin/fitness-trainers", endpoint: "/api/admin/fitness-trainers", viewLabel: "View Profile" },
  { roleKey: "CATERING_SERVICES", applicantName: "Chetan Catering", type: "profile", route: "/admin/catering-services", endpoint: "/api/admin/catering-services", viewLabel: "View Profile" },
];

const now = new Date().toISOString();

function toTitle(value: string) {
  return String(value || "")
    .toLowerCase()
    .replace(/_/g, " ")
    .replace(/\b\w/g, (c) => c.toUpperCase());
}

test.describe("Verification to approval lifecycle across roles", () => {
  test("all roles validate docs, request docs, approve, and appear in management with view actions", async ({ page }) => {
    test.setTimeout(120000);

    const verificationMap = new Map(
      roleCases.map((item, idx) => {
        const payload: any = {
          first_name: item.applicantName.split(" ")[0] || "User",
          last_name: item.applicantName.split(" ").slice(1).join(" ") || "",
          company_name: item.roleKey === "COMPANY" ? "Nxtgauge Labs Pvt Ltd" : undefined,
          city: "Chennai",
          area: "Anna Nagar",
          role_key: item.roleKey,
          documents: [
            {
              id: `${item.roleKey.toLowerCase()}-doc-image`,
              title: `${toTitle(item.roleKey)} ID Proof`,
              type: "IMAGE",
              url: "/nxtgauge-logo.png",
              status: "SUBMITTED",
            },
            {
              id: `${item.roleKey.toLowerCase()}-doc-pdf`,
              title: `${toTitle(item.roleKey)} Address Proof`,
              type: "PDF",
              url: "/nxtgauge-icon.png",
              status: "SUBMITTED",
            },
          ],
        };
        if (item.type === "job") payload.job_id = "job-001";
        if (item.type === "requirement") payload.requirement_id = "req-001";

        return [
          item.roleKey,
          {
            id: `ver-${idx + 1}`,
            user_id: `user-${idx + 1}`,
            user_name: item.applicantName,
            role_key: item.roleKey,
            type: item.type,
            case_type: item.type,
            status: "PENDING",
            created_at: now,
            updated_at: now,
            payload,
          },
        ];
      })
    );

    const finalApprovedRoles = new Set<string>();
    let jobFinalApproved = false;
    let requirementFinalApproved = false;

    const statusForRole = (roleKey: string) => {
      if (roleKey === "COMPANY") return jobFinalApproved ? "ACTIVE" : "PENDING";
      if (roleKey === "CUSTOMER") return requirementFinalApproved ? "ACTIVE" : "PENDING";
      return finalApprovedRoles.has(roleKey) ? "ACTIVE" : "PENDING";
    };

    const asProfessionRow = (roleKey: string, applicantName: string) => {
      const parts = applicantName.split(" ");
      return {
        id: `pro-${roleKey.toLowerCase()}`,
        first_name: parts[0] || applicantName,
        last_name: parts.slice(1).join(" ") || "User",
        email: `${roleKey.toLowerCase()}@example.test`,
        phone: "9999999999",
        status: statusForRole(roleKey),
        created_at: now,
      };
    };

    await page.route("**/api/admin/**", async (route) => {
      const req = route.request();
      const url = new URL(req.url());
      const path = url.pathname;
      const method = req.method();

      if (path === "/api/admin/verifications" && method === "GET") {
        await route.fulfill({
          status: 200,
          contentType: "application/json",
          body: JSON.stringify({ items: Array.from(verificationMap.values()) }),
        });
        return;
      }

      if (path.startsWith("/api/admin/verifications/") && method === "GET") {
        const id = path.split("/").pop() || "";
        const row = Array.from(verificationMap.values()).find((item) => item.id === id);
        await route.fulfill({
          status: row ? 200 : 404,
          contentType: "application/json",
          body: JSON.stringify(row || { error: "Not found" }),
        });
        return;
      }

      if (path.startsWith("/api/admin/verifications/") && method === "POST") {
        const parts = path.split("/");
        const id = parts[4] || "";
        const action = parts[5] || "";
        const row = Array.from(verificationMap.values()).find((item) => item.id === id);
        if (!row) {
          await route.fulfill({ status: 404, contentType: "application/json", body: JSON.stringify({ error: "Not found" }) });
          return;
        }
        if (action === "approve") row.status = "APPROVED";
        if (action === "reject") row.status = "REJECTED";
        if (action === "request-documents") row.status = "DOCUMENTS_REQUESTED";
        if (action === "request-revision") row.status = "REVISION_REQUESTED";
        row.updated_at = new Date().toISOString();
        await route.fulfill({ status: 200, contentType: "application/json", body: JSON.stringify({ ok: true }) });
        return;
      }

      if (path.startsWith("/api/admin/approvals/jobs/") && method === "POST") {
        if (path.endsWith("/approve")) jobFinalApproved = true;
        await route.fulfill({ status: 200, contentType: "application/json", body: JSON.stringify({ ok: true }) });
        return;
      }

      if (path.startsWith("/api/admin/approvals/requirements/") && method === "POST") {
        if (path.endsWith("/approve")) requirementFinalApproved = true;
        await route.fulfill({ status: 200, contentType: "application/json", body: JSON.stringify({ ok: true }) });
        return;
      }

      if (path.startsWith("/api/admin/approvals/profiles/") && method === "POST") {
        const verificationId = path.split("/")[5] || "";
        const row = Array.from(verificationMap.values()).find((item) => item.id === verificationId);
        if (path.endsWith("/approve") && row) finalApprovedRoles.add(row.role_key);
        await route.fulfill({ status: 200, contentType: "application/json", body: JSON.stringify({ ok: true }) });
        return;
      }

      if (path === "/api/admin/companies" && method === "GET") {
        await route.fulfill({
          status: 200,
          contentType: "application/json",
          body: JSON.stringify([
            {
              id: "cmp-001",
              company_name: "Nxtgauge Labs Pvt Ltd",
              registration_number: "TN-REG-0021",
              industry: "Software",
              city: "Chennai",
              status: jobFinalApproved ? "APPROVED" : "PENDING",
              created_at: now,
              updated_at: now,
              job_postings_count: 3,
              total_hires: 1,
            },
          ]),
        });
        return;
      }

      if (path === "/api/admin/companies/jobs" && method === "GET") {
        await route.fulfill({
          status: 200,
          contentType: "application/json",
          body: JSON.stringify([
            {
              id: "job-001",
              title: "Senior Frontend Engineer",
              company_name: "Nxtgauge Labs Pvt Ltd",
              location: "Chennai",
              salary_min: 1200000,
              salary_max: 1800000,
              status: jobFinalApproved ? "ACTIVE" : "PENDING_APPROVAL",
              created_at: now,
              updated_at: now,
            },
          ]),
        });
        return;
      }

      if (path === "/api/admin/leads" && method === "GET") {
        await route.fulfill({
          status: 200,
          contentType: "application/json",
          body: JSON.stringify([
            {
              id: "req-001",
              title: "Wedding Photography Requirement",
              profession: "photographer",
              budget_range: "INR 75,000",
              location: "Chennai",
              status: requirementFinalApproved ? "ACTIVE" : "PENDING",
              description: "Need full-day candid and cinematic coverage",
              created_at: now,
              updated_at: now,
            },
          ]),
        });
        return;
      }

      if (path === "/api/admin/users" && method === "GET") {
        const requestedRole = String(url.searchParams.get("role") || "").toUpperCase();
        const users = roleCases.map((item, idx) => {
          const status = statusForRole(item.roleKey);
          const names = item.applicantName.split(" ");
          return {
            id: `user-${idx + 1}`,
            first_name: names[0] || "User",
            last_name: names.slice(1).join(" ") || "",
            full_name: item.applicantName,
            email: `${item.roleKey.toLowerCase()}@example.test`,
            status,
            roles: status === "ACTIVE" ? [item.roleKey] : [],
            created_at: now,
            updated_at: now,
          };
        });
        const payload = requestedRole ? users.filter((u) => u.roles.includes(requestedRole)) : users;
        await route.fulfill({ status: 200, contentType: "application/json", body: JSON.stringify(payload) });
        return;
      }

      const professionEndpointMap: Record<string, string> = {
        "/api/admin/photographers": "PHOTOGRAPHER",
        "/api/admin/makeup-artists": "MAKEUP_ARTIST",
        "/api/admin/tutors": "TUTOR",
        "/api/admin/developers": "DEVELOPER",
        "/api/admin/video-editors": "VIDEO_EDITOR",
        "/api/admin/graphic-designers": "GRAPHIC_DESIGNER",
        "/api/admin/social-media-managers": "SOCIAL_MEDIA_MANAGER",
        "/api/admin/fitness-trainers": "FITNESS_TRAINER",
        "/api/admin/catering-services": "CATERING_SERVICES",
      };

      if (method === "GET" && professionEndpointMap[path]) {
        const roleKey = professionEndpointMap[path];
        const roleCase = roleCases.find((item) => item.roleKey === roleKey)!;
        await route.fulfill({
          status: 200,
          contentType: "application/json",
          body: JSON.stringify([asProfessionRow(roleKey, roleCase.applicantName)]),
        });
        return;
      }

      await route.fulfill({ status: 200, contentType: "application/json", body: JSON.stringify([]) });
    });

    await page.goto("/admin/verification?_preview=1", { waitUntil: "domcontentloaded" });
    await expect(page.getByRole("heading", { name: "Verification Management" })).toBeVisible();

    for (const item of roleCases) {
      await expect(page.getByText(toTitle(item.roleKey), { exact: false }).first()).toBeVisible();
    }

    const firstRole = roleCases[0];
    const firstRow = page.locator("tr", { hasText: firstRole.applicantName }).first();
    await firstRow.getByRole("button", { name: "View" }).click();

    await expect(page.getByText("Submitted Documents")).toBeVisible();
    await page.getByRole("button", { name: "View" }).nth(1).click();
    await expect(page.getByRole("button", { name: "Close" })).toBeVisible();
    await page.getByRole("button", { name: "Close" }).click();

    const requestCheckbox = page.locator('input[type="checkbox"]').nth(1);
    await requestCheckbox.check();
    await page.getByRole("button", { name: "Request Selected Documents" }).click();
    await expect(page.getByText(/Document request sent/i)).toBeVisible();

    await page.getByRole("button", { name: "Approve" }).first().click();
    await expect(page.getByText("Successfully verified and sent to Approval Management.")).toBeVisible();
    await page.getByRole("button", { name: "Back to List" }).click();

    for (const item of roleCases.slice(1)) {
      const row = page.locator("tr", { hasText: item.applicantName }).first();
      await row.getByRole("button", { name: "View" }).click();
      await page.getByRole("button", { name: "Approve" }).first().click();
      await page.getByRole("button", { name: "Back to List" }).click();
    }

    await page.goto("/admin/approval?_preview=1", { waitUntil: "domcontentloaded" });
    await expect(page.getByRole("heading", { name: "Approval Management" })).toBeVisible();

    for (const item of roleCases) {
      const row = page.locator("tr", { hasText: item.applicantName }).first();
      await expect(row).toBeVisible();
    }

    const firstApprovalRow = page.locator("tbody tr").first();
    await firstApprovalRow.locator("button").first().click();
    await page.getByRole("button", { name: /^Approve$/ }).first().click();

    jobFinalApproved = true;
    requirementFinalApproved = true;
    for (const item of roleCases) {
      if (item.type === "profile") finalApprovedRoles.add(item.roleKey);
    }

    await page.goto("/admin/jobs?_preview=1", { waitUntil: "domcontentloaded" });
    await expect(page.getByRole("heading", { name: "Jobs Management" })).toBeVisible();
    await expect(page.locator("tr", { hasText: "Senior Frontend Engineer" })).toContainText("Active");

    await page.goto("/admin/leads?_preview=1", { waitUntil: "domcontentloaded" });
    await expect(page.getByRole("heading", { name: "Leads Management" })).toBeVisible();
    await expect(page.locator("tr", { hasText: "Wedding Photography Requirement" })).toContainText("ACTIVE");
    await expect(page.getByRole("link", { name: "View" }).first()).toBeVisible();

    await page.goto("/admin/company?_preview=1", { waitUntil: "domcontentloaded" });
    await expect(page.getByRole("heading", { name: "Company Management" })).toBeVisible();
    const companyRow = page.locator("tr", { hasText: "Nxtgauge Labs Pvt Ltd" }).first();
    await expect(companyRow).toContainText("Active");
    await companyRow.locator("button").first().click();
    await companyRow.getByRole("button", { name: "View Company" }).click();
    await expect(page.getByRole("button", { name: "Back to List" })).toBeVisible();

    await page.goto("/admin/users?_preview=1", { waitUntil: "domcontentloaded" });
    await expect(page.getByRole("heading", { name: "Users Management" })).toBeVisible();
    for (const item of roleCases) {
      await expect(page.getByText(toTitle(item.roleKey), { exact: false }).first()).toBeVisible();
    }

    for (const item of roleCases.filter((row) => row.route)) {
      await page.goto(`${item.route}?_preview=1`, { waitUntil: "domcontentloaded" });
      await expect(page.getByText(item.applicantName.split(" ")[0], { exact: false }).first()).toBeVisible();
      const tableRow = page.locator("tr", { hasText: item.applicantName.split(" ")[0] }).first();
      await tableRow.locator("button").first().click();
      await expect(page.getByRole("link", { name: item.viewLabel || "View Profile" }).first()).toBeVisible();
    }
  });
});
