// =============================================================================
// WOOO AIOps - AwoooP Approval Decision
// =============================================================================
// 人工審批必須回到 Run State / Timeline，避免 Approval 成為獨立孤島。

"use client";

import { useCallback, useEffect, useMemo, useState } from "react";
import { useSearchParams } from "next/navigation";
import { useLocale, useTranslations } from "next-intl";
import {
  AlertCircle,
  ArrowLeft,
  ArrowRight,
  CheckCircle,
  Clock,
  RefreshCw,
  ShieldAlert,
  ShieldCheck,
  X,
  XCircle,
} from "lucide-react";

import { Link, useRouter } from "@/i18n/routing";
import { IncidentEvidenceHeader } from "@/components/awooop/incident-evidence-header";
import {
  AwoooPStatusChainPanel,
  type AwoooPStatusChain,
} from "@/components/awooop/status-chain";
import { cn } from "@/lib/utils";

interface RunDetail {
  run_id: string;
  project_id: string;
  agent_id: string;
  state: string;
  trace_id?: string | null;
  trigger_type?: string | null;
  trigger_ref?: string | null;
  is_shadow?: boolean | null;
  cost_usd?: number | string;
  attempt_count?: number;
  max_attempts?: number;
  error_code?: string | null;
  error_detail?: string | null;
  created_at: string;
  timeout_at?: string | null;
}

interface RemediationHistoryItem {
  incident_id?: string | null;
  mode?: string | null;
  verification_result_preview?: string | null;
  tool_count?: number | null;
  agent_id?: string | null;
  tool_name?: string | null;
  required_scope?: string | null;
  writes_incident_state?: boolean | null;
  writes_auto_repair_result?: boolean | null;
  created_at?: string | null;
}

type OwnerResponseValidationDecisionRef = {
  phase: string;
  key: string;
  contract: string;
};

interface RunRemediationHistory {
  incident_ids?: string[];
  total?: number;
  items?: RemediationHistoryItem[];
}

interface RunDetailResponse {
  run: RunDetail;
  remediation_history?: RunRemediationHistory;
  awooop_status_chain?: AwoooPStatusChain | null;
}

const API_BASE = process.env.NEXT_PUBLIC_API_URL ?? "";
const ADR100_GATE5_PROJECTION_TRIGGER = "adr100_runtime_replay_gate5";

const ownerResponseValidationDecisionRefs: OwnerResponseValidationDecisionRef[] = [
  {
    phase: "S4.13",
    key: "validationRollup",
    contract: "source_control_owner_response_validation_rollup_v1",
  },
  {
    phase: "S4.9",
    key: "giteaAttestation",
    contract: "gitea_inventory_owner_attestation_response_v1",
  },
  {
    phase: "S4.10",
    key: "githubTarget",
    contract: "github_target_owner_decision_response_v1",
  },
  {
    phase: "S4.11",
    key: "refsTruth",
    contract: "source_control_ref_truth_owner_response_v1",
  },
  {
    phase: "S4.12",
    key: "workflowSecret",
    contract: "source_control_workflow_secret_name_owner_response_v1",
  },
];

const ownerResponseValidationDecisionBoundaries = [
  "owner_response_validation_received_count=0",
  "owner_response_validation_accepted_count=0",
  "owner_response_validation_rejected_count=0",
  "approval_decision_owner_response_linked=false",
  "owner_response_acceptance_authorized=false",
  "security_approval_record_created=false",
  "platform_run_creation_authorized=false",
  "execution_router_linked=false",
  "repo_creation_authorized=false",
  "refs_sync_authorized=false",
  "workflow_modification_authorized=false",
  "secret_value_collection_allowed=false",
  "github_primary_switch_authorized=false",
  "runtime_execution_authorized=false",
  "action_buttons_allowed=false",
];

const STATE_STYLE: Record<string, string> = {
  waiting_approval: "border-[#d9b36f] bg-[#fff7e8] text-[#8a5a08]",
  running: "border-[#9bb6d9] bg-[#eef5ff] text-[#1f5b9b]",
  completed: "border-[#9bc7a4] bg-[#f0faf2] text-[#17602a]",
  cancelled: "border-[#e2a29b] bg-[#fff0ef] text-[#9f2f25]",
  failed: "border-[#e2a29b] bg-[#fff0ef] text-[#9f2f25]",
  timeout: "border-[#e2a29b] bg-[#fff0ef] text-[#9f2f25]",
};

