"use client";

import { useMemo, type ReactNode } from "react";
import {
  Accordion,
  AccordionContent,
  AccordionItem,
  AccordionTrigger,
} from "@/components/ui/accordion";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import {
  Popover,
  PopoverContent,
  PopoverTrigger,
} from "@/components/ui/popover";
import { Skeleton } from "@/components/ui/skeleton";
import {
  PARTY_LABELS_HE,
  PRIORITY_LABELS_HE,
  PRIORITY_ORDER,
  useAggregateArguments,
  useLegalArguments,
  type AggregateArgumentsResult,
  type LegalArgument,
  type LegalArgumentParty,
  type LegalArgumentPriority,
} from "@/lib/api/legal-arguments";
import { toast } from "sonner";
import { ListTree, Loader2, RefreshCw, Sparkles } from "lucide-react";

const PRIORITY_BADGE_TONE: Record<LegalArgumentPriority, string> = {
  threshold: "bg-danger-bg/60 text-danger-strong border-danger/40",
  substantive: "bg-gold-soft/50 text-navy border-gold/40",
  procedural: "bg-rule-soft text-ink border-rule",
  relief: "bg-emerald-50 text-emerald-900 border-emerald-200",
};

// Per-party colour mark + one-line role description (mockup 25b party trigger).
const PARTY_MARK_TONE: Record<LegalArgumentParty, string> = {
  appellant: "bg-info",
  respondent: "bg-gold-deep",
  committee: "bg-success",
  permit_applicant: "bg-warn",
  unknown: "bg-ink-muted",
};

const PARTY_SUB_HE: Record<LegalArgumentParty, string> = {
  appellant: "הצד היוזם של הערר",
  respondent: "הצד המשיב לערר",
  committee: "עמדת הגורם המאשר",
  permit_applicant: "צד שלישי שזכותו עשויה להיפגע",
  unknown: "צד שלא זוהה אוטומטית",
};

function groupByPriority(
  args: LegalArgument[],
): Record<LegalArgumentPriority, LegalArgument[]> {
  const out: Record<LegalArgumentPriority, LegalArgument[]> = {
    threshold: [],
    substantive: [],
    procedural: [],
    relief: [],
  };
  for (const a of args) {
    (out[a.priority] ?? out.substantive).push(a);
  }
  for (const key of PRIORITY_ORDER) {
    out[key].sort((x, y) => x.argument_index - y.argument_index);
  }
  return out;
}

type PartySectionProps = {
  args: LegalArgument[];
};

/**
 * Inner body of a single party. For a multi-litigant side (respondent /
 * permit_applicant) whose arguments carry distinct ``party_name`` brief labels,
 * we sub-group by brief first — so opposing joint briefs (e.g. "משיבות 2-3" vs
 * "משיבים 4-6") read as separate positions rather than one merged list (#224).
 * Single-voice sides (one empty brief) render the priority groups directly.
 */
function PartySection({ args }: PartySectionProps) {
  const briefs = useMemo(() => {
    const byBrief = new Map<string, LegalArgument[]>();
    for (const a of args) {
      const key = a.party_name?.trim() ?? "";
      const list = byBrief.get(key);
      if (list) list.push(a);
      else byBrief.set(key, [a]);
    }
    return [...byBrief.entries()];
  }, [args]);

  // No real per-brief split (single, unnamed group) → render groups directly.
  if (briefs.length <= 1) {
    return <PriorityGroups args={briefs[0]?.[1] ?? args} />;
  }

  return (
    <div className="space-y-5">
      {briefs.map(([brief, briefArgs]) => (
        <div key={brief || "—"} className="space-y-2">
          <div className="flex items-center gap-2 border-s-2 border-gold-deep ps-2">
            <span className="text-navy text-sm font-semibold">
              {brief || "ללא שיוך לכתב"}
            </span>
            <span className="text-ink-muted text-xs">
              {briefArgs.length} טיעונים
            </span>
          </div>
          <PriorityGroups args={briefArgs} />
        </div>
      ))}
    </div>
  );
}

