"use client";

import { useMemo, useState } from "react";
import {
  useCaseFiles,
  useCaseFileText,
  caseFileUrl,
  type CaseFileFolder,
} from "@/lib/api/case-files";
import { Markdown } from "@/components/ui/markdown";
import { Badge } from "@/components/ui/badge";
import { formatDateTime } from "@/lib/format-date";
import {
  Folder,
  FileText,
  File as FileIcon,
  Download,
  ChevronDown,
  Loader2,
  FolderOpen,
} from "lucide-react";

/* ── Helpers ─────────────────────────────────────────────────── */

const FOLDER_LABELS: Record<string, string> = {
  research: "מחקר וטיוטות",
  originals: "מסמכי מקור",
  extracted: "טקסט מחולץ (OCR)",
  proofread: "לאחר הגהה",
  drafts: "טיוטות DOCX",
  backup: "גיבויים",
};

// Extensions the inline viewer can render (everything else → download only).
const TEXT_EXT = new Set(["md", "txt", "json", "csv", "log", "markdown"]);

function fileExt(filename: string): string {
  return filename.includes(".") ? filename.split(".").pop()!.toLowerCase() : "";
}

function folderLabel(f: CaseFileFolder): string {
  return FOLDER_LABELS[f.name] ?? f.name;
}

function fmtSize(bytes: number): string {
  if (bytes < 1024) return `${bytes} B`;
  if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
  return `${(bytes / 1024 / 1024).toFixed(1)} MB`;
}

const EXT_TONE: Record<string, string> = {
  md: "bg-teal-100 text-teal-700",
  markdown: "bg-teal-100 text-teal-700",
  txt: "bg-blue-100 text-blue-700",
  json: "bg-blue-100 text-blue-700",
  pdf: "bg-red-100 text-red-700",
  docx: "bg-indigo-100 text-indigo-700",
  doc: "bg-indigo-100 text-indigo-700",
};
function extTone(ext: string): string {
  return EXT_TONE[ext] ?? "bg-gray-100 text-gray-600";
}

type Selected = { folderKey: string; filename: string };

/* ── Component ───────────────────────────────────────────────── */

