import { afterEach, beforeEach, describe, expect, it, jest } from "@jest/globals";
import { RouterLinkStub, flushPromises, mount, shallowMount } from "@vue/test-utils";

import PlatformSection from "../../../frontend/src/components/PlatformSection.vue";
import { auth } from "../../../frontend/src/auth.js";
import { homepageContentForMode, normalizeHomepageFocus } from "../../../frontend/src/data/homepageContent.js";
import HomeView from "../../../frontend/src/views/HomeView.vue";

let mockRoute = { meta: { homepageFocus: "sdet" }, params: {}, query: {} };

jest.mock("vue-router", () => ({
  RouterLink: {
    name: "RouterLink",
    props: ["to"],
    template: "<a :href=\"typeof to === 'string' ? to : '#'\" @click=\"$emit('click', $event)\"><slot /></a>",
  },
  useRoute: () => mockRoute,
}), { virtual: true });

function resetAuth() {
  auth.ready = true;
  auth.enabled = true;
  auth.authenticated = false;
  auth.username = "";
  auth.email = "";
  auth.emailVerified = null;
  auth.groups = [];
  auth.resetUrl = "https://sso.example.dev/reset";
}

describe("HomeView", () => {
  beforeEach(() => {
    mockRoute = { meta: { homepageFocus: "sdet" }, params: {}, query: {} };
    global.fetch = jest.fn(async (resource) => {
      const url = typeof resource === "string" ? resource : resource?.url || "";
      if (url.includes("/api/account/member-state")) {
        return new Response(
          JSON.stringify({
            status: "ready",
            onboarding_url: "/onboarding?code=ada~CODE",
            dashboard_url: "/apps",
            account_url: "/account",
          }),
          { status: 200, headers: { "content-type": "application/json" } },
        );
      }
      return new Response("{}", { status: 200, headers: { "content-type": "application/json" } });
    });
  });

  afterEach(() => {
    resetAuth();
    jest.restoreAllMocks();
  });

  it("renders the professional homepage while logged out", () => {
    resetAuth();
    const wrapper = mount(HomeView, {
      global: {
        stubs: {
          RouterLink: RouterLinkStub,
          PlatformSection: true,
        },
      },
      props: {
        labStatus: {
          connected: true,
          atlas: { up: true, known: true },
          active_service: { known: true, label: "Nextcloud", url: "https://cloud.example.dev", window: "15m" },
          dedicated_hosts: {
            known: true,
            up: true,
            up_count: 2,
            total: 2,
            hosts: [
              { label: "Database node", known: true, up: true },
              { label: "Jumphost", known: true, up: true },
            ],
          },
          checked_at: 1000,
        },
        loading: false,
        error: "",
      },
    });

    expect(wrapper.text()).toContain("Brad Stein");
    expect(wrapper.text()).toContain("Senior SDET / DevOps Automation Engineer");
    expect(wrapper.text()).toContain("Discuss a Project");
    expect(wrapper.text()).toContain("View Résumé");
    expect(wrapper.text()).toContain("Explore the Live Platform");
    expect(wrapper.text()).toContain("Quality Systems I Can Take From Zero to Reliable");
    expect(wrapper.text()).toContain("Testing, Automation, and Platform Work");
    expect(wrapper.text()).toContain("Atlas operator tools");
    expect(wrapper.text()).toContain("Cassandra");
    expect(wrapper.text()).not.toContain("TaskWatcher");
    expect(wrapper.text()).toContain("family, friends, and the lucky few");
    expect(wrapper.text()).toContain("Register");
    expect(wrapper.text()).toContain("Request Lab Access");
    expect(wrapper.find("[aria-label='Keycloak: Use one account to sign in across bstein.dev.']").exists()).toBe(true);
    expect(wrapper.find("[title='Nextcloud: Keep files, photos, office docs, and personal cloud data in sync.']").exists()).toBe(true);
    expect(wrapper.find("a[href='https://bstein.dev/ai/chat']").exists()).toBe(true);
    expect(wrapper.find("a[href='https://bstein.dev/monero']").exists()).toBe(true);
    expect(wrapper.find("a[href='https://chat.ai.bstein.dev']").exists()).toBe(false);
    expect(wrapper.find("a[href='https://monero.bstein.dev:443']").exists()).toBe(false);
    expect(wrapper.find("a[href='/ai/chat']").exists()).toBe(false);
    expect(wrapper.find("a[href='/monero']").exists()).toBe(false);
    expect(wrapper.text()).not.toContain("Existing registration, verification, onboarding");
    expect(wrapper.text()).not.toContain("Looking for hosted services or an existing Titan Lab account");
    expect(wrapper.find("a[href^='mailto:brad@bstein.dev']").exists()).toBe(true);
    expect(wrapper.findComponent(PlatformSection).exists()).toBe(true);
    expect(wrapper.text()).toContain("Atlas cluster");
    expect(wrapper.text()).toContain("Most requested service");
    expect(wrapper.text()).toContain("Nextcloud");
    expect(wrapper.text()).toContain("Outpost hosts");
    expect(wrapper.text()).toContain("2 of 2 online");
    expect(wrapper.text()).toContain("Database machine");
    expect(wrapper.text()).toContain("Jumphost");
    expect(wrapper.text()).toContain("Responding");
  });

  it("shows a calm fallback when public status is unavailable", () => {
    resetAuth();
    const wrapper = mount(HomeView, {
      global: {
        stubs: {
          RouterLink: RouterLinkStub,
          PlatformSection: true,
        },
      },
      props: {
        labStatus: null,
        loading: false,
        error: "Live data unavailable",
      },
    });

    expect(wrapper.text()).toContain("Live status is temporarily unavailable");
    expect(wrapper.text()).not.toContain("status 500");
  });

  it("shows authenticated member actions without exposing service secrets", async () => {
    resetAuth();
    auth.authenticated = true;
    auth.username = "ada";
    auth.email = "ada@example.dev";

    const wrapper = mount(HomeView, {
      global: {
        stubs: {
          RouterLink: RouterLinkStub,
          PlatformSection: true,
        },
      },
      props: {
        labStatus: { connected: true, atlas: { up: true, known: true } },
        loading: false,
        error: "",
      },
    });
    await flushPromises();

    expect(wrapper.text()).toContain("Open Services");
    expect(wrapper.text()).toContain("Account");
    expect(wrapper.text()).not.toContain("app_password");
    expect(wrapper.text()).not.toContain("mailu_app_password");
  });

  it("builds developer and SDET homepage modes", () => {
    const devops = homepageContentForMode("devops");
    const developer = homepageContentForMode("developer");
    const sdet = homepageContentForMode("sdet");

    expect(normalizeHomepageFocus("dev")).toBe("developer");
    expect(devops.summary).toContain("custom software, tooling, and infrastructure");
    expect(devops.techStack).toEqual([
      "Kubernetes",
      "Docker",
      "Linux",
      "Terraform",
      "Ansible",
      "Flux",
      "Helm",
      "Jenkins",
      "Harbor",
      "Keycloak",
      "Vault",
      "Grafana",
      "Prometheus",
      "Python",
      "Bash",
      "Pytest",
      "Selenium",
      "Playwright",
    ]);
    expect(developer.focus).toBe("developer");
    expect(developer.role).toBe("Full-Stack Platform Engineer / Senior SDET");
    expect(developer.resumeUrl).toBe("/developer/about");
    expect(developer.techStack).toContain("Vue");
    expect(developer.techStack.indexOf("Selenium")).toBeLessThan(developer.techStack.indexOf("Playwright"));
    expect(developer.workSection.heading).toBe("Product and Platform Showcase");
    expect(developer.selectedWork[0].title).toBe("Cassandra");

    expect(sdet.focus).toBe("sdet");
    expect(sdet.role).toBe("Senior SDET / DevOps Automation Engineer");
    expect(sdet.resumeUrl).toBe("/about");
    expect(sdet.techStack).toContain("Selenium");
    expect(sdet.techStack.indexOf("Selenium")).toBeLessThan(sdet.techStack.indexOf("Playwright"));
    expect(sdet.capabilities[0].title).toBe("Test Automation & SDET");
    expect(sdet.selectedWork[0].title).toBe("Boeing");
  });
});