/** Priority-grouped argument accordion for one coherent set of arguments. */
function PriorityGroups({ args }: PartySectionProps) {
  const grouped = useMemo(() => groupByPriority(args), [args]);
  return (
    <div className="space-y-4">
      {PRIORITY_ORDER.map((priority) => {
        const list = grouped[priority];
        if (!list?.length) return null;
        return (
          <div key={priority} className="space-y-1">
            <div className="flex items-center gap-2">
              <Badge
                variant="outline"
                className={`${PRIORITY_BADGE_TONE[priority]} text-xs`}
              >
                {PRIORITY_LABELS_HE[priority]}
              </Badge>
              <span className="text-ink-muted text-xs">
                {list.length} טיעונים
              </span>
            </div>
            <Accordion type="multiple" className="rounded-md border border-rule bg-surface">
              {list.map((arg) => (
                <AccordionItem key={arg.id} value={arg.id} className="px-3">
                  <AccordionTrigger className="text-start">
                    <div className="flex flex-1 flex-col items-start gap-1">
                      <span className="text-navy text-sm font-medium leading-tight">
                        {arg.argument_index}. {arg.argument_title}
                      </span>
                      {arg.legal_topic && (
                        <span className="text-ink-muted text-xs">
                          {arg.legal_topic}
                        </span>
                      )}
                    </div>
                  </AccordionTrigger>
                  <AccordionContent>
                    <div className="space-y-2 px-1">
                      <p className="text-ink leading-relaxed whitespace-pre-line">
                        {arg.argument_body}
                      </p>
                      {arg.supporting_claims.length > 0 &&
                        (arg.supporting_propositions &&
                        arg.supporting_propositions.length > 0 ? (
                          <Popover>
                            <PopoverTrigger asChild>
                              <button
                                type="button"
                                className="text-gold-strong hover:text-gold inline-flex items-center gap-1 text-xs underline decoration-dotted underline-offset-2"
                              >
                                <ListTree className="size-3.5" aria-hidden />
                                מסתמך על {arg.supporting_claims.length}{" "}
                                פרופוזיציות גולמיות
                              </button>
                            </PopoverTrigger>
                            <PopoverContent
                              align="start"
                              className="max-h-96 w-96 overflow-y-auto"
                            >
                              <p className="text-ink-muted mb-2 text-xs font-medium">
                                הטענות הגולמיות שמהן אוגד הטיעון:
                              </p>
                              <ol className="space-y-2">
                                {arg.supporting_propositions.map((p, i) => (
                                  <li
                                    key={p.id}
                                    className="border-rule border-s-2 ps-2 text-xs"
                                  >
                                    <span className="text-navy font-medium">
                                      {i + 1}.
                                    </span>{" "}
                                    <span className="text-ink leading-relaxed">
                                      {p.text}
                                    </span>
                                    {p.source_document && (
                                      <span className="text-ink-muted mt-0.5 block">
                                        מקור: {p.source_document}
                                      </span>
                                    )}
                                  </li>
                                ))}
                              </ol>
                            </PopoverContent>
                          </Popover>
                        ) : (
                          <p className="text-ink-muted text-xs">
                            מסתמך על {arg.supporting_claims.length} פרופוזיציות
                            גולמיות.
                          </p>
                        ))}
                    </div>
                  </AccordionContent>
                </AccordionItem>
              ))}
            </Accordion>
          </div>
        );
      })}
    </div>
  );
}

type LegalArgumentsPanelProps = {
  caseNumber: string;
};

