import Link from "next/link";
import { notFound } from "next/navigation";
import { getTranslations } from "next-intl/server";
import { ArrowLeft, Pencil } from "lucide-react";
import { requireSession } from "@/server/auth";
import { dbForTenant } from "@/server/db";
import { hasPermission, requirePermission } from "@/server/rbac";
import { Button } from "@/components/ui/button";
import { Pill } from "@/components/mockup-ui";
import {
  PolicyReadView,
  POLICY_STATUS_LABEL,
  POLICY_STATUS_TONE,
  POLICY_TYPE_LABEL,
} from "@/components/policy-modals";
import { PolicyRegisterView } from "@/components/policy-registers";
import { GenericRegisterView, type RegisterColumn } from "@/components/generic-register";

const REGISTER_CODES = new Set(["CRYPTO", "RISKMATRIX", "CLASSIFICATION", "HANDBUCH"]);
// Aus Vorlagen-Markdown gerenderte Dokumente (bearbeitbar über den Editor)
const TEMPLATE_TYPES = new Set(["LEITLINIE", "RICHTLINIE", "VERFAHREN"]);

export default async function PolicyDetailPage({
  params,
}: {
  params: Promise<{ code: string }>;
}) {
  const session = await requireSession();
  requirePermission(session, "policy:read");
  const t = await getTranslations("policies");
  const db = dbForTenant(session.user.tenantId);
  const { code } = await params;

  const doc = await db.policyDocument.findFirst({ where: { code: decodeURIComponent(code) } });
  if (!doc) notFound();

  const canWrite = hasPermission(session, "policy:write");
  const isRegister = REGISTER_CODES.has(doc.code);
  // Generisches verwaltetes Register (WP3.0): editierbare Zeilen nach Pflichtspalten.
  const genericReg = doc.type === "REGISTER" && !isRegister
    ? await db.managedRegister.findFirst({ where: { code: doc.code } })
    : null;

  let content: React.ReactNode;
  if (genericReg) {
    const [rows, allAssets] = await Promise.all([
      db.registerRow.findMany({ where: { registerId: genericReg.id }, orderBy: { orderIdx: "asc" } }),
      db.asset.findMany({ select: { id: true, name: true, type: true }, orderBy: { name: "asc" } }),
    ]);
    content = (
      <GenericRegisterView
        register={{
          code: genericReg.code, title: genericReg.title, description: genericReg.description,
          columns: (genericReg.columns as unknown as RegisterColumn[]) ?? [],
          supplierLink: genericReg.supplierLink, assetLink: genericReg.assetLink,
        }}
        rows={rows.map((r) => ({ id: r.id, values: (r.values as Record<string, string>) ?? {}, supplierRef: r.supplierRef, assetRef: r.assetRef }))}
        canWrite={canWrite}
        suppliers={allAssets.filter((a) => a.type === "SUPPLIER" || a.type === "IT_SERVICE").map((a) => ({ id: a.id, name: a.name }))}
        assets={allAssets.map((a) => ({ id: a.id, name: a.name }))}
      />
    );
  } else if (isRegister) {
    const data =
      doc.code === "CRYPTO"
        ? { crypto: await db.cryptoEntry.findMany({ orderBy: { orderIdx: "asc" } }) }
        : doc.code === "CLASSIFICATION"
          ? {
              classes: await db.classificationClass.findMany({ orderBy: { orderIdx: "asc" } }),
              aspects: await db.handlingAspect.findMany({ orderBy: { orderIdx: "asc" } }),
              rules: await db.handlingRule.findMany(),
            }
          : doc.code === "RISKMATRIX"
            ? {
                riskClasses: await db.riskMatrixClass.findMany({ orderBy: { orderIdx: "asc" } }),
                ewLevels: await db.riskEwLevel.findMany({ orderBy: { level: "asc" } }),
                damage: await db.riskDamageDimension.findMany({ orderBy: { orderIdx: "asc" } }),
              }
            : { handbook: await db.handbookTopic.findMany({ orderBy: { orderIdx: "asc" } }), variables: await db.policyVariable.findMany({ orderBy: { orderIdx: "asc" } }) };
    content = <PolicyRegisterView doc={doc} data={data} canWrite={canWrite} />;
  } else {
    const [variables, reqs] = await Promise.all([
      db.policyVariable.findMany({ orderBy: { orderIdx: "asc" } }),
      db.policyRequirement.findMany({ where: { policyCode: doc.code, archivedAt: null } }),
    ]);
    const controls = [...new Set(reqs.map((r) => r.control))].sort();
    const relatedVas = [...new Set(reqs.flatMap((r) => r.vaCodes))].sort();
    content = <PolicyReadView data={{ doc, variables, controls, relatedVas }} />;
  }

  const showEdit = canWrite && TEMPLATE_TYPES.has(doc.type);

  return (
    <main className="flex-1 p-6">
      <Link href="/policies" className="inline-flex items-center gap-1.5 text-[12.5px] font-semibold text-muted-foreground hover:text-foreground">
        <ArrowLeft className="size-4" /> {t("backToLibrary")}
      </Link>

      <div className="mt-3 mb-5 flex flex-wrap items-start justify-between gap-3">
        <div>
          <div className="flex flex-wrap items-center gap-2">
            <h1 className="font-heading text-2xl font-bold">{doc.code} · {doc.title}</h1>
            <Pill tone={POLICY_STATUS_TONE[doc.status]}>{POLICY_STATUS_LABEL[doc.status]}</Pill>
          </div>
          <p className="mt-0.5 text-[12.5px] text-muted-foreground">
            {POLICY_TYPE_LABEL[doc.type]} · v{doc.version}
            {(isRegister || genericReg) && canWrite ? ` · ${t("editableInline")}` : ""}
          </p>
        </div>
        {showEdit && (
          <Button nativeButton={false} render={<Link href={`/policies/${doc.code}/edit`} />}>
            <Pencil className="size-4" /> {t("edit")}
          </Button>
        )}
      </div>

      <div className="shadow-card rounded-2xl border bg-card p-6">{content}</div>
    </main>
  );
}