function formatDate(value: string | null | undefined, locale: string, emptyLabel: string) {
  if (!value) return emptyLabel;
  return new Date(value).toLocaleString(locale === "zh-TW" ? "zh-TW" : "en-US", {
    month: "2-digit",
    day: "2-digit",
    hour: "2-digit",
    minute: "2-digit",
    second: "2-digit",
  });
}

function runTimelineHref(runId: string, projectId?: string | null) {
  const query = projectId ? `?project_id=${encodeURIComponent(projectId)}` : "";
  return `/awooop/runs/${runId}${query}` as never;
}

function remediationRoute(item?: RemediationHistoryItem | null) {
  if (!item) return "--";
  return [item.agent_id, item.tool_name, item.required_scope].filter(Boolean).join("/") || "--";
}

function booleanLabel(value: boolean | null | undefined, emptyLabel: string) {
  if (value === true) return "true";
  if (value === false) return "false";
  return emptyLabel;
}

function DetailRow({
  label,
  value,
  emptyLabel,
}: {
  label: string;
  value?: string | number | null | React.ReactNode;
  emptyLabel: string;
}) {
  return (
    <div className="grid gap-1 border-b border-[#eee9dd] py-3 last:border-0 md:grid-cols-[132px_1fr]">
      <dt className="text-xs font-semibold uppercase text-[#77736a]">{label}</dt>
      <dd className="min-w-0 break-words font-mono text-sm text-[#141413]">
        {value ?? emptyLabel}
      </dd>
    </div>
  );
}

function ApprovalRemediationEvidence({
  history,
  locale,
  emptyLabel,
}: {
  history?: RunRemediationHistory;
  locale: string;
  emptyLabel: string;
}) {
  const t = useTranslations("awooop.approvalDecision.remediation");
  const total = history?.total ?? 0;
  const latest = history?.items?.[0] ?? null;
  const incidentIds = history?.incident_ids ?? [];
  const hasRecords = total > 0;

  return (
    <section className="border border-[#e0ddd4] bg-white">
      <div className="flex flex-wrap items-center justify-between gap-3 border-b border-[#e0ddd4] bg-[#faf9f3] px-5 py-4">
        <div className="flex items-center gap-2">
          <ShieldCheck className="h-4 w-4 text-brand-accent" aria-hidden="true" />
          <h3 className="text-sm font-semibold text-[#141413]">{t("title")}</h3>
        </div>
        <span
          className={cn(
            "border px-2 py-0.5 text-xs font-semibold",
            hasRecords
              ? "border-[#d9b36f] bg-[#fff7e8] text-[#8a5a08]"
              : "border-[#d8d3c7] bg-white text-[#5f5b52]"
          )}
        >
          {hasRecords ? t("status.linked") : t("status.empty")}
        </span>
      </div>
      <div className="grid gap-px bg-[#e0ddd4] md:grid-cols-3">
        {[
          { label: t("metrics.incidents"), value: incidentIds.length || emptyLabel },
          { label: t("metrics.dryRuns"), value: total },
          { label: t("metrics.tools"), value: latest?.tool_count ?? emptyLabel },
        ].map((item) => (
          <div key={item.label} className="min-w-0 bg-white px-5 py-3">
            <p className="text-xs font-semibold text-[#77736a]">{item.label}</p>
            <p className="mt-2 truncate font-mono text-lg font-semibold text-[#141413]">
              {item.value}
            </p>
          </div>
        ))}
      </div>
      {latest ? (
        <div className="space-y-2 px-5 py-4 text-sm leading-6 text-[#5f5b52]">
          <p>
            <span className="font-semibold text-[#141413]">{t("latest")}</span>{" "}
            <span className="font-mono text-[#141413]">{latest.incident_id ?? emptyLabel}</span>{" "}
            {t("preview", {
              mode: latest.mode ?? emptyLabel,
              preview: latest.verification_result_preview ?? emptyLabel,
            })}
          </p>
          <p className="font-mono text-xs text-[#77736a]">
            {remediationRoute(latest)} · {formatDate(latest.created_at, locale, emptyLabel)}
          </p>
          <p className="text-xs text-[#77736a]">
            {t("writes", {
              incident: booleanLabel(latest.writes_incident_state, emptyLabel),
              autoRepair: booleanLabel(latest.writes_auto_repair_result, emptyLabel),
            })}
          </p>
        </div>
      ) : (
        <div className="px-5 py-4 text-sm text-[#77736a]">{t("empty")}</div>
      )}
    </section>
  );
}

