import { headers } from "next/headers";
import { resolveTenantFromHostname } from "@/core/tenant/resolve-tenant";
import {
  TenantResolutionError,
  type TenantContext,
} from "@/core/tenant/types";
import { classifyHostname } from "@/core/tenant/classify-hostname";
import {
  getPlatformRootDomain,
  hostnameWithoutPort,
  isIpAddress,
  normalizeHostname,
} from "@/core/config/domains";

/**
 * Host the browser actually used for this request.
 * Prefers LAN IPs so public studio links stay phone-reachable even when
 * APP_URL / AUTH_URL are configured as localhost.
 */
export async function getRequestHostname(): Promise<string> {
  const h = await headers();
  const candidates = [
    h.get("x-archi-hostname"),
    h.get("x-forwarded-host"),
    h.get("host"),
  ]
    .flatMap((value) => {
      if (!value) return [];
      // x-forwarded-host may be a comma-separated list
      return value.split(",").map((part) => part.trim()).filter(Boolean);
    })
    .map(normalizeHostname);

  const ipHost = candidates.find((candidate) =>
    isIpAddress(hostnameWithoutPort(candidate)),
  );
  if (ipHost) return ipHost;

  return candidates[0] ?? "localhost:3000";
}

/**
 * Resolve trusted TenantContext for tenant website requests.
 * Supports:
 * - {slug}.localhost / {slug}.archi.com
 * - custom verified domains
 * - LAN path preview /studio/{slug} via x-archi-tenant-slug header
 */
export async function resolveRequestTenant(): Promise<
  | { ok: true; context: TenantContext }
  | {
      ok: false;
      code: TenantResolutionError["code"];
      message: string;
    }
> {
  const h = await headers();
  const hostname = await getRequestHostname();
  const kind = classifyHostname(hostname);
  const slugHeader = h.get("x-archi-tenant-slug")?.trim().toLowerCase() || null;
  const refererSlug = studioSlugFromRefererHeader(h.get("referer"));
  const slug = slugHeader || refererSlug;

  // Path preview on platform/IP hosts: proxy or client sets x-archi-tenant-slug
  if (slug) {
    try {
      const context = await resolveTenantFromHostname(
        `${slug}.${getPlatformRootDomain()}`,
      );
      return { ok: true, context: { ...context, hostname } };
    } catch (error) {
      if (error instanceof TenantResolutionError) {
        return { ok: false, code: error.code, message: error.message };
      }
      throw error;
    }
  }

  if (
    kind.kind === "platform" ||
    kind.kind === "app" ||
    kind.kind === "admin" ||
    kind.kind === "api"
  ) {
    return {
      ok: false,
      code: "INVALID_HOST",
      message: "Not a tenant host",
    };
  }

  try {
    if (kind.kind === "tenant_subdomain") {
      const context = await resolveTenantFromHostname(
        `${kind.slug}.${getPlatformRootDomain()}`,
      );
      return { ok: true, context: { ...context, hostname } };
    }

    const context = await resolveTenantFromHostname(hostname);
    return { ok: true, context };
  } catch (error) {
    if (error instanceof TenantResolutionError) {
      return { ok: false, code: error.code, message: error.message };
    }
    throw error;
  }
}

function studioSlugFromRefererHeader(referer: string | null): string | null {
  if (!referer) return null;
  try {
    const path = new URL(referer).pathname;
    const match = path.match(/^\/studio\/([^/]+)/);
    const slug = match?.[1]?.toLowerCase() ?? null;
    if (!slug || slug.includes(".")) return null;
    return slug;
  } catch {
    return null;
  }
}
