import { getSessionUser, canMutate } from "@/lib/session";
import { getTranslations, getFormatter } from "next-intl/server";
import { redirect } from "next/navigation";
import { listTenants } from "@/lib/k8s";
import { listActiveTenantRequestsByOrgId } from "@/lib/db";
import {
  listVisibleTenants,
  canSeeInflightRequests,
  isUserScoped,
} from "@/lib/visibility";
import { personalAccountAtCapacity } from "@/lib/personal-org";
import { Card, CardHeader } from "@/components/ui/card";
import { StatusBadge } from "@/components/ui/status-badge";
import { OnboardingFlow } from "@/components/onboarding/onboarding-flow";
import { ProvisioningStatus } from "@/components/onboarding/provisioning-status";
import { formatDateTime } from "@/lib/format";
import Link from "next/link";

export default async function DashboardPage() {
  const user = await getSessionUser();
  if (!user) redirect("/login");

  const t = await getTranslations("dashboard");
  const tAdmin = await getTranslations("admin");
  const f = await getFormatter();

  const allTenants = await listTenants();

  // Platform users see overview of all tenants — unchanged from pre-Slice-3.
  if (user.isPlatform) {
    const phaseCount = allTenants.reduce<Record<string, number>>((acc, t) => {
      const phase = t.status?.phase ?? "Pending";
      acc[phase] = (acc[phase] || 0) + 1;
      return acc;
    }, {});

    return (
      <div>
        <div className="mb-8 animate-in">
          <h1 className="font-display text-2xl font-semibold accent-rule mb-2">
            {t("title")}
          </h1>
          <p className="text-text-secondary text-sm mt-4">
            {t("welcome", { name: user.name || user.email })}
          </p>
        </div>

        <Link
          href="/admin"
          className="inline-flex items-center gap-1.5 mb-6 text-xs font-medium text-accent hover:text-accent-dim transition-colors animate-in animate-in-delay-1"
        >
          <span>→</span> {tAdmin("title")}
        </Link>

        {/* Summary cards */}
        <div className="grid gap-5 sm:grid-cols-2 lg:grid-cols-4 mb-8 animate-in animate-in-delay-1">
          <Card>
            <CardHeader>{tAdmin("allTenants")}</CardHeader>
            <span className="font-display text-3xl font-semibold text-text-primary tabular-nums">
              {allTenants.length}
            </span>
          </Card>
          {Object.entries(phaseCount).map(([phase, count]) => (
            <Card key={phase}>
              <CardHeader>{phase}</CardHeader>
              <div className="flex items-center gap-2">
                <span className="font-display text-3xl font-semibold text-text-primary tabular-nums">
                  {count}
                </span>
                <StatusBadge phase={phase} />
              </div>
            </Card>
          ))}
        </div>

        {/* Tenant table */}
        {allTenants.length > 0 && (
          <div className="bg-surface-1 border border-border rounded-xl overflow-hidden animate-in animate-in-delay-2">
            <div className="overflow-x-auto">
              <table className="w-full text-sm">
                <thead>
                  <tr className="border-b border-border text-left">
                    <th className="px-5 py-3 text-xs font-semibold uppercase tracking-wider text-text-muted">
                      {tAdmin("name")}
                    </th>
                    <th className="px-5 py-3 text-xs font-semibold uppercase tracking-wider text-text-muted">
                      {tAdmin("phase")}
                    </th>
                    <th className="px-5 py-3 text-xs font-semibold uppercase tracking-wider text-text-muted">
                      {tAdmin("packages")}
                    </th>
                    <th className="px-5 py-3 text-xs font-semibold uppercase tracking-wider text-text-muted">
                      {tAdmin("created")}
                    </th>
                    <th className="px-5 py-3" />
                  </tr>
                </thead>
                <tbody>
                  {allTenants.map((tenant) => (
                    <tr
                      key={tenant.metadata.name}
                      className="border-b border-border last:border-0 hover:bg-surface-2/50 transition-colors"
                    >
                      <td className="px-5 py-3">
                        <div className="font-mono text-xs text-accent">
                          {tenant.metadata.name}
                        </div>
                        {tenant.spec.displayName && (
                          <div className="text-xs text-text-secondary">
                            {tenant.spec.displayName}
                          </div>
                        )}
                      </td>
                      <td className="px-5 py-3">
                        <StatusBadge phase={tenant.status?.phase ?? "Pending"} />
                      </td>
                      <td className="px-5 py-3 text-xs text-text-secondary font-mono">
                        {tenant.spec.packages?.join(", ") || "—"}
                      </td>
                      <td className="px-5 py-3 text-xs text-text-muted tabular-nums">
                        {formatDateTime(tenant.metadata.creationTimestamp, f)}
                      </td>
                      <td className="px-5 py-3 text-right">
                        <Link
                          href={`/tenants/${tenant.metadata.name}`}
                          className="text-xs font-medium text-accent hover:text-accent-dim transition-colors"
                        >
                          {t("manage")} →
                        </Link>
                      </td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
          </div>
        )}
      </div>
    );
  }

  // ---------------------------------------------------------------------
  // Customer view (Slice 3 multi-tenant + Slice 6 visibility scoping)
  // ---------------------------------------------------------------------

  // Slice 6: orgTenants becomes "visible tenants for this user". For an
  // owner that's all of the org's tenants; for a `user`-role member
  // it's only the tenants they've been assigned to via
  // tenant_user_assignments. The dashboard renders fewer cards in the
  // user-role case but otherwise uses the same template.
  const orgTenants = await listVisibleTenants(user, allTenants);

  // For the "no instances yet" empty state, we want to know whether
  // this user is being scoped down. A `user`-role with 0 visible
  // tenants gets a different message than an owner with 0 tenants
  // (the user might just need an assignment; the owner needs to
  // create one).
  const userScoped = isUserScoped(user);

  // Pending/in-flight requests are only shown to roles that can act on
  // them. `user`-role customers see no request cards.
  const orgRequests = canSeeInflightRequests(user)
    ? await listActiveTenantRequestsByOrgId(user.orgId)
    : [];

  // Pending requests that don't yet have a tenant CR. Once the CR
  // exists, the tenant card carries the live phase, so a separate
  // "request" card would just duplicate it. We compare against
  // *all* org tenants here (not just visible ones) — otherwise a
  // request whose tenant is invisible to the caller would erroneously
  // show as in-flight.
  const orgScopedTenants = allTenants.filter(
    (t) => t.metadata.labels?.["pieced.ch/zitadel-org-id"] === user.orgId
  );
  const inflightRequests = orgRequests.filter(
    (r) => !r.tenantName || !orgScopedTenants.some((t) => t.metadata.name === r.tenantName)
  );

  // Slice 5: only owners (and platform users, who'd typically be using
  // the admin panel anyway) see the "Create new instance" link. A
  // `user`-role member sees the dashboard but not the create flow —
  // they need to ask an owner.
  //
  // Bug 5: personal accounts are 1-instance by design. Once a personal
  // account has either an active tenant OR an in-flight request, the
  // create button must disappear. The matching server-side guard is
  // in `/api/onboarding` so direct POSTs are also rejected.
  const personalAtCapacity = personalAccountAtCapacity(
    user.isPersonal,
    orgScopedTenants.length,
    inflightRequests.length
  );
  const canCreate = canMutate(user) && !personalAtCapacity;

  // First-time / no-visibility branch.
  //
  // Three sub-cases:
  //   1. owner / platform with 0 tenants and 0 requests → show wizard.
  //   2. owner / platform with 0 visibility but the org HAS tenants →
  //      shouldn't happen (owners see all org tenants). Defensive
  //      fall-through to the wizard.
  //   3. user-role with 0 visible tenants → show "ask your owner"
  //      message, with copy distinguishing whether the org has any
  //      tenants at all.
  if (orgTenants.length === 0 && inflightRequests.length === 0) {
    if (userScoped) {
      // Slice 6 empty state for `user` role. The org might or might
      // not have tenants — either way this user has none assigned.
      // The two messages are subtly different: "no instances exist"
      // means owner needs to create one; "you're not assigned" means
      // owner needs to grant access.
      const orgHasTenants = orgScopedTenants.length > 0;
      return (
        <div>
          <div className="mb-8 animate-in">
            <h1 className="font-display text-2xl font-semibold accent-rule mb-2">
              {t("title")}
            </h1>
            <p className="text-text-secondary text-sm mt-4">
              {t("welcome", { name: user.name || user.email })}
            </p>
          </div>
          <Card className="animate-in animate-in-delay-1">
            <div className="text-center py-6">
              <h2 className="font-display text-base font-semibold text-text-primary mb-2">
                {orgHasTenants
                  ? t("noAssignmentsTitle")
                  : t("noInstancesYetTitle")}
              </h2>
              <p className="text-sm text-text-secondary max-w-sm mx-auto">
                {orgHasTenants
                  ? t("noAssignmentsDescription")
                  : t("noInstancesYetDescription")}
              </p>
            </div>
          </Card>
        </div>
      );
    }

    if (!canCreate) {
      // Belt-and-braces: any role that's neither owner-with-create nor
      // user-scope ends up here (e.g. weird cases like a session with
      // no roles at all). Same generic message as before.
      return (
        <div>
          <div className="mb-8 animate-in">
            <h1 className="font-display text-2xl font-semibold accent-rule mb-2">
              {t("title")}
            </h1>
            <p className="text-text-secondary text-sm mt-4">
              {t("welcome", { name: user.name || user.email })}
            </p>
          </div>
          <Card className="animate-in animate-in-delay-1">
            <p className="text-sm text-text-secondary text-center py-6">
              {t("noAccessNoInstances")}
            </p>
          </Card>
        </div>
      );
    }

    return (
      <div>
        <div className="mb-8 animate-in">
          <h1 className="font-display text-2xl font-semibold accent-rule mb-2">
            {t("title")}
          </h1>
          <p className="text-text-secondary text-sm mt-4">
            {t("welcome", { name: user.name || user.email })}
          </p>
        </div>

        <div className="animate-in animate-in-delay-1">
          <OnboardingFlow
            orgName={user.orgName}
            userName={user.name}
            userEmail={user.email}
          />
        </div>
      </div>
    );
  }

  // Returning customer: list of tenants + in-flight requests, plus
  // a button to add another instance (owners only).
  return (
    <div>
      <div className="mb-8 animate-in flex items-start justify-between gap-4">
        <div>
          <h1 className="font-display text-2xl font-semibold accent-rule mb-2">
            {t("title")}
          </h1>
          <p className="text-text-secondary text-sm mt-4">
            {t("welcome", { name: user.name || user.email })}
          </p>
        </div>

        {canCreate && (
          <Link
            href="/dashboard/new"
            className="shrink-0 inline-flex items-center gap-1.5 py-2 px-4 bg-accent text-white text-xs font-medium rounded-lg hover:bg-accent-dim transition-colors"
          >
            <span>+</span> {t("createInstance")}
          </Link>
        )}
      </div>

      {/* In-flight (pending/approved/provisioning/rejected) requests */}
      {inflightRequests.length > 0 && (
        <div className="mb-8 animate-in animate-in-delay-1">
          <h2 className="text-xs font-semibold uppercase tracking-wider text-text-muted mb-3">
            {t("inflightRequests")}
          </h2>
          <div className="space-y-3">
            {inflightRequests.map((r) => (
              <ProvisioningStatus
                key={r.id}
                requestId={r.id}
                canAct={canMutate(user)}
              />
            ))}
          </div>
        </div>
      )}

      {/* Active tenants */}
      {orgTenants.length > 0 && (
        <div className="animate-in animate-in-delay-2">
          <h2 className="text-xs font-semibold uppercase tracking-wider text-text-muted mb-3">
            {t("instances")}
          </h2>
          <div className="grid gap-4 md:grid-cols-2">
            {orgTenants.map((tenant) => (
              <Link
                key={tenant.metadata.name}
                href={`/tenants/${tenant.metadata.name}`}
                className="block group"
              >
                <Card className="h-full hover:border-accent/40 transition-colors">
                  <div className="flex items-start justify-between gap-3 mb-3">
                    <div className="min-w-0">
                      <div className="text-sm font-semibold text-text-primary truncate">
                        {tenant.spec.displayName || tenant.metadata.name}
                      </div>
                      <div className="font-mono text-xs text-text-muted truncate mt-0.5">
                        {tenant.metadata.name}
                      </div>
                    </div>
                    <StatusBadge phase={tenant.status?.phase ?? "Pending"} />
                  </div>

                  {tenant.spec.agentName && (
                    <div className="text-xs text-text-secondary mb-2">
                      {tenant.spec.agentName}
                    </div>
                  )}

                  {tenant.spec.packages && tenant.spec.packages.length > 0 && (
                    <div className="flex flex-wrap gap-1.5 mb-3">
                      {tenant.spec.packages.slice(0, 4).map((pkg) => (
                        <span
                          key={pkg}
                          className="text-xs font-mono bg-accent/10 text-accent border border-accent/20 rounded-full px-2 py-0.5"
                        >
                          {pkg}
                        </span>
                      ))}
                      {tenant.spec.packages.length > 4 && (
                        <span className="text-xs text-text-muted">
                          +{tenant.spec.packages.length - 4}
                        </span>
                      )}
                    </div>
                  )}

                  <div className="text-xs font-medium text-accent group-hover:text-accent-dim transition-colors">
                    {t("manage")} →
                  </div>
                </Card>
              </Link>
            ))}
          </div>
        </div>
      )}
    </div>
  );
}
