"use client";

import { useEffect, useMemo, useState } from "react";
import Link from "next/link";
import {
  fetchCoursewareRuntimeConfig,
  normalizeCoursewareRuntimeConfig,
  type ResolvedCoursewareRuntimeConfig,
} from "~/lib/courseware-runtime";

type PageProps = {
  params: { service: string };
  searchParams?: Record<string, string | string[] | undefined>;
};

type ServiceDescriptor = {
  label: string;
  resolveUrl: (runtime: ResolvedCoursewareRuntimeConfig) => string | null;
  allowIframe: boolean;
};

function coerceSearchParam(
  value: string | string[] | undefined,
): string | undefined {
  if (Array.isArray(value)) return value[0];
  return value;
}

function resolveDescriptor(serviceId: string): ServiceDescriptor | null {
  switch (serviceId) {
    case "open-webui":
      return {
        label: "Open WebUI",
        resolveUrl: (runtime) => runtime.services["open-webui"],
        allowIframe: false,
      };
    case "promptfoo":
      return {
        label: "Promptfoo",
        resolveUrl: (runtime) => runtime.services.promptfoo,
        allowIframe: false,
      };
    case "chunkviz":
      return {
        label: "ChunkViz",
        resolveUrl: (runtime) => runtime.services.chunkviz,
        allowIframe: false,
      };
    case "embedding-atlas":
      return {
        label: "Embedding Atlas",
        resolveUrl: (runtime) => runtime.services["embedding-atlas"],
        allowIframe: false,
      };
    case "unsloth":
      return {
        label: "Unsloth Studio",
        resolveUrl: (runtime) => runtime.services.unsloth,
        allowIframe: false,
      };
    case "wetty":
      return {
        label: "Lab 3 Terminal",
        resolveUrl: (runtime) => runtime.lab3TerminalUrl,
        allowIframe: true,
      };
    case "netron":
      return {
        label: "Netron",
        resolveUrl: (runtime) => runtime.lab1NetronUrl,
        allowIframe: false,
      };
    default:
      return null;
  }
}

export default function ServiceAppPage({ params, searchParams }: PageProps) {
  const serviceId = params.service?.trim() ?? "";
  const descriptor = useMemo(
    () => resolveDescriptor(serviceId),
    [serviceId],
  );
  const embedParam = coerceSearchParam(searchParams?.embed);
  const embed = embedParam === "1" || embedParam === "true";

  const [runtime, setRuntime] = useState<ResolvedCoursewareRuntimeConfig>(() =>
    normalizeCoursewareRuntimeConfig(),
  );
  const [isRuntimeResolved, setIsRuntimeResolved] = useState(false);

  useEffect(() => {
    let isCancelled = false;
    void fetchCoursewareRuntimeConfig()
      .then((nextRuntime) => {
        if (isCancelled) return;
        setRuntime(nextRuntime);
      })
      .catch(() => {
        if (isCancelled) return;
        setRuntime(normalizeCoursewareRuntimeConfig());
      })
      .finally(() => {
        if (isCancelled) return;
        setIsRuntimeResolved(true);
      });

    return () => {
      isCancelled = true;
    };
  }, []);

  if (!descriptor) {
    return (
      <main className="mx-auto w-full max-w-5xl px-6 py-10">
        <h1 className="text-2xl font-semibold text-[#004E78]">
          Unknown tool
        </h1>
        <p className="mt-2 text-slate-700">
          The tool <code>{serviceId}</code> is not configured.
        </p>
        <div className="mt-6">
          <Link href="/apps" className="text-[#004E78] hover:text-[#F89C27]">
            Back to tools
          </Link>
        </div>
      </main>
    );
  }

  const resolvedUrl = descriptor.resolveUrl(runtime);
  const shouldEmbed = embed && descriptor.allowIframe;

  if (!isRuntimeResolved) {
    return (
      <main className="mx-auto w-full max-w-5xl px-6 py-10">
        <h1 className="text-2xl font-semibold text-[#004E78]">
          Loading {descriptor.label}…
        </h1>
      </main>
    );
  }

  if (!resolvedUrl) {
    return (
      <main className="mx-auto w-full max-w-5xl px-6 py-10">
        <h1 className="text-2xl font-semibold text-[#004E78]">
          {descriptor.label} is unavailable
        </h1>
        <p className="mt-2 text-slate-700">
          The runtime config did not provide a URL for this service.
        </p>
        <div className="mt-6">
          <Link href="/apps" className="text-[#004E78] hover:text-[#F89C27]">
            Back to tools
          </Link>
        </div>
      </main>
    );
  }

  if (!shouldEmbed) {
    // Full-screen navigation: replace the current page so the URL remains a single origin path.
    // (Embedding is reserved for services that explicitly allow iframes, like WeTTY.)
    if (typeof window !== "undefined") {
      window.location.replace(resolvedUrl);
    }

    return (
      <main className="mx-auto w-full max-w-5xl px-6 py-10">
        <h1 className="text-2xl font-semibold text-[#004E78]">
          Opening {descriptor.label}…
        </h1>
        <p className="mt-3 text-slate-700">
          If you are not redirected automatically, open{" "}
          <a
            className="text-[#004E78] underline hover:text-[#F89C27]"
            href={resolvedUrl}
          >
            {resolvedUrl}
          </a>
          .
        </p>
        <div className="mt-6">
          <Link href="/apps" className="text-[#004E78] hover:text-[#F89C27]">
            Back to tools
          </Link>
        </div>
      </main>
    );
  }

  return (
    <div className="h-[calc(100vh-0px)] w-full">
      <iframe
        title={descriptor.label}
        src={resolvedUrl}
        className="h-screen w-full border-0"
        allow="clipboard-read; clipboard-write"
      />
    </div>
  );
}