function OwnerResponseValidationDecisionBoundaryPanel() {
  const t = useTranslations("awooop.approvalDecision.ownerResponseValidationDecisionBoundary");
  const metrics = [
    { label: t("metrics.packets.label"), value: "4", detail: t("metrics.packets.detail") },
    { label: t("metrics.templates.label"), value: "22", detail: t("metrics.templates.detail") },
    { label: t("metrics.received.label"), value: "0", detail: t("metrics.received.detail") },
    { label: t("metrics.accepted.label"), value: "0", detail: t("metrics.accepted.detail") },
    { label: t("metrics.decisionAcceptance.label"), value: "0", detail: t("metrics.decisionAcceptance.detail") },
    { label: t("metrics.displaySections.label"), value: "8", detail: t("metrics.displaySections.detail") },
  ];

  return (
    <section className="border border-[#d7c9f0] bg-[#fbf8ff]">
      <div className="flex flex-wrap items-start justify-between gap-4 border-b border-[#d7c9f0] px-4 py-4">
        <div className="max-w-4xl">
          <div className="flex items-center gap-2">
            <ShieldCheck className="h-4 w-4 text-[#6d48a8]" aria-hidden="true" />
            <h3 className="text-sm font-semibold text-[#141413]">{t("title")}</h3>
          </div>
          <p className="mt-2 text-sm leading-6 text-[#5f5b52]">{t("subtitle")}</p>
        </div>
        <div className="flex flex-wrap items-center gap-2">
          <span className="border border-[#bda9df] bg-white px-2 py-1 text-xs font-semibold text-[#5c3b91]">
            {t("badge")}
          </span>
          <Link
            href="/iwooos"
            className="inline-flex items-center gap-2 border border-[#bda9df] bg-white px-3 py-2 text-sm font-semibold text-[#141413] hover:border-[#6d48a8]"
          >
            {t("openIwooos")}
            <ArrowRight className="h-4 w-4" aria-hidden="true" />
          </Link>
        </div>
      </div>

      <div className="grid gap-px bg-[#d7c9f0] md:grid-cols-3 xl:grid-cols-6">
        {metrics.map((item) => (
          <div key={item.label} className="min-w-0 bg-white px-4 py-3">
            <p className="text-xs font-semibold text-[#77736a]">{item.label}</p>
            <p className="mt-2 font-mono text-2xl font-semibold text-[#141413]">{item.value}</p>
            <p className="mt-2 text-xs leading-5 text-[#5f5b52]">{item.detail}</p>
          </div>
        ))}
      </div>

      <div className="grid gap-px bg-[#d7c9f0] lg:grid-cols-[1fr_1fr]">
        <div className="min-w-0 bg-white p-4">
          <h4 className="text-sm font-semibold text-[#141413]">{t("decisionRefsTitle")}</h4>
          <div className="mt-3 divide-y divide-[#eee9dd] border border-[#eee9dd]">
            {ownerResponseValidationDecisionRefs.map((item) => (
              <div key={item.contract} className="grid gap-2 px-3 py-3 md:grid-cols-[72px_1fr]">
                <span className="font-mono text-xs font-semibold text-[#5c3b91]">{item.phase}</span>
                <div className="min-w-0">
                  <p className="text-sm font-semibold text-[#141413]">
                    {t(`decisionRefs.${item.key}.title` as never)}
                  </p>
                  <p className="mt-1 text-xs leading-5 text-[#5f5b52]">
                    {t(`decisionRefs.${item.key}.detail` as never)}
                  </p>
                  <p className="mt-2 break-all font-mono text-xs text-[#77736a]">{item.contract}</p>
                </div>
              </div>
            ))}
          </div>
        </div>

        <div className="min-w-0 bg-[#f7f0ff] p-4">
          <div className="flex items-center gap-2">
            <ShieldAlert className="h-4 w-4 text-[#6d48a8]" aria-hidden="true" />
            <span className="text-xs font-semibold text-[#5c3b91]">{t("boundaryLabel")}</span>
          </div>
          <h4 className="mt-2 text-base font-semibold text-[#141413]">{t("boundaryTitle")}</h4>
          <p className="mt-2 text-sm leading-6 text-[#5f5b52]">{t("boundaryDetail")}</p>
          <div className="mt-4 space-y-1 font-mono text-xs leading-6 text-[#141413]">
            {ownerResponseValidationDecisionBoundaries.map((item) => (
              <div key={item} className="break-all">
                {item}
              </div>
            ))}
          </div>
        </div>
      </div>
    </section>
  );
}

