"use client";

/*
 * Side-drawer for inspecting + editing a single style_corpus entry.
 *
 * Tabs:
 *   - "פרטים" — show + edit the enriched metadata (decision_number, date,
 *     subjects, summary, outcome, key_principles, appeal_subtype). Saving
 *     issues a PATCH /api/training/corpus/{id} and invalidates the list.
 *   - "תוכן" — read-only full_text view (truncated to 5K with "show more").
 *     We never let the chair edit full_text from the UI; corrections happen
 *     by re-uploading via the Upload dialog.
 *   - "מה למדנו" — per-decision lessons (Phase 4 placeholder for now).
 *   - "דפוסים" — style_patterns scoped by appeal_subtype.
 *
 * Why a Sheet, not a Dialog: the drawer needs to coexist with the corpus
 * table so the chair can scan multiple decisions without losing context.
 * Sheet (side: "left" in RTL = right edge in LTR) gives that without
 * stealing the entire viewport.
 */

import { useEffect, useState } from "react";
import { Save, FileText, Tag, Calendar, BookOpen, Loader2 } from "lucide-react";
import { toast } from "sonner";
import {
  Sheet, SheetContent, SheetHeader, SheetTitle, SheetDescription,
} from "@/components/ui/sheet";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { Card, CardContent } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Textarea } from "@/components/ui/textarea";
import { Badge } from "@/components/ui/badge";
import { ScrollArea } from "@/components/ui/scroll-area";
import {
  usePatchCorpus,
  type CorpusDecision,
  type CorpusDecisionPatch,
} from "@/lib/api/training";
import { LessonsTab } from "./lessons-tab";

type Props = {
  decision: CorpusDecision | null;
  onOpenChange: (open: boolean) => void;
};

