import { and, eq } from "drizzle-orm";
import { getDb } from "@/core/db/client";
import { domains, tenants } from "@/core/db/schema";
import { classifyHostname } from "@/core/tenant/classify-hostname";
import {
  TenantResolutionError,
  type TenantContext,
} from "@/core/tenant/types";
import { normalizeHostname } from "@/core/config/domains";

/**
 * Authoritative tenant resolution service.
 * All hostname → tenant mapping MUST go through this module.
 *
 * CRITICAL: Never fall back to a default tenant when resolution fails.
 */
export async function resolveTenantFromHostname(
  rawHostname: string,
): Promise<TenantContext> {
  const hostname = normalizeHostname(rawHostname);
  const hostKind = classifyHostname(hostname);

  if (
    hostKind.kind === "platform" ||
    hostKind.kind === "app" ||
    hostKind.kind === "admin" ||
    hostKind.kind === "api"
  ) {
    throw new TenantResolutionError(
      "INVALID_HOST",
      "Hostname is a platform host, not a tenant website",
    );
  }

  if (hostKind.kind === "unknown") {
    throw new TenantResolutionError("NOT_FOUND", "Unknown hostname");
  }

  const db = getDb();

  if (hostKind.kind === "tenant_subdomain") {
    const [tenant] = await db
      .select()
      .from(tenants)
      .where(eq(tenants.slug, hostKind.slug))
      .limit(1);

    if (!tenant) {
      throw new TenantResolutionError("NOT_FOUND", "Tenant not found");
    }

    assertTenantPubliclyResolvable(tenant.status);

    return {
      tenantId: tenant.id,
      tenantSlug: tenant.slug,
      studioName: tenant.studioName,
      status: tenant.status,
      hostname,
      domainId: null,
      domainType: "subdomain",
      isPrimaryDomain: true,
    };
  }

  // Custom domain — only verified domains become active
  const [row] = await db
    .select({
      domainId: domains.id,
      domainType: domains.type,
      isPrimary: domains.isPrimary,
      verificationStatus: domains.verificationStatus,
      tenantId: tenants.id,
      tenantSlug: tenants.slug,
      studioName: tenants.studioName,
      status: tenants.status,
    })
    .from(domains)
    .innerJoin(tenants, eq(domains.tenantId, tenants.id))
    .where(
      and(
        eq(domains.normalizedDomain, hostKind.domain),
        eq(domains.verificationStatus, "verified"),
      ),
    )
    .limit(1);

  if (!row) {
    throw new TenantResolutionError(
      "NOT_FOUND",
      "Custom domain not verified or not found",
    );
  }

  assertTenantPubliclyResolvable(row.status);

  return {
    tenantId: row.tenantId,
    tenantSlug: row.tenantSlug,
    studioName: row.studioName,
    status: row.status,
    hostname,
    domainId: row.domainId,
    domainType: "custom",
    isPrimaryDomain: row.isPrimary,
  };
}

function assertTenantPubliclyResolvable(
  status: string,
): asserts status is "active" {
  if (status === "suspended") {
    throw new TenantResolutionError("SUSPENDED", "Tenant is suspended");
  }
  if (status !== "active") {
    throw new TenantResolutionError("INACTIVE", "Tenant is not active");
  }
}