function DecisionDialog({
  decision,
  runId,
  loading,
  onCancel,
  onConfirm,
}: {
  decision: "approve" | "reject";
  runId: string;
  loading: boolean;
  onCancel: () => void;
  onConfirm: (reason?: string) => void;
}) {
  const t = useTranslations("awooop.approvalDecision.dialog");
  const [reason, setReason] = useState("");
  const isReject = decision === "reject";
  const titleId = `${decision}-dialog-title`;
  const tone = isReject
    ? "border-[#e2a29b] bg-[#fff0ef] text-[#9f2f25]"
    : "border-[#9bc7a4] bg-[#f0faf2] text-[#17602a]";
  const Icon = isReject ? XCircle : CheckCircle;

  return (
    <div
      className="fixed inset-0 z-50 flex items-center justify-center bg-black/50 p-4 backdrop-blur-sm"
      role="dialog"
      aria-modal="true"
      aria-labelledby={titleId}
    >
      <div className="w-full max-w-md border border-[#e0ddd4] bg-white shadow-2xl">
        <div className="flex items-center justify-between border-b border-[#e0ddd4] bg-[#faf9f3] px-5 py-4">
          <div className="flex items-center gap-3">
            <span className={cn("flex h-9 w-9 items-center justify-center border", tone)}>
              <Icon className="h-4 w-4" aria-hidden="true" />
            </span>
            <h3 id={titleId} className="text-base font-semibold text-[#141413]">
              {t(`${decision}.title` as never)}
            </h3>
          </div>
          <button
            onClick={onCancel}
            className="flex h-8 w-8 items-center justify-center border border-[#d8d3c7] text-[#5f5b52] hover:border-[#d97757]"
            aria-label={t("close")}
          >
            <X className="h-4 w-4" aria-hidden="true" />
          </button>
        </div>

        <div className="space-y-4 px-5 py-4">
          <p className="text-sm leading-6 text-[#5f5b52]">
            {t(`${decision}.body` as never)}
          </p>
          <div className="border border-[#eee9dd] bg-[#faf9f3] px-3 py-2">
            <span className="font-mono text-xs text-[#5f5b52]">
              {t("runId")} <span className="text-[#141413]">{runId.slice(0, 8)}</span>
            </span>
          </div>

          {isReject && (
            <label className="block">
              <span className="text-sm font-semibold text-[#141413]">{t("reject.reason")}</span>
              <textarea
                value={reason}
                onChange={(event) => setReason(event.target.value)}
                rows={3}
                placeholder={t("reject.placeholder")}
                className="mt-2 w-full resize-none border border-[#d8d3c7] bg-white px-3 py-2 text-sm text-[#141413] outline-none focus:border-[#d97757]"
              />
            </label>
          )}

          <p className="text-xs leading-5 text-[#77736a]">
            {t(`${decision}.warning` as never)}
          </p>
        </div>

        <div className="flex items-center justify-end gap-3 border-t border-[#e0ddd4] bg-[#faf9f3] px-5 py-4">
          <button
            onClick={onCancel}
            disabled={loading}
            className="border border-[#d8d3c7] bg-white px-4 py-2 text-sm font-semibold text-[#5f5b52] hover:border-[#d97757] disabled:opacity-50"
          >
            {t("cancel")}
          </button>
          <button
            onClick={() => onConfirm(isReject ? reason.trim() : undefined)}
            disabled={loading || (isReject && reason.trim().length === 0)}
            className={cn(
              "inline-flex items-center gap-2 border px-4 py-2 text-sm font-semibold disabled:cursor-not-allowed disabled:opacity-50",
              tone
            )}
          >
            {loading && <RefreshCw className="h-3.5 w-3.5 animate-spin" aria-hidden="true" />}
            <Icon className="h-3.5 w-3.5" aria-hidden="true" />
            {t(`${decision}.confirm` as never)}
          </button>
        </div>
      </div>
    </div>
  );
}

