"use client";

import { useEffect, useState } from "react";
import { Upload, Loader2, CheckCircle2, AlertCircle, Trash2, RefreshCw } from "lucide-react";
import { toast } from "sonner";
import { useQueryClient } from "@tanstack/react-query";
import {
  Sheet, SheetContent, SheetHeader, SheetTitle, SheetDescription,
} from "@/components/ui/sheet";
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 {
  Select, SelectContent, SelectItem, SelectTrigger, SelectValue,
} from "@/components/ui/select";
import { Progress } from "@/components/ui/progress";
import {
  useUploadPrecedent, useUploadInternalDecision, useDeletePrecedent,
  useRequestHalachotExtraction, libraryKeys,
  isCommitteeCitation, COMMITTEE_DISTRICTS,
  type PracticeArea, type SourceType, type CommitteeDistrict,
} from "@/lib/api/precedent-library";
import { ApiError } from "@/lib/api/client";
import { useProgress } from "@/lib/api/documents";
import { formatDateShort } from "@/lib/format-date";
import {
  PRACTICE_AREAS, PRECEDENT_LEVELS, SOURCE_TYPES,
} from "./practice-area";

const ACCEPT = ".pdf,.docx,.doc,.rtf,.txt,.md";

type DuplicateConflict = {
  error: string;
  case_law_id: string;
  citation: string;
  case_name: string;
  court: string;
  date: string | null;
  halacha_extraction_status: string;
};

type Props = {
  open: boolean;
  onOpenChange: (open: boolean) => void;
};