export function LegalArgumentsPanel({ caseNumber }: LegalArgumentsPanelProps) {
  const { data, isPending, isError, error } = useLegalArguments(caseNumber);
  const aggregate = useAggregateArguments(caseNumber);

  const parties = useMemo<LegalArgumentParty[]>(() => {
    if (!data?.by_party) return [];
    const order: LegalArgumentParty[] = [
      "appellant",
      "respondent",
      "committee",
      "permit_applicant",
      "unknown",
    ];
    return order.filter((p) => (data.by_party[p]?.length ?? 0) > 0);
  }, [data]);

  const handleAggregate = (force: boolean) => {
    // Status feedback is rendered inline as a banner from `aggregate.data`;
    // only hard transport/HTTP errors fall through to a toast.
    aggregate.mutate(force, {
      onError: (e) => toast.error(`שגיאה: ${(e as Error).message}`),
    });
  };

  return (
    <div className="space-y-4">
      <div className="flex items-center justify-between flex-wrap gap-3">
        <div>
          <h2 className="text-navy text-base font-semibold">טיעונים משפטיים</h2>
          <p className="text-ink-muted text-xs mt-0.5">
            טיעונים מאוגדים מתוך הטענות הגולמיות, מקובצים לפי צד וקדימות. החישוב
            רץ אצל המנתח המשפטי ומדווח בחזרה.
          </p>
        </div>
        <div className="flex items-center gap-2">
          <Button
            variant="outline"
            size="sm"
            disabled={aggregate.isPending}
            onClick={() => handleAggregate(false)}
          >
            {aggregate.isPending ? (
              <Loader2 className="w-3.5 h-3.5 animate-spin me-1.5" />
            ) : (
              <Sparkles className="w-3.5 h-3.5 me-1.5" />
            )}
            חשב טיעונים
          </Button>
          <Button
            variant="ghost"
            size="sm"
            disabled={aggregate.isPending || !data?.total}
            onClick={() => handleAggregate(true)}
            title="חישוב מחדש (מוחק טיעונים קיימים)"
          >
            <RefreshCw className="w-3.5 h-3.5" />
          </Button>
        </div>
      </div>

      <AggregateStatusBanner
        result={aggregate.data}
        force={aggregate.variables ?? false}
      />

      {isPending ? (
        <div className="space-y-2">
          <Skeleton className="h-6 w-48" />
          <Skeleton className="h-20 w-full" />
          <Skeleton className="h-20 w-full" />
        </div>
      ) : isError ? (
        <p className="text-danger text-sm">
          שגיאה בטעינת טיעונים: {(error as Error).message}
        </p>
      ) : !data?.total ? (
        <p className="text-ink-muted text-sm">
          אין טיעונים מאוגדים עדיין. לחץ &ldquo;חשב טיעונים&rdquo; כדי לשלוח את
          החישוב למנתח המשפטי.
        </p>
      ) : (
        // Top-level party accordion — each party is its own collapsible section,
        // closed by default (empty defaultValue). The count badge on every
        // trigger shows the scope without expanding (mockup 25b).
        <Accordion type="multiple" className="space-y-3.5">
          {parties.map((party) => {
            const args = data.by_party[party] ?? [];
            return (
              <AccordionItem
                key={party}
                value={party}
                className="overflow-hidden rounded-lg border border-rule bg-surface shadow-sm"
              >
                <AccordionTrigger className="px-5 py-4 hover:no-underline data-[state=open]:border-b data-[state=open]:border-rule-soft data-[state=open]:bg-parchment">
                  <span className="flex flex-1 items-center gap-3.5">
                    <span
                      className={`h-8 w-1.5 flex-none rounded ${PARTY_MARK_TONE[party]}`}
                      aria-hidden
                    />
                    <span className="flex flex-1 flex-col items-start gap-0.5">
                      <span className="text-navy text-base font-bold leading-tight">
                        {PARTY_LABELS_HE[party] ?? party}
                      </span>
                      <span className="text-ink-muted text-xs">
                        {PARTY_SUB_HE[party]}
                      </span>
                    </span>
                    <Badge
                      variant="outline"
                      className="bg-gold-wash text-gold-deep border-rule rounded-full px-3 py-0.5 text-xs font-bold whitespace-nowrap"
                    >
                      {args.length} טיעונים
                    </Badge>
                  </span>
                </AccordionTrigger>
                <AccordionContent className="px-5 pb-4 pt-4">
                  <PartySection args={args} />
                </AccordionContent>
              </AccordionItem>
            );
          })}
        </Accordion>
      )}
    </div>
  );
}

const BANNER_TONE = {
  info: "border-info/30 bg-info-bg",
  gold: "border-gold/40 bg-gold-wash",
  muted: "border-rule bg-rule-soft",
  warn: "border-warn/40 bg-warn-bg",
} as const;

const DOT_TONE = {
  info: "bg-info",
  gold: "bg-gold-deep",
  muted: "bg-ink-light",
  warn: "bg-warn",
} as const;

const TITLE_TONE = {
  info: "text-info",
  gold: "text-gold-deep",
  muted: "text-ink-soft",
  warn: "text-warn",
} as const;

/**
 * Inline status feedback for the aggregation trigger — mirrors the approved
 * Claude Design mockup (25-legal-arguments-panel). Shown only after a click;
 * the four states map to the endpoint's discriminated-union result.
 */
function AggregateStatusBanner({
  result,
  force,
}: {
  result: AggregateArgumentsResult | undefined;
  force: boolean;
}) {
  if (!result) return null;

  let tone: keyof typeof BANNER_TONE;
  let title: string;
  let body: ReactNode;

  switch (result.status) {
    case "queued":
      tone = "info";
      title = "נשלח לאנליטיקאי.";
      body = `${force ? "החישוב-מחדש" : "החישוב"} רץ ברקע אצל המנתח המשפטי; התוצאה תופיע תוך כמה דקות — רענן את הדף.`;
      break;
    case "exists":
      tone = "gold";
      title = "כבר חושב.";
      body = result.message;
      break;
    case "no_claims":
      tone = "muted";
      title = "אין טענות גולמיות.";
      body = result.message;
      break;
    case "skipped":
      tone = "warn";
      title = "לא ניתן להפעיל אוטומטית";
      body = (
        <>
          {` (${result.reason}). הרץ ידנית מ-Claude Code: `}
          <code className="font-mono text-[0.72rem] bg-navy/5 rounded px-1.5 py-0.5 select-all">
            mcp__legal-ai__aggregate_claims_to_arguments
          </code>
        </>
      );
      break;
    default:
      return null;
  }

  return (
    <div
      className={`flex items-start gap-2.5 rounded-md border px-3.5 py-2.5 text-[0.8rem] leading-relaxed text-ink-soft ${BANNER_TONE[tone]}`}
    >
      <span
        className={`mt-1.5 size-2 flex-none rounded-full ${DOT_TONE[tone]}`}
        aria-hidden
      />
      <p>
        <strong className={`font-semibold ${TITLE_TONE[tone]}`}>{title}</strong>{" "}
        {body}
      </p>
    </div>
  );
}