export default function ApprovalDecisionPage({
  params,
}: {
  params: { run_id: string };
}) {
  const { run_id } = params;
  const router = useRouter();
  const locale = useLocale();
  const t = useTranslations("awooop.approvalDecision");
  const searchParams = useSearchParams();
  const projectId = searchParams.get("project_id") ?? "";

  const [detail, setDetail] = useState<RunDetailResponse | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [actionLoading, setActionLoading] = useState(false);
  const [actionError, setActionError] = useState<string | null>(null);
  const [actionSuccess, setActionSuccess] = useState<string | null>(null);
  const [dialogDecision, setDialogDecision] = useState<"approve" | "reject" | null>(null);

  const timelineHref = useMemo(
    () => runTimelineHref(run_id, detail?.run?.project_id || projectId || undefined),
    [detail?.run?.project_id, projectId, run_id]
  );

  const fetchRun = useCallback(async () => {
    try {
      setError(null);
      const query = new URLSearchParams();
      if (projectId) query.set("project_id", projectId);
      const suffix = query.toString() ? `?${query.toString()}` : "";
      const res = await fetch(`${API_BASE}/api/v1/platform/runs/${run_id}/detail${suffix}`);
      if (!res.ok) throw new Error(`HTTP ${res.status}`);
      const data: RunDetailResponse = await res.json();
      setDetail(data);
    } catch (err) {
      setError(err instanceof Error ? err.message : t("errors.loadFailed"));
    } finally {
      setLoading(false);
    }
  }, [projectId, run_id, t]);

  useEffect(() => {
    setLoading(true);
    fetchRun();
  }, [fetchRun]);

  const handleDecision = async (decision: "approve" | "reject", reason?: string) => {
    if (!detail?.run?.project_id) {
      setActionError(t("errors.missingProject"));
      setDialogDecision(null);
      return;
    }
    if (detail.run.trigger_type === ADR100_GATE5_PROJECTION_TRIGGER) {
      setActionError(t("gate5Projection.actionBlocked"));
      setDialogDecision(null);
      return;
    }
    setActionLoading(true);
    setActionError(null);
    try {
      const res = await fetch(`${API_BASE}/api/v1/platform/approvals/${run_id}/decide`, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          project_id: detail.run.project_id,
          decision,
          reason: reason ?? null,
        }),
      });
      if (!res.ok) {
        let message = `HTTP ${res.status}`;
        try {
          const body = await res.json();
          if (typeof body?.detail === "string" && body.detail) {
            message = body.detail;
          }
        } catch {
          // Keep the HTTP status when the API did not return a JSON error body.
        }
        throw new Error(message);
      }
      setActionSuccess(t(`success.${decision}` as never));
      setDialogDecision(null);
      setTimeout(() => router.push(timelineHref), 1200);
    } catch (err) {
      setActionError(err instanceof Error ? err.message : t("errors.actionFailed"));
      setDialogDecision(null);
    } finally {
      setActionLoading(false);
    }
  };

  const run = detail?.run;
  const latestRemediation = detail?.remediation_history?.items?.[0] ?? null;
  const isWaitingApproval = run?.state === "waiting_approval";
  const isGate5Projection = run?.trigger_type === ADR100_GATE5_PROJECTION_TRIGGER;
  const stateClass = STATE_STYLE[run?.state ?? ""] ?? "border-[#d8d3c7] bg-white text-[#5f5b52]";

  return (
    <>
      {dialogDecision && (
        <DecisionDialog
          decision={dialogDecision}
          runId={run_id}
          loading={actionLoading}
          onCancel={() => setDialogDecision(null)}
          onConfirm={(reason) => handleDecision(dialogDecision, reason)}
        />
      )}

      <div className="max-w-4xl space-y-6">
        <div className="flex flex-wrap items-center justify-between gap-3">
          <Link
            href="/awooop/approvals"
            className="inline-flex items-center gap-2 text-sm text-[#77736a] hover:text-[#141413]"
          >
            <ArrowLeft className="h-4 w-4" aria-hidden="true" />
            {t("back")}
          </Link>
          <Link
            href={timelineHref}
            className="inline-flex items-center gap-2 border border-[#d8d3c7] bg-white px-3 py-2 text-sm font-semibold text-[#5f5b52] hover:border-[#d97757]"
          >
            {t("viewTimeline")}
            <ArrowRight className="h-4 w-4" aria-hidden="true" />
          </Link>
        </div>

        <section className="border border-[#e0ddd4] bg-white">
          <div className="grid gap-px bg-[#e0ddd4] lg:grid-cols-[1.2fr_0.8fr]">
            <div className="bg-white p-5">
              <div className="flex items-center gap-3">
                <ShieldCheck className="h-5 w-5 text-brand-accent" aria-hidden="true" />
                <div>
                  <p className="text-xs font-semibold text-[#77736a]">{t("eyebrow")}</p>
                  <h2 className="text-lg font-semibold text-[#141413]">{t("title")}</h2>
                  <p className="mt-1 font-mono text-xs text-[#77736a]">{run_id}</p>
                </div>
              </div>
            </div>
            <div className="bg-white p-5">
              <div className="flex items-center gap-2 text-xs font-semibold text-[#77736a]">
                <Clock className="h-3.5 w-3.5" aria-hidden="true" />
                {t("timeout")}
              </div>
              <p className="mt-2 font-mono text-sm text-[#141413]">
                {formatDate(run?.timeout_at, locale, t("empty"))}
              </p>
            </div>
          </div>
        </section>

        {error && (
          <div className="flex items-start gap-3 border border-[#e2a29b] bg-[#fff0ef] p-4 text-[#9f2f25]">
            <AlertCircle className="mt-0.5 h-5 w-5 shrink-0" aria-hidden="true" />
            <div>
              <p className="text-sm font-semibold">{t("errors.title")}</p>
              <p className="mt-1 text-xs">{error}</p>
            </div>
          </div>
        )}

        {actionError && (
          <div className="flex items-start gap-3 border border-[#e2a29b] bg-[#fff0ef] p-4 text-[#9f2f25]">
            <AlertCircle className="mt-0.5 h-5 w-5 shrink-0" aria-hidden="true" />
            <p className="text-sm">{actionError}</p>
          </div>
        )}

        {actionSuccess && (
          <div className="flex items-center gap-3 border border-[#9bc7a4] bg-[#f0faf2] p-4 text-[#17602a]">
            <CheckCircle className="h-5 w-5 shrink-0" aria-hidden="true" />
            <p className="text-sm font-semibold">{actionSuccess}</p>
          </div>
        )}

        {run && !isWaitingApproval && (
          <div className="flex items-start gap-3 border border-[#d9b36f] bg-[#fff7e8] p-4 text-[#8a5a08]">
            <AlertCircle className="mt-0.5 h-5 w-5 shrink-0" aria-hidden="true" />
            <div>
              <p className="text-sm font-semibold">{t("notWaiting.title")}</p>
              <p className="mt-1 text-xs leading-5">
                {t("notWaiting.detail", { state: run.state || t("empty") })}
              </p>
            </div>
          </div>
        )}

        {run && isGate5Projection && (
          <div className="flex items-start gap-3 border border-[#9bb6d9] bg-[#eef5ff] p-4 text-[#1f5b9b]">
            <ShieldAlert className="mt-0.5 h-5 w-5 shrink-0" aria-hidden="true" />
            <div>
              <p className="text-sm font-semibold">{t("gate5Projection.title")}</p>
              <p className="mt-1 text-xs leading-5">{t("gate5Projection.detail")}</p>
              <p className="mt-2 font-mono text-xs text-[#47709a]">
                {t("gate5Projection.boundary")}
              </p>
            </div>
          </div>
        )}

        <IncidentEvidenceHeader
          projectId={run?.project_id || projectId || "awoooi"}
          runId={run_id}
          incidentIds={detail?.remediation_history?.incident_ids}
          dryRunCount={detail?.remediation_history?.total}
          latestRoute={remediationRoute(latestRemediation)}
          writesIncidentState={latestRemediation?.writes_incident_state}
          writesAutoRepairResult={latestRemediation?.writes_auto_repair_result}
        />

        <AwoooPStatusChainPanel chain={detail?.awooop_status_chain} />

        <ApprovalRemediationEvidence
          history={detail?.remediation_history}
          locale={locale}
          emptyLabel={t("empty")}
        />

        <OwnerResponseValidationDecisionBoundaryPanel />

        <section className="border border-[#e0ddd4] bg-white">
          <div className="flex items-center justify-between border-b border-[#e0ddd4] bg-[#faf9f3] px-5 py-4">
            <h3 className="text-sm font-semibold text-[#141413]">{t("details.title")}</h3>
            {loading && <RefreshCw className="h-4 w-4 animate-spin text-[#77736a]" aria-hidden="true" />}
          </div>

          <dl className="px-5">
            {loading ? (
              Array.from({ length: 7 }).map((_, index) => (
                <div key={index} className="grid gap-3 border-b border-[#eee9dd] py-3 md:grid-cols-[132px_1fr]">
                  <div className="h-4 animate-pulse bg-[#f2efe6]" />
                  <div className="h-4 w-full max-w-md animate-pulse bg-[#f2efe6]" />
                </div>
              ))
            ) : run ? (
              <>
                <DetailRow label={t("details.runId")} value={run.run_id} emptyLabel={t("empty")} />
                <DetailRow label={t("details.project")} value={run.project_id} emptyLabel={t("empty")} />
                <DetailRow label={t("details.agent")} value={run.agent_id} emptyLabel={t("empty")} />
                <DetailRow
                  label={t("details.state")}
                  value={
                    <span className={cn("inline-flex border px-2 py-0.5 text-xs font-semibold", stateClass)}>
                      {run.state || t("empty")}
                    </span>
                  }
                  emptyLabel={t("empty")}
                />
                <DetailRow label={t("details.traceId")} value={run.trace_id} emptyLabel={t("empty")} />
                <DetailRow label={t("details.trigger")} value={run.trigger_type} emptyLabel={t("empty")} />
                <DetailRow label={t("details.triggerRef")} value={run.trigger_ref} emptyLabel={t("empty")} />
                <DetailRow
                  label={t("details.cost")}
                  value={run.cost_usd === undefined ? null : `$${Number(run.cost_usd ?? 0).toFixed(4)}`}
                  emptyLabel={t("empty")}
                />
                <DetailRow
                  label={t("details.attempts")}
                  value={
                    run.attempt_count === undefined || run.max_attempts === undefined
                      ? null
                      : `${run.attempt_count}/${run.max_attempts}`
                  }
                  emptyLabel={t("empty")}
                />
                <DetailRow
                  label={t("details.created")}
                  value={formatDate(run.created_at, locale, t("empty"))}
                  emptyLabel={t("empty")}
                />
                <DetailRow
                  label={t("details.timeout")}
                  value={formatDate(run.timeout_at, locale, t("empty"))}
                  emptyLabel={t("empty")}
                />
                <DetailRow
                  label={t("details.error")}
                  value={run.error_detail || run.error_code}
                  emptyLabel={t("empty")}
                />
              </>
            ) : (
              <div className="py-12 text-center text-sm text-[#77736a]">{t("details.empty")}</div>
            )}
          </dl>
        </section>

        {!loading && run && isWaitingApproval && !isGate5Projection && !actionSuccess && (
          <section className="grid gap-3 md:grid-cols-2">
            <button
              onClick={() => setDialogDecision("approve")}
              disabled={actionLoading}
              className="inline-flex items-center justify-center gap-2 border border-[#9bc7a4] bg-[#f0faf2] px-6 py-3 text-sm font-semibold text-[#17602a] hover:bg-[#e4f6e7] disabled:opacity-50"
            >
              <CheckCircle className="h-4 w-4" aria-hidden="true" />
              {t("actions.approve")}
            </button>
            <button
              onClick={() => setDialogDecision("reject")}
              disabled={actionLoading}
              className="inline-flex items-center justify-center gap-2 border border-[#e2a29b] bg-[#fff0ef] px-6 py-3 text-sm font-semibold text-[#9f2f25] hover:bg-[#ffe4e1] disabled:opacity-50"
            >
              <XCircle className="h-4 w-4" aria-hidden="true" />
              {t("actions.reject")}
            </button>
          </section>
        )}
      </div>
    </>
  );
}