export function PrecedentUploadSheet({ open, onOpenChange }: Props) {
  const [file, setFile] = useState<File | null>(null);
  const [citation, setCitation] = useState("");
  const [caseName, setCaseName] = useState("");
  const [court, setCourt] = useState("");
  const [decisionDate, setDecisionDate] = useState("");
  const [sourceType, setSourceType] = useState<SourceType>("");
  const [precedentLevel, setPrecedentLevel] = useState("");
  const [practiceArea, setPracticeArea] = useState<PracticeArea>("");
  const [appealSubtype, setAppealSubtype] = useState("");
  const [subjectTags, setSubjectTags] = useState("");
  const [headnote, setHeadnote] = useState("");
  const [isBinding, setIsBinding] = useState(true);

  const [chairName, setChairName] = useState("");
  const [district, setDistrict] = useState<CommitteeDistrict | "">("");
  const [caseNumber, setCaseNumber] = useState("");
  const isCommittee = isCommitteeCitation(citation);

  const [taskId, setTaskId] = useState<string | null>(null);
  const [conflict, setConflict] = useState<DuplicateConflict | null>(null);

  const upload = useUploadPrecedent();
  const uploadInternal = useUploadInternalDecision();
  const deletePrecedent = useDeletePrecedent();
  const requestHalachot = useRequestHalachotExtraction();
  const progress = useProgress(taskId);
  const qc = useQueryClient();

  useEffect(() => {
    if (open) return;
    // eslint-disable-next-line react-hooks/set-state-in-effect -- reset form on close
    setFile(null); setCitation(""); setCaseName(""); setCourt("");
    setDecisionDate(""); setSourceType(""); setPrecedentLevel("");
    setPracticeArea(""); setAppealSubtype(""); setSubjectTags("");
    setHeadnote(""); setIsBinding(true); setTaskId(null); setConflict(null);
    setChairName(""); setDistrict(""); setCaseNumber("");
  }, [open]);

  useEffect(() => {
    if (progress?.status === "completed") {
      qc.invalidateQueries({ queryKey: libraryKeys.all });
      toast.success("הפסיקה הוכנסה לקורפוס. ההלכות ממתינות לאישור.");
      const t = window.setTimeout(() => onOpenChange(false), 1200);
      return () => window.clearTimeout(t);
    }
    if (progress?.status === "failed") {
      qc.invalidateQueries({ queryKey: libraryKeys.all });
      toast.error(`כשל בעיבוד: ${progress.error || "שגיאה לא ידועה"}`);
    }
  }, [progress, onOpenChange, qc]);

  const onSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    if (!file) { toast.error("בחר קובץ"); return; }
    if (!citation.trim()) { toast.error("מראה המקום (citation) חובה"); return; }
    setConflict(null);

    const tags = subjectTags.split(",").map((t) => t.trim()).filter(Boolean);

    try {
      if (isCommittee) {
        if (!caseNumber.trim()) { toast.error("מספר תיק חובה להחלטת ועדת ערר"); return; }
        if (!chairName.trim()) { toast.error("שם יו\"ר חובה להחלטת ועדת ערר"); return; }
        if (!district) { toast.error("מחוז חובה להחלטת ועדת ערר"); return; }
        const res = await uploadInternal.mutateAsync({
          file, case_number: caseNumber.trim(), citation: citation.trim(),
          chair_name: chairName.trim(), district, case_name: caseName.trim(),
          court: court.trim(), decision_date: decisionDate || undefined,
          practice_area: practiceArea, appeal_subtype: appealSubtype.trim(),
          subject_tags: tags, is_binding: false, summary: headnote.trim(),
        });
        setTaskId(res.task_id);
        return;
      }

      const res = await upload.mutateAsync({
        file, citation: citation.trim(), case_name: caseName.trim(),
        court: court.trim(), decision_date: decisionDate || undefined,
        source_type: sourceType || undefined, precedent_level: precedentLevel || undefined,
        practice_area: practiceArea, appeal_subtype: appealSubtype.trim(),
        subject_tags: tags, is_binding: isBinding, headnote: headnote.trim(),
      });
      setTaskId(res.task_id);
    } catch (err) {
      if (err instanceof ApiError && err.status === 409) {
        const body = err.body as { detail?: DuplicateConflict } | null;
        if (body?.detail?.error === "duplicate_external_upload") {
          setConflict(body.detail!);
          return;
        }
      }
      toast.error(err instanceof Error ? err.message : "כשל בהעלאה");
    }
  };

  const handleDelete = async () => {
    if (!conflict) return;
    if (!window.confirm("למחוק את הרשומה הקיימת? פעולה זו תמחק גם את כל ההלכות שחולצו ממנה.")) return;
    try {
      await deletePrecedent.mutateAsync(conflict.case_law_id);
      toast.success("הרשומה נמחקה — כעת ניתן להעלות מחדש");
      setConflict(null);
    } catch (e) {
      toast.error(e instanceof Error ? e.message : "שגיאה במחיקה");
    }
  };

  const handleReextract = async () => {
    if (!conflict) return;
    try {
      await requestHalachot.mutateAsync(conflict.case_law_id);
      toast.success("חילוץ הלכות הועמד בתור — ההלכות החדשות יופיעו בתור האישור");
      qc.invalidateQueries({ queryKey: libraryKeys.all });
      onOpenChange(false);
    } catch (e) {
      toast.error(e instanceof Error ? e.message : "שגיאה בהפעלת חילוץ");
    }
  };

  const isProcessing = taskId !== null && progress?.status !== "completed" && progress?.status !== "failed";
  const isSubmitting = upload.isPending || uploadInternal.isPending;
  const stage = (progress as { stage?: string; percent?: number; step?: string } | null)?.stage;
  const percent = (progress as { percent?: number } | null)?.percent ?? 0;

  return (
    <Sheet open={open} onOpenChange={onOpenChange}>
      <SheetContent side="left" className="w-full sm:max-w-2xl overflow-y-auto" dir="rtl">
        <SheetHeader>
          <SheetTitle className="text-navy">העלאת פסיקה לקורפוס הסמכותי</SheetTitle>
          <SheetDescription className="text-ink-muted">
            הקובץ יעבור חילוץ טקסט, embeddings, וחילוץ אוטומטי של מטא־דאטה
            (שם, ערכאה, תאריך, תחום, תת־סוג, תגיות) והלכות. ההלכות ימתינו
            לאישורך לפני שיהיו זמינות לסוכני הכתיבה.
          </SheetDescription>
        </SheetHeader>

        {/* ─── Conflict banner ─── */}
        {conflict && (
          <div className="mx-6 mt-4 rounded-lg border border-danger bg-danger-bg p-4 space-y-3">
            <div className="flex items-start gap-2">
              <AlertCircle className="w-5 h-5 text-danger shrink-0 mt-0.5" />
              <div className="space-y-1 flex-1 min-w-0">
                <p className="font-semibold text-danger text-sm">הפסיקה כבר קיימת במאגר</p>
                <p className="text-danger/80 text-[0.78rem]" dir="rtl">
                  {conflict.citation}
                  {conflict.case_name && ` — ${conflict.case_name}`}
                  {conflict.court && ` · ${conflict.court}`}
                  {conflict.date && ` · ${formatDateShort(conflict.date)}`}
                </p>
                {conflict.halacha_extraction_status && (
                  <p className="text-danger/60 text-[0.72rem]">
                    סטטוס חילוץ הלכות: {conflict.halacha_extraction_status}
                  </p>
                )}
              </div>
            </div>
            <div className="flex gap-2 justify-end">
              <Button
                size="sm" variant="ghost"
                onClick={() => setConflict(null)}
                className="text-ink-muted"
              >
                ביטול
              </Button>
              <Button
                size="sm" variant="outline"
                onClick={handleReextract}
                disabled={requestHalachot.isPending}
                className="border-danger/40 text-danger hover:bg-danger-bg"
              >
                {requestHalachot.isPending
                  ? <Loader2 className="w-3.5 h-3.5 animate-spin me-1" />
                  : <RefreshCw className="w-3.5 h-3.5 me-1" />}
                הפעל חילוץ מחדש
              </Button>
              <Button
                size="sm"
                onClick={handleDelete}
                disabled={deletePrecedent.isPending}
                className="bg-danger text-white hover:bg-danger/90"
              >
                {deletePrecedent.isPending
                  ? <Loader2 className="w-3.5 h-3.5 animate-spin me-1" />
                  : <Trash2 className="w-3.5 h-3.5 me-1" />}
                מחק את הרשומה
              </Button>
            </div>
          </div>
        )}

        <form onSubmit={onSubmit} className="px-6 pb-6 space-y-4 mt-4">
          {/* File */}
          <div className="space-y-1">
            <Label htmlFor="file">קובץ (PDF / DOCX / DOC / RTF / TXT / MD)</Label>
            <Input
              id="file" type="file" accept={ACCEPT}
              onChange={(e) => setFile(e.target.files?.[0] ?? null)}
              disabled={isProcessing}
            />
          </div>

          {/* Citation */}
          <div className="space-y-1">
            <Label htmlFor="citation">מראה המקום (חובה)</Label>
            <Input
              id="citation" value={citation}
              onChange={(e) => { setCitation(e.target.value); setConflict(null); }}
              placeholder={`עע"מ 3975/22 ב. קרן-נכסים נ' ועדה מקומית`}
              disabled={isProcessing} dir="rtl"
            />
            {isCommittee && (
              <p className="text-[0.72rem] text-ink-muted">
                זוהתה כהחלטת ועדת ערר — נדרשים שם יו&quot;ר ומחוז (למטה).
              </p>
            )}
          </div>

          {isCommittee && (
            <div className="space-y-3 rounded-md border border-gold/40 bg-gold-wash/40 p-3">
              <div className="space-y-1">
                <Label htmlFor="committee-case-number">מספר תיק — מזהה ייחודי (חובה)</Label>
                <Input
                  id="committee-case-number" value={caseNumber}
                  onChange={(e) => setCaseNumber(e.target.value)}
                  placeholder="8027-25"
                  disabled={isProcessing} dir="rtl"
                />
                <p className="text-[0.72rem] text-ink-muted">
                  המזהה הנקי בלבד (למשל 8027-25) — לא המראה-מקום המלא.
                </p>
              </div>
              <div className="grid grid-cols-2 gap-3">
              <div className="space-y-1">
                <Label htmlFor="chair-name">שם יו&quot;ר (חובה)</Label>
                <Input
                  id="chair-name" value={chairName}
                  onChange={(e) => setChairName(e.target.value)}
                  placeholder='עו"ד פלוני אלמוני'
                  disabled={isProcessing} dir="rtl"
                />
              </div>
              <div className="space-y-1">
                <Label htmlFor="district">מחוז (חובה)</Label>
                <Select
                  value={district || "_none"}
                  onValueChange={(v) =>
                    setDistrict(v === "_none" ? "" : (v as CommitteeDistrict))
                  }
                  disabled={isProcessing}
                >
                  <SelectTrigger><SelectValue placeholder="—" /></SelectTrigger>
                  <SelectContent>
                    <SelectItem value="_none">—</SelectItem>
                    {COMMITTEE_DISTRICTS.map((d) => (
                      <SelectItem key={d} value={d}>{d}</SelectItem>
                    ))}
                  </SelectContent>
                </Select>
              </div>
              </div>
            </div>
          )}

          <details className="group rounded-md border border-rule bg-rule-soft/30">
            <summary className="cursor-pointer select-none px-3 py-2 text-[0.78rem] text-ink-muted hover:text-navy">
              אופציונלי — דריסה ידנית של שדות שיחולצו אוטומטית מהמסמך
            </summary>
            <div className="space-y-3 border-t border-rule px-3 py-3">
              <div className="grid grid-cols-2 gap-3">
                <div className="space-y-1">
                  <Label htmlFor="case-name">שם קצר</Label>
                  <Input id="case-name" value={caseName}
                    onChange={(e) => setCaseName(e.target.value)}
                    placeholder="ב. קרן-נכסים" disabled={isProcessing} />
                </div>
                <div className="space-y-1">
                  <Label htmlFor="court">ערכאה</Label>
                  <Input id="court" value={court}
                    onChange={(e) => setCourt(e.target.value)}
                    placeholder='בית משפט עליון / בג"ץ / מנהלי / ועדת ערר'
                    disabled={isProcessing} />
                </div>
                <div className="space-y-1">
                  <Label htmlFor="date">תאריך החלטה</Label>
                  <Input id="date" type="date" value={decisionDate}
                    onChange={(e) => setDecisionDate(e.target.value)}
                    disabled={isProcessing} />
                </div>
                <div className="space-y-1">
                  <Label htmlFor="appeal-subtype">תת-סוג (חופשי)</Label>
                  <Input id="appeal-subtype" value={appealSubtype}
                    onChange={(e) => setAppealSubtype(e.target.value)}
                    placeholder="שימוש חורג / סופיות ההחלטה" disabled={isProcessing} />
                </div>
              </div>

              <div className="space-y-1">
                <Label>תחום משפט</Label>
                <div className="flex gap-4 flex-wrap">
                  {PRACTICE_AREAS.map((a) => (
                    <label key={a.value} className="flex items-center gap-2 cursor-pointer">
                      <input
                        type="radio" name="practice_area" value={a.value}
                        checked={practiceArea === a.value}
                        onChange={() => setPracticeArea(a.value as PracticeArea)}
                        disabled={isProcessing}
                      />
                      <span className="text-sm text-ink">{a.label}</span>
                    </label>
                  ))}
                </div>
              </div>

              {!isCommittee && (
                <div className="grid grid-cols-2 gap-3">
                  <div className="space-y-1">
                    <Label htmlFor="source-type">סוג מקור</Label>
                    <Select value={sourceType || "_none"}
                      onValueChange={(v) => setSourceType(v === "_none" ? "" : v as SourceType)}
                      disabled={isProcessing}>
                      <SelectTrigger><SelectValue placeholder="—" /></SelectTrigger>
                      <SelectContent>
                        <SelectItem value="_none">—</SelectItem>
                        {SOURCE_TYPES.map((s) => (
                          <SelectItem key={s.value} value={s.value}>{s.label}</SelectItem>
                        ))}
                      </SelectContent>
                    </Select>
                  </div>
                  <div className="space-y-1">
                    <Label htmlFor="precedent-level">רמת תקדים</Label>
                    <Select value={precedentLevel || "_none"}
                      onValueChange={(v) => setPrecedentLevel(v === "_none" ? "" : v)}
                      disabled={isProcessing}>
                      <SelectTrigger><SelectValue placeholder="—" /></SelectTrigger>
                      <SelectContent>
                        <SelectItem value="_none">—</SelectItem>
                        {PRECEDENT_LEVELS.map((l) => (
                          <SelectItem key={l.value} value={l.value}>{l.label}</SelectItem>
                        ))}
                      </SelectContent>
                    </Select>
                  </div>
                </div>
              )}

              <div className="space-y-1">
                <Label htmlFor="tags">תגיות נושא (מופרדות בפסיקים)</Label>
                <Input id="tags" value={subjectTags}
                  onChange={(e) => setSubjectTags(e.target.value)}
                  placeholder="חניה, קווי בניין, שיקול דעת" disabled={isProcessing} />
              </div>

              <div className="space-y-1">
                <Label htmlFor="headnote">תקציר / headnote</Label>
                <Textarea id="headnote" value={headnote} rows={2}
                  onChange={(e) => setHeadnote(e.target.value)}
                  placeholder="תקציר חופשי שיוצג ברשימה" disabled={isProcessing} dir="rtl" />
              </div>

              <label className={`flex items-center gap-2 ${isCommittee ? "cursor-not-allowed opacity-60" : "cursor-pointer"}`}>
                <input type="checkbox" checked={isCommittee ? false : isBinding}
                  onChange={(e) => setIsBinding(e.target.checked)}
                  disabled={isProcessing || isCommittee} />
                <span className="text-sm">הלכה מחייבת</span>
              </label>
              {isCommittee && (
                <p className="text-[0.72rem] text-ink-muted">
                  החלטות ועדת ערר אינן מהוות הלכה מחייבת — ההלכות שיחולצו יסומנו כ&quot;משכנעת&quot; (persuasive).
                </p>
              )}
            </div>
          </details>

          {isProcessing && (
            <div className="rounded-lg border border-rule bg-rule-soft/40 p-4 space-y-2">
              <div className="flex items-center gap-2 text-sm text-navy">
                <Loader2 className="w-4 h-4 animate-spin" />
                <span>{(progress as { step?: string } | null)?.step || stage || "מעבד"}</span>
              </div>
              <Progress value={percent} className="h-1.5" />
            </div>
          )}

          {progress?.status === "completed" && (
            <div className="rounded-lg border border-gold/40 bg-gold-wash p-4 flex items-center gap-2 text-gold-deep text-sm">
              <CheckCircle2 className="w-4 h-4" />
              נכנס לקורפוס. ההלכות ממתינות בתור האישור.
            </div>
          )}

          {progress?.status === "failed" && (
            <div className="rounded-lg border border-danger/40 bg-danger-bg p-4 flex items-center gap-2 text-danger text-sm">
              <AlertCircle className="w-4 h-4" />
              {progress.error || "שגיאה"}
            </div>
          )}

          <div className="flex gap-2 justify-end pt-2">
            <Button type="button" variant="ghost"
              onClick={() => onOpenChange(false)} disabled={isSubmitting}>
              ביטול
            </Button>
            <Button type="submit"
              disabled={isSubmitting || isProcessing}
              className="bg-navy text-parchment hover:bg-navy-soft">
              <Upload className="w-4 h-4 me-1" />
              העלה
            </Button>
          </div>
        </form>
      </SheetContent>
    </Sheet>
  );
}