export function CorpusDetailDrawer({ decision, onOpenChange }: Props) {
  // Local editable state for the "details" tab. Re-seeds whenever the
  // selected decision changes so the form reflects the row the chair
  // clicked.
  const [draft, setDraft] = useState<CorpusDecisionPatch>({});
  const patch = usePatchCorpus();

  /* eslint-disable react-hooks/set-state-in-effect */
  useEffect(() => {
    if (!decision) {
      setDraft({});
      return;
    }
    setDraft({
      decision_number: decision.decision_number,
      decision_date: decision.decision_date,
      subject_categories: decision.subject_categories,
      summary: decision.summary,
      outcome: decision.outcome,
      key_principles: decision.key_principles,
      appeal_subtype: decision.appeal_subtype,
      practice_area: decision.practice_area,
    });
  }, [decision]);
  /* eslint-enable react-hooks/set-state-in-effect */

  const open = decision !== null;
  if (!decision) return null;

  // Diff against the originally loaded row — only PATCH fields the chair
  // actually changed, so concurrent edits to other fields stay intact.
  const diff: CorpusDecisionPatch = {};
  if (draft.decision_number !== decision.decision_number)
    diff.decision_number = draft.decision_number;
  if (draft.decision_date !== decision.decision_date)
    diff.decision_date = draft.decision_date;
  if (draft.summary !== decision.summary)
    diff.summary = draft.summary;
  if (draft.outcome !== decision.outcome)
    diff.outcome = draft.outcome;
  if (draft.appeal_subtype !== decision.appeal_subtype)
    diff.appeal_subtype = draft.appeal_subtype;
  if (draft.practice_area !== decision.practice_area)
    diff.practice_area = draft.practice_area;
  if (
    JSON.stringify(draft.subject_categories) !==
    JSON.stringify(decision.subject_categories)
  )
    diff.subject_categories = draft.subject_categories;
  if (
    JSON.stringify(draft.key_principles) !==
    JSON.stringify(decision.key_principles)
  )
    diff.key_principles = draft.key_principles;

  const isDirty = Object.keys(diff).length > 0;

  const onSave = async () => {
    if (!isDirty) return;
    try {
      await patch.mutateAsync({ id: decision.id, patch: diff });
      toast.success("המטא-דאטה עודכן");
    } catch (e) {
      toast.error(e instanceof Error ? e.message : "כשל בשמירה");
    }
  };

  const setSubjects = (raw: string) =>
    setDraft((d) => ({
      ...d,
      subject_categories: raw.split(/[,،]/).map((s) => s.trim()).filter(Boolean),
    }));
  const setPrinciples = (raw: string) =>
    setDraft((d) => ({
      ...d,
      key_principles: raw.split("\n").map((s) => s.trim()).filter(Boolean),
    }));

  return (
    <Sheet open={open} onOpenChange={onOpenChange}>
      <SheetContent side="left" className="w-full sm:max-w-3xl overflow-y-auto" dir="rtl">
        <SheetHeader>
          <SheetTitle className="text-navy flex items-center gap-2">
            <BookOpen className="w-4 h-4 shrink-0" />
            {decision.legal_citation || decision.decision_number || "—"}
          </SheetTitle>
          <SheetDescription className="text-ink-muted">
            {decision.doc_title || "החלטה בקורפוס הסגנוני"}
          </SheetDescription>
        </SheetHeader>

        {/* Summary strip — fast-scan info, always visible above the tabs. */}
        <div className="px-6 mt-3 grid grid-cols-2 md:grid-cols-4 gap-3 text-[0.78rem]">
          <DataPoint icon={<Calendar className="w-3 h-3" />} label="תאריך"
            value={decision.decision_date || "—"} />
          <DataPoint icon={<FileText className="w-3 h-3" />} label="תווים"
            value={`${(decision.chars / 1000).toFixed(1)}K`} />
          <DataPoint icon={<FileText className="w-3 h-3" />} label="עמודים"
            value={decision.page_count > 0 ? String(decision.page_count) : "—"} />
          <DataPoint icon={<Tag className="w-3 h-3" />} label="תת-סוג"
            value={decision.appeal_subtype || "—"} />
        </div>

        <div className="px-6 pb-6 mt-4">
          <Tabs defaultValue="details" dir="rtl">
            <TabsList className="bg-rule-soft/60">
              <TabsTrigger value="details">פרטים</TabsTrigger>
              <TabsTrigger value="content">תוכן</TabsTrigger>
              <TabsTrigger value="lessons">מה למדנו</TabsTrigger>
              <TabsTrigger value="patterns">דפוסים</TabsTrigger>
            </TabsList>

            {/* ── Tab: editable metadata ─────────────────────────── */}
            <TabsContent value="details" className="mt-4 space-y-4">
              <div className="grid grid-cols-2 gap-3">
                <Field label="מספר ההחלטה">
                  <Input value={draft.decision_number ?? ""}
                    onChange={(e) => setDraft((d) => ({ ...d, decision_number: e.target.value }))}
                    dir="rtl" />
                </Field>
                <Field label="תאריך">
                  <Input type="date" value={draft.decision_date ?? ""}
                    onChange={(e) => setDraft((d) => ({ ...d, decision_date: e.target.value }))} />
                </Field>
              </div>

              <Field label="נושאים (מופרדים בפסיקים)">
                <Input value={(draft.subject_categories ?? []).join(", ")}
                  onChange={(e) => setSubjects(e.target.value)} dir="rtl" />
                {decision.subject_categories.length > 0 && (
                  <div className="flex flex-wrap gap-1 mt-1">
                    {decision.subject_categories.map((s) => (
                      <Badge key={s} variant="outline"
                        className="text-[0.7rem] bg-gold-wash text-gold-deep border-gold/40">
                        {s}
                      </Badge>
                    ))}
                  </div>
                )}
              </Field>

              <div className="grid grid-cols-2 gap-3">
                <Field label="תת-סוג ערר">
                  <Input value={draft.appeal_subtype ?? ""}
                    onChange={(e) => setDraft((d) => ({ ...d, appeal_subtype: e.target.value }))}
                    placeholder="building_permit / betterment_levy / compensation_197"
                    dir="rtl" />
                </Field>
                <Field label="תחום משפט">
                  <Input value={draft.practice_area ?? ""}
                    onChange={(e) => setDraft((d) => ({ ...d, practice_area: e.target.value }))}
                    dir="rtl" />
                </Field>
              </div>

              <Field label="תקציר (summary)">
                <Textarea value={draft.summary ?? ""} rows={3}
                  onChange={(e) => setDraft((d) => ({ ...d, summary: e.target.value }))}
                  placeholder="תקציר חופשי — מי, מה, איך הוכרע"
                  dir="rtl" />
              </Field>

              <Field label="התוצאה (outcome)">
                <Textarea value={draft.outcome ?? ""} rows={2}
                  onChange={(e) => setDraft((d) => ({ ...d, outcome: e.target.value }))}
                  placeholder="קבלה / קבלה חלקית / דחייה — בקצרה"
                  dir="rtl" />
              </Field>

              <Field label="עקרונות מרכזיים (שורה לכל אחד)">
                <Textarea value={(draft.key_principles ?? []).join("\n")} rows={4}
                  onChange={(e) => setPrinciples(e.target.value)}
                  placeholder={"דוגמה:\nשיקול דעת מוגבל לחריגות קטנות\nריפוי פגם רק בנסיבות חריגות"}
                  dir="rtl" />
              </Field>

              {decision.parties.appellant && (
                <Card className="bg-rule-soft/40 border-rule">
                  <CardContent className="px-4 py-3 text-[0.78rem] text-ink-soft">
                    <p><strong className="text-navy">עורר/ת:</strong> {decision.parties.appellant}</p>
                    {decision.parties.respondent && (
                      <p className="mt-1"><strong className="text-navy">משיב/ה:</strong> {decision.parties.respondent}</p>
                    )}
                    <p className="mt-2 text-ink-muted text-[0.72rem]">
                      (חולץ אוטומטית מתחילת הטקסט — תקן ע&quot;י עריכת ה-full_text במקור.)
                    </p>
                  </CardContent>
                </Card>
              )}

              <div className="flex items-center justify-end gap-2 pt-2 border-t border-rule">
                <Button variant="ghost" onClick={() => onOpenChange(false)}>
                  סגור
                </Button>
                <Button onClick={onSave} disabled={!isDirty || patch.isPending}
                  className="bg-navy text-parchment hover:bg-navy-soft">
                  {patch.isPending ? (
                    <Loader2 className="w-4 h-4 animate-spin me-1" />
                  ) : (
                    <Save className="w-4 h-4 me-1" />
                  )}
                  שמור שינויים
                </Button>
              </div>
            </TabsContent>

            {/* ── Tab: full_text (read-only) ─────────────────────── */}
            <TabsContent value="content" className="mt-4">
              <Card className="bg-surface border-rule">
                <CardContent className="px-4 py-3">
                  <p className="text-[0.72rem] text-ink-muted mb-2">
                    {decision.chars.toLocaleString("he-IL")} תווים · קריאה בלבד
                  </p>
                  <ScrollArea className="h-[480px] pe-2">
                    <p className="text-sm text-ink leading-relaxed whitespace-pre-wrap">
                      <FullTextLazy id={decision.id} />
                    </p>
                  </ScrollArea>
                </CardContent>
              </Card>
            </TabsContent>

            {/* ── Tab: lessons (per-decision) ────────────────────── */}
            <TabsContent value="lessons" className="mt-4">
              <LessonsTab corpusId={decision.id} />
            </TabsContent>

            {/* ── Tab: patterns scoped by appeal_subtype ─────────── */}
            <TabsContent value="patterns" className="mt-4">
              <PatternsForSubtype subtype={decision.appeal_subtype} />
            </TabsContent>
          </Tabs>
        </div>
      </SheetContent>
    </Sheet>
  );
}