describe("PlatformSection", () => {
  it("preserves platform service, status, metric, and diagram behavior", () => {
    const wrapper = shallowMount(PlatformSection, {
      global: {
        stubs: {
          MetricRow: true,
          ServiceGrid: true,
          MermaidCard: true,
        },
      },
      props: {
        labStatus: {
          connected: true,
          atlas: { up: true, known: true },
          dedicated_hosts: {
            known: true,
            up: false,
            up_count: 1,
            total: 2,
            hosts: [
              { label: "Database node", known: true, up: true },
              { label: "Jumphost", known: true, up: false },
            ],
          },
        },
        serviceData: {
          services: [
            { name: "Nextcloud", summary: "Storage", link: "https://cloud.example.dev" },
            { name: "Monero", summary: "Node", link: "/monero", host: "monerod.crypto.svc.cluster.local:18081" },
            { name: "Mystery", summary: "Default", link: "https://default.example.dev" },
          ],
        },
        loading: true,
        error: "",
      },
    });

    expect(wrapper.vm.atlasPillClass).toBe("pill-ok");
    expect(wrapper.vm.dedicatedHostsPillClass).toBe("pill-bad");
    expect(wrapper.vm.dedicatedHostsLabel).toBe("1/2 responding");
    expect(wrapper.vm.dedicatedHostItems.map((host) => host.value)).toEqual(["Responding", "Needs attention"]);
    expect(wrapper.get(".status").text()).toBe("Loading...");
    expect(wrapper.vm.displayServices.map((service) => service.icon)).toEqual(["NC", "XM", "TL"]);
    expect(wrapper.vm.displayServices.find((service) => service.name === "Monero").host).toBe("/monero");
    expect(wrapper.vm.hardwareDiagram).toContain("Titan Lab");
    expect(wrapper.vm.hardwareDiagram).toContain("Dedicated non-cluster hosts");
    expect(wrapper.vm.networkDiagram).toContain("oauth2-proxy");
    expect(wrapper.vm.pipelineDiagram).toContain("Flux");
    expect(wrapper.text()).toContain("IaC source");
    expect(wrapper.text()).toContain("Titan Lab: Live Platform");
  });

  it("shows public status errors without raw API detail", () => {
    const wrapper = shallowMount(PlatformSection, {
      global: {
        stubs: {
          MetricRow: true,
          ServiceGrid: true,
          MermaidCard: true,
        },
      },
      props: {
        labStatus: { connected: false, atlas: { up: false, known: false } },
        serviceData: { services: [] },
        metricsData: { items: [{ label: "Custom", value: "1", note: "" }] },
        loading: false,
        error: "Live data unavailable",
      },
    });

    expect(wrapper.vm.atlasPillClass).toBe("pill-bad");
    expect(wrapper.get(".status").text()).toBe("Live data unavailable");
    expect(wrapper.vm.metricItems[0].note).toBe("");
    expect(wrapper.text()).toContain("The platform overview remains available below");
  });
});