export function CaseFilesBrowser({ caseNumber }: { caseNumber: string }) {
  const { data, isLoading, error } = useCaseFiles(caseNumber);
  const folders = useMemo(() => data?.folders ?? [], [data?.folders]);

  const totalFiles = folders.reduce((n, f) => n + f.files.length, 0);

  // Default selection derived (not via an effect): a text file in research,
  // else any text file. The chair's explicit pick overrides it.
  const defaultSelected = useMemo<Selected | null>(() => {
    const pick = (
      pred: (f: CaseFileFolder, name: string) => boolean,
    ): Selected | null => {
      for (const f of folders)
        for (const file of f.files)
          if (pred(f, file.filename))
            return { folderKey: f.key, filename: file.filename };
      return null;
    };
    return (
      pick((f, name) => f.name === "research" && TEXT_EXT.has(fileExt(name))) ??
      pick((_f, name) => TEXT_EXT.has(fileExt(name)))
    );
  }, [folders]);

  const [userSelected, setUserSelected] = useState<Selected | null>(null);
  const selected = userSelected ?? defaultSelected;

  // A folder is open if explicitly toggled; otherwise the folder of the current
  // selection (or the first non-empty folder) is open by default.
  const defaultOpenKey =
    selected?.folderKey ?? folders.find((f) => f.files.length)?.key ?? null;
  const [openOverrides, setOpenOverrides] = useState<Map<string, boolean>>(
    new Map(),
  );
  const isOpen = (key: string) =>
    openOverrides.has(key) ? openOverrides.get(key)! : key === defaultOpenKey;

  const selExt = selected ? fileExt(selected.filename) : "";
  const selIsText = TEXT_EXT.has(selExt);
  const {
    data: fileText,
    isLoading: textLoading,
    error: textError,
  } = useCaseFileText(
    caseNumber,
    selIsText ? selected?.folderKey : undefined,
    selIsText ? selected?.filename : undefined,
  );

  const toggleFolder = (key: string) => {
    const next = !isOpen(key);
    setOpenOverrides((prev) => new Map(prev).set(key, next));
  };

  if (isLoading) {
    return (
      <div className="flex items-center justify-center py-10 text-ink-faint">
        <Loader2 className="w-5 h-5 animate-spin me-2" />
        <span>טוען קבצים...</span>
      </div>
    );
  }
  if (error) {
    return (
      <div className="text-center py-10 text-red-500 text-sm">
        שגיאה בטעינת קבצי-התיק
      </div>
    );
  }

  return (
    <div className="border border-rule rounded-xl overflow-hidden">
      {/* header */}
      <div className="flex items-center gap-2 px-4 py-3 border-b border-rule-soft bg-parchment">
        <FolderOpen className="w-4 h-4 text-gold-deep" />
        <h3 className="text-sm font-bold text-navy">קבצי-התיק</h3>
        <span className="text-[11px] text-ink-muted ms-auto">
          כל תתי-התיקיות · {totalFiles} קבצים
        </span>
      </div>

      <div className="grid md:grid-cols-[320px_1fr]">
        {/* file tree */}
        <div className="border-b md:border-b-0 md:border-e border-rule-soft max-h-[560px] overflow-y-auto">
          {folders.map((f) => {
            const open = isOpen(f.key);
            return (
              <div key={f.key} className="border-b border-rule-soft last:border-b-0">
                <button
                  type="button"
                  onClick={() => toggleFolder(f.key)}
                  aria-expanded={open}
                  className="w-full flex items-center gap-2 px-3.5 py-2.5 hover:bg-sand-soft/60 text-start"
                >
                  <Folder className="w-4 h-4 text-gold-deep shrink-0" />
                  <span className="text-[0.78rem] font-bold text-navy">
                    {folderLabel(f)}
                  </span>
                  <span className="text-[9px] font-mono text-ink-faint hidden sm:inline">
                    {f.path}
                  </span>
                  <span
                    className={`text-[10px] font-semibold rounded-full px-2 ms-auto ${f.files.length ? "bg-gray-100 text-ink-muted" : "text-ink-light"}`}
                  >
                    {f.files.length || "ריק"}
                  </span>
                  <ChevronDown
                    className={`w-4 h-4 text-ink-faint shrink-0 transition-transform ${open ? "rotate-180" : ""}`}
                  />
                </button>

                {open && f.files.length > 0 && (
                  <div className="pb-1 bg-parchment/50">
                    {f.files.map((file) => {
                      const ext = fileExt(file.filename);
                      const isSel =
                        selected?.folderKey === f.key &&
                        selected?.filename === file.filename;
                      const viewable = TEXT_EXT.has(ext);
                      return (
                        <div
                          key={file.filename}
                          className={`flex items-center gap-2.5 py-1.5 pe-3.5 ps-5 cursor-pointer border-s-2 ${isSel ? "bg-gold-wash border-gold" : "border-transparent hover:bg-sand-soft/60"}`}
                          onClick={() =>
                            viewable
                              ? setUserSelected({
                                  folderKey: f.key,
                                  filename: file.filename,
                                })
                              : undefined
                          }
                        >
                          <span
                            className={`w-6 h-6 rounded-md flex items-center justify-center shrink-0 ${extTone(ext)}`}
                          >
                            {viewable ? (
                              <FileText className="w-3.5 h-3.5" />
                            ) : (
                              <FileIcon className="w-3.5 h-3.5" />
                            )}
                          </span>
                          <div className="min-w-0 flex-1">
                            <div className="text-[11.5px] font-medium text-ink-soft truncate">
                              {file.filename}
                            </div>
                            <div className="text-[9.5px] text-ink-light">
                              {fmtSize(file.size)} ·{" "}
                              {formatDateTime(file.modified_at * 1000)}
                            </div>
                          </div>
                          <a
                            href={caseFileUrl(caseNumber, f.key, file.filename)}
                            download={file.filename}
                            onClick={(e) => e.stopPropagation()}
                            className="w-7 h-7 rounded-md border border-rule bg-surface flex items-center justify-center text-ink-muted hover:text-navy shrink-0"
                            title="הורדה"
                          >
                            <Download className="w-3.5 h-3.5" />
                          </a>
                        </div>
                      );
                    })}
                  </div>
                )}
              </div>
            );
          })}
          {folders.length === 0 && (
            <div className="text-center py-10 text-ink-faint text-sm">
              אין קבצים בתיק.
            </div>
          )}
        </div>

        {/* viewer */}
        <div className="min-w-0 flex flex-col">
          {!selected ? (
            <div className="flex-1 flex flex-col items-center justify-center py-16 text-ink-faint text-sm">
              <FileText className="w-8 h-8 mb-2 opacity-40" />
              בחר קובץ טקסט מהרשימה לצפייה
            </div>
          ) : (
            <>
              <div className="flex items-center gap-2.5 px-4 py-3 border-b border-rule-soft">
                <span
                  className={`w-7 h-7 rounded-md flex items-center justify-center shrink-0 ${extTone(selExt)}`}
                >
                  <FileText className="w-4 h-4" />
                </span>
                <div className="min-w-0">
                  <div className="text-[12.5px] font-bold text-navy truncate">
                    {selected.filename}
                  </div>
                </div>
                <a
                  href={caseFileUrl(
                    caseNumber,
                    selected.folderKey,
                    selected.filename,
                  )}
                  download={selected.filename}
                  className="ms-auto inline-flex items-center gap-1.5 text-[11.5px] font-semibold text-navy bg-parchment border border-rule rounded-md px-3 py-1.5 hover:bg-sand-soft"
                >
                  <Download className="w-3.5 h-3.5" />
                  הורדה
                </a>
              </div>
              <div className="px-5 py-4 overflow-y-auto max-h-[520px] bg-[#fdfcf9]">
                {!selIsText ? (
                  <div className="text-center py-12 text-sm text-ink-muted">
                    קובץ מסוג <Badge variant="outline">{selExt || "?"}</Badge> —
                    לא ניתן לצפייה מוטבעת. הורד כדי לפתוח.
                  </div>
                ) : textLoading ? (
                  <div className="flex items-center justify-center py-12 text-ink-faint">
                    <Loader2 className="w-5 h-5 animate-spin me-2" />
                    טוען תוכן...
                  </div>
                ) : textError ? (
                  <div className="text-center py-12 text-red-500 text-sm">
                    שגיאה בטעינת תוכן הקובץ
                  </div>
                ) : selExt === "md" || selExt === "markdown" ? (
                  <Markdown content={fileText ?? ""} />
                ) : (
                  <pre className="whitespace-pre-wrap text-xs text-ink-soft font-mono leading-relaxed">
                    {fileText}
                  </pre>
                )}
              </div>
            </>
          )}
        </div>
      </div>
    </div>
  );
}