// ── helpers ────────────────────────────────────────────────────────

function DataPoint({
  icon, label, value,
}: { icon: React.ReactNode; label: string; value: string }) {
  return (
    <div className="flex items-center gap-1 text-ink-muted">
      {icon}
      <span>{label}:</span>
      <span className="font-semibold text-navy tabular-nums truncate">{value}</span>
    </div>
  );
}

function Field({
  label, children,
}: { label: string; children: React.ReactNode }) {
  return (
    <div className="space-y-1">
      <Label className="text-[0.78rem]">{label}</Label>
      {children}
    </div>
  );
}

/* The corpus-list endpoint deliberately doesn't return full_text (too big).
 * We fetch it on demand only when the content tab opens.
 *
 * Implementation note: we don't have a dedicated /api/training/corpus/{id}
 * GET endpoint yet. As a thin stopgap we hit a planned `/full-text` shortcut
 * via apiRequest; if the endpoint isn't deployed yet the UI just shows the
 * fallback message instead of crashing. The full-text endpoint lands with
 * the next backend deploy.
 */
function FullTextLazy({ id }: { id: string }) {
  const [text, setText] = useState<string>("");
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState("");

  /* eslint-disable react-hooks/set-state-in-effect */
  useEffect(() => {
    let cancelled = false;
    setLoading(true);
    setError("");
    fetch(`/api/training/corpus/${encodeURIComponent(id)}/full-text`)
      .then((r) => (r.ok ? r.json() : Promise.reject(new Error(`HTTP ${r.status}`))))
      .then((d: { full_text: string }) => {
        if (cancelled) return;
        setText(d.full_text || "");
      })
      .catch((e: Error) => {
        if (cancelled) return;
        setError(e.message);
      })
      .finally(() => !cancelled && setLoading(false));
    return () => { cancelled = true; };
  }, [id]);
  /* eslint-enable react-hooks/set-state-in-effect */

  if (loading) return <span className="text-ink-muted">טוען…</span>;
  if (error) return <span className="text-ink-muted">לא נמצא ({error})</span>;
  return text;
}

function PatternsForSubtype({ subtype }: { subtype: string }) {
  // Filtered patterns endpoint isn't built yet — we fall back to /patterns
  // and filter client-side. The result is mediocre when many subtypes share
  // patterns; better filtering ships in the metadata-enrichment iteration.
  const [data, setData] = useState<Record<string, { pattern_text: string; frequency: number }[]> | null>(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    let cancelled = false;
    fetch("/api/training/patterns")
      .then((r) => r.json())
      .then((d: { by_type: Record<string, { pattern_text: string; frequency: number }[]> }) => {
        if (!cancelled) setData(d.by_type);
      })
      .catch(() => !cancelled && setData({}))
      .finally(() => !cancelled && setLoading(false));
    return () => { cancelled = true; };
  }, []);

  if (loading) return <p className="text-ink-muted text-sm text-center py-6">טוען…</p>;
  if (!data || Object.keys(data).length === 0) {
    return <p className="text-ink-muted text-sm text-center py-6">אין דפוסים שמורים — הרץ ניתוח סגנון.</p>;
  }

  return (
    <div className="space-y-3">
      {subtype && (
        <p className="text-[0.78rem] text-ink-muted">
          דפוסים בכלל הקורפוס. סינון לפי תת-סוג {subtype} ייושם בעדכון הבא.
        </p>
      )}
      {Object.entries(data).slice(0, 4).map(([type, items]) => (
        <Card key={type} className="bg-surface border-rule">
          <CardContent className="px-4 py-3">
            <h4 className="text-[0.78rem] uppercase tracking-wider text-gold-deep font-semibold mb-2">
              {type}
            </h4>
            <ul className="space-y-1 text-sm text-ink">
              {items.slice(0, 6).map((p, i) => (
                <li key={i} className="flex items-start gap-2">
                  <span className="text-[0.72rem] tabular-nums text-ink-muted shrink-0 mt-0.5">
                    ×{p.frequency}
                  </span>
                  <span>{p.pattern_text}</span>
                </li>
              ))}
            </ul>
          </CardContent>
        </Card>
      ))}
    </div>
  );
}
