"use client";

import React, { useEffect, useState, useRef } from "react";
import Link from "next/link";
import { useParams } from "next/navigation";
import {
  ArrowLeft,
  Pencil,
  Check,
  X,
  FolderKanban,
  Download,
  FileSpreadsheet,
  FileDown,
  ChevronDown,
  Loader2,
  Plus,
} from "lucide-react";
import { useI18n } from "@/lib/i18n/context";
import { useDashboardShell } from "@/components/dashboard/DashboardShellContext";
import { ProcessedReceipt, ReceiptCategory } from "@/lib/schema/receipt";
import {
  assignReceiptsToProject,
  deleteServerReceipt,
  deleteServerReceipts,
  fetchProject,
  fetchProjects,
  fetchServerReceipt,
  fetchServerReceipts,
  getCurrentUserId,
  renameProject,
  ServerProject,
} from "@/lib/storage/server";
import { usePersistReceipts } from "@/lib/hooks/usePersistReceipts";
import { RECEIPT_FILE_ACCEPT } from "@/lib/ingest/acceptedTypes";
import { LiveTable } from "@/components/dashboard/LiveTable";
import { ReceiptDetailModal } from "@/components/dashboard/ReceiptDetailModal";
import { FilterChipsBar } from "@/components/dashboard/FilterChipsBar";
import { KPICards } from "@/components/dashboard/KPICards";
import { useReceiptFilters } from "@/lib/hooks/useReceiptFilters";
import { useTableSelection } from "@/lib/hooks/useTableSelection";
import { ReceiptStatusTier } from "@/components/dashboard/StatusBadge";
import { GlobalDropzoneOverlay } from "@/components/dashboard/GlobalDropzoneOverlay";
import { BatchUploadDrawer } from "@/components/dashboard/BatchUploadDrawer";
import { apiFetch } from "@/lib/csrf/client";

function downloadBlob(blob: Blob, fileName: string) {
  const url = window.URL.createObjectURL(blob);
  const a = document.createElement("a");
  a.href = url;
  a.download = fileName;
  document.body.appendChild(a);
  a.click();
  window.URL.revokeObjectURL(url);
  a.remove();
}

export default function ProjectDetailPage() {
  const { language } = useI18n();
  const isDe = language === "de";
  const { openPaywall } = useDashboardShell();
  const params = useParams<{ projectId: string }>();
  const projectId = params.projectId;

  const [isPro, setIsPro] = useState(false);
  const [project, setProject] = useState<ServerProject | null>(null);
  const [projectNotFound, setProjectNotFound] = useState(false);
  const [allProjects, setAllProjects] = useState<ServerProject[]>([]);
  const [allReceipts, setAllReceipts] = useState<ProcessedReceipt[]>([]);
  const [userId, setUserId] = useState<string>("guest_default");
  const [selectedReceipt, setSelectedReceipt] = useState<ProcessedReceipt | null>(null);
  const [isRenaming, setIsRenaming] = useState(false);
  const [renameValue, setRenameValue] = useState("");

  // Export State
  const [isExportOpen, setIsExportOpen] = useState(false);
  const [isExporting, setIsExporting] = useState<"xlsx" | "csv" | "pdf" | null>(null);
  const exportDropdownRef = useRef<HTMLDivElement>(null);

  // Batch Ingestion State
  const [batchFiles, setBatchFiles] = useState<File[]>([]);
  const [isBatchDrawerOpen, setIsBatchDrawerOpen] = useState(false);
  const fileInputRef = useRef<HTMLInputElement>(null);
  const persistReceipts = usePersistReceipts(userId);

  const projectReceipts = allReceipts.filter((r) => r.projectId === projectId);
  const filterHook = useReceiptFilters(projectReceipts);
  const selectionHook = useTableSelection();

  useEffect(() => {
    let active = true;
    async function load() {
      try {
        const res = await apiFetch("/api/auth/session");
        const data = res.ok ? await res.json() : null;
        if (active) setIsPro(Boolean(data?.user?.isPro));
      } catch {
        if (active) setIsPro(false);
      }

      const uid = await getCurrentUserId();
      const [proj, receiptsList, projectRows] = await Promise.all([
        fetchProject(projectId),
        fetchServerReceipts(uid),
        fetchProjects(),
      ]);
      if (!active) return;
      setUserId(uid);
      setProjectNotFound(!proj);
      setProject(proj);
      setAllReceipts(receiptsList);
      setAllProjects(projectRows);
    }
    load();
    return () => {
      active = false;
    };
  }, [projectId]);

  const handleUpdateReceipt = async (updated: ProcessedReceipt) => {
    setAllReceipts((prev) => prev.map((r) => (r.id === updated.id ? updated : r)));
    await persistReceipts([updated]);
  };

  const handleDeleteReceipt = async (id: string) => {
    setAllReceipts((prev) => prev.filter((r) => r.id !== id));
    selectionHook.deselectOne(id);
    await deleteServerReceipt(id);
  };

  const handleBulkDelete = async (ids: string[]) => {
    setAllReceipts((prev) => prev.filter((r) => !ids.includes(r.id)));
    selectionHook.clearSelection();
    await deleteServerReceipts(ids);
  };

  const handleBulkCategorize = async (ids: string[], category: ReceiptCategory) => {
    const updated = allReceipts.map((r) =>
      ids.includes(r.id) ? { ...r, suggestedCategory: category } : r
    );
    setAllReceipts(updated);
    await persistReceipts(updated.filter((r) => ids.includes(r.id)));
    selectionHook.clearSelection();
  };

  const handleBulkStatusUpdate = async (ids: string[], status: ReceiptStatusTier) => {
    const updatedList: ProcessedReceipt[] = allReceipts.map((r) => {
      if (!ids.includes(r.id)) return r;
      if (status === "pending_review") {
        return {
          ...r,
          status: "needs_review" as const,
          validation: { ...r.validation, needsUserReview: true, userConfirmed: false },
        };
      }
      return {
        ...r,
        status: "ready" as const,
        validation: { ...r.validation, needsUserReview: false, userConfirmed: true },
      };
    });
    setAllReceipts(updatedList);
    await persistReceipts(updatedList.filter((r) => ids.includes(r.id)));
    selectionHook.clearSelection();
  };

  const handleBulkMoveToProject = async (ids: string[], targetProjectId: string | null) => {
    setAllReceipts((prev) =>
      prev.map((r) => (ids.includes(r.id) ? { ...r, projectId: targetProjectId } : r))
    );
    await assignReceiptsToProject(ids, targetProjectId);
    selectionHook.clearSelection();
  };

  const openRename = () => {
    if (!isPro) {
      openPaywall();
      return;
    }
    if (project) setRenameValue(project.name);
    setIsRenaming(true);
  };

  const handleRename = async () => {
    const name = renameValue.trim();
    setIsRenaming(false);
    if (!name || !project || name === project.name) return;
    const updated = await renameProject(project.id, { name });
    if (updated) setProject((prev) => (prev ? { ...prev, name: updated.name } : prev));
  };

  if (!project && !projectNotFound) {
    return (
      <div className="flex items-center justify-center py-24">
        <div className="w-6 h-6 border-2 border-[#E2E8F0] border-t-[#161C22] rounded-full animate-spin" />
      </div>
    );
  }

  if (projectNotFound || !project) {
    return (
      <div className="max-w-xl mx-auto mt-12 text-center space-y-4 font-sans">
        <FolderKanban className="w-10 h-10 mx-auto text-[#94A3B8]" />
        <h1 className="font-display text-2xl font-bold text-black">
          {isDe ? "Projekt nicht gefunden" : "Project not found"}
        </h1>
        <Link
          href="/dashboard/projects"
          className="inline-flex items-center gap-1.5 font-mono text-xs uppercase tracking-caps text-black hover:underline"
        >
          <ArrowLeft className="w-3.5 h-3.5" />
          {isDe ? "Zurück zu Projekten" : "Back to Projects"}
        </Link>
      </div>
    );
  }

  const handleExport = async (kind: "xlsx" | "csv" | "pdf") => {
    if (projectReceipts.length === 0) return;
    if (!isPro) {
      openPaywall();
      return;
    }
    setIsExporting(kind);
    setIsExportOpen(false);
    try {
      const today = new Date().toISOString().split("T")[0];
      const safeName = (project?.name || "Projekt").replace(/[^a-zA-Z0-9_-]/g, "_");
      const endpoint =
        kind === "xlsx"
          ? "/api/export/excel"
          : kind === "pdf"
          ? "/api/export/pdf"
          : "/api/export/csv";
      const fallbackName =
        kind === "xlsx"
          ? `${safeName}_${today}.xlsx`
          : kind === "pdf"
          ? `${safeName}_${today}.pdf`
          : `${safeName}_${today}.csv`;

      const res = await apiFetch(endpoint, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ receipts: projectReceipts, locale: language }),
      });

      if (res.status === 401 || res.status === 403) {
        openPaywall();
        return;
      }
      if (!res.ok) throw new Error("Export failed");
      const blob = await res.blob();
      downloadBlob(blob, fallbackName);
    } catch (err) {
      console.error(err);
      alert(isDe ? "Export fehlgeschlagen." : "Export failed.");
    } finally {
      setIsExporting(null);
    }
  };

  const handleFilesSelected = (files: File[]) => {
    if (!files || files.length === 0) return;
    setBatchFiles(files);
    setIsBatchDrawerOpen(true);
  };

  const handleReceiptProcessed = (receipt: ProcessedReceipt) => {
    const assignedReceipt = { ...receipt, projectId: receipt.projectId || projectId };
    setAllReceipts((prev) => {
      if (prev.some((r) => r.id === assignedReceipt.id)) {
        return prev.map((r) => (r.id === assignedReceipt.id ? assignedReceipt : r));
      }
      return [assignedReceipt, ...prev];
    });
    void persistReceipts([assignedReceipt]);
  };

  const handleBatchComplete = (completed: ProcessedReceipt[]) => {
    setAllReceipts((prev) => {
      const existingIds = new Set(prev.map((r) => r.id));
      const toAdd = completed
        .filter((r) => !existingIds.has(r.id))
        .map((r) => ({ ...r, projectId: r.projectId || projectId }));
      return [...toAdd, ...prev];
    });
  };

  const otherProjects = allProjects.filter((p) => p.id !== projectId);

  return (
    <div className="space-y-6 sm:space-y-8 font-sans overflow-x-hidden w-full">
      {/* Global Drag & Drop Overlay */}
      <GlobalDropzoneOverlay onFilesDropped={handleFilesSelected} />

      {/* Batch Upload Drawer pre-populated for this project */}
      <BatchUploadDrawer
        isOpen={isBatchDrawerOpen}
        onClose={() => setIsBatchDrawerOpen(false)}
        files={batchFiles}
        existingReceipts={allReceipts}
        onReceiptProcessed={handleReceiptProcessed}
        onComplete={handleBatchComplete}
        projects={allProjects}
      />

      {/* Header */}
      <div className="space-y-3 pb-6 border-b border-[#E2E8F0]">
        <Link
          href="/dashboard/projects"
          className="inline-flex items-center gap-1.5 font-mono text-xs uppercase tracking-caps text-[#64748B] hover:text-black"
        >
          <ArrowLeft className="w-3.5 h-3.5" />
          {isDe ? "Alle Projekte" : "All Projects"}
        </Link>

        <div className="flex flex-col sm:flex-row sm:items-center justify-between gap-3">
          <div className="flex items-center gap-3 min-w-0">
            {isRenaming ? (
              <div className="flex items-center gap-2">
                <input
                  autoFocus
                  value={renameValue}
                  onChange={(e) => setRenameValue(e.target.value)}
                  onKeyDown={(e) => {
                    if (e.key === "Enter") void handleRename();
                    if (e.key === "Escape") setIsRenaming(false);
                  }}
                  className="font-display text-2xl sm:text-3xl font-bold tracking-tight text-black border-b-2 border-black focus:outline-none bg-transparent"
                />
                <button type="button" onClick={() => void handleRename()} className="p-1 text-emerald-600 hover:bg-emerald-50">
                  <Check className="w-5 h-5" />
                </button>
                <button type="button" onClick={() => setIsRenaming(false)} className="p-1 text-[#94A3B8] hover:bg-[#F8FAFC]">
                  <X className="w-5 h-5" />
                </button>
              </div>
            ) : (
              <>
                <h1 className="font-display text-2xl sm:text-3xl font-bold tracking-tight text-black truncate">
                  {project.name}
                </h1>
                <button
                  type="button"
                  onClick={openRename}
                  className="p-1.5 text-[#94A3B8] hover:text-black hover:bg-[#F8FAFC] shrink-0"
                  aria-label={isDe ? "Umbenennen" : "Rename"}
                >
                  <Pencil className="w-4 h-4" />
                </button>
              </>
            )}
          </div>

          <div className="flex items-center gap-2.5 flex-wrap">
            <input
              type="file"
              ref={fileInputRef}
              onChange={(e) => {
                if (e.target.files && e.target.files.length > 0) {
                  handleFilesSelected(Array.from(e.target.files));
                }
                if (fileInputRef.current) fileInputRef.current.value = "";
              }}
              accept={RECEIPT_FILE_ACCEPT}
              multiple
              className="hidden"
            />
            <button
              type="button"
              onClick={() => fileInputRef.current?.click()}
              className="px-3.5 py-2 bg-white border border-[#E2E8F0] hover:border-black text-black font-mono text-xs uppercase tracking-caps transition-colors font-medium flex items-center gap-1.5"
            >
              <Plus className="w-3.5 h-3.5" />
              <span>{isDe ? "Beleg hinzufügen" : "Add Receipt"}</span>
            </button>

            {/* Export dropdown */}
            <div className="relative" ref={exportDropdownRef}>
              <button
                type="button"
                onClick={() => setIsExportOpen(!isExportOpen)}
                disabled={isExporting !== null || projectReceipts.length === 0}
                className="px-4 py-2 bg-black text-white font-mono text-xs uppercase tracking-caps hover:bg-[#334155] transition-colors font-medium flex items-center gap-2 disabled:opacity-40"
              >
                {isExporting ? (
                  <Loader2 className="w-3.5 h-3.5 animate-spin" />
                ) : (
                  <Download className="w-3.5 h-3.5" />
                )}
                <span>{isDe ? "EXPORTIEREN" : "EXPORT"}</span>
                <ChevronDown className="w-3.5 h-3.5" />
              </button>

              {isExportOpen && (
                <div className="absolute right-0 top-full mt-1 z-30 w-56 bg-white border-2 border-black shadow-xl font-mono text-xs animate-fade-in divide-y divide-[#E2E8F0]">
                  <div className="p-2 bg-[#F8FAFC] text-[10px] uppercase text-[#64748B]">
                    {isDe ? "Projekt exportieren" : "Export Project"}
                  </div>
                  <button
                    type="button"
                    onClick={() => void handleExport("xlsx")}
                    className="w-full text-left px-3 py-2 hover:bg-[#F8FAFC] flex items-center gap-2 text-black transition-colors"
                  >
                    <FileSpreadsheet className="w-3.5 h-3.5 text-emerald-600" />
                    <span>Excel (.xlsx)</span>
                  </button>
                  <button
                    type="button"
                    onClick={() => void handleExport("csv")}
                    className="w-full text-left px-3 py-2 hover:bg-[#F8FAFC] flex items-center gap-2 text-black transition-colors"
                  >
                    <Download className="w-3.5 h-3.5 text-blue-600" />
                    <span>{isDe ? "CSV (.csv)" : "CSV (.csv)"}</span>
                  </button>
                  <button
                    type="button"
                    onClick={() => void handleExport("pdf")}
                    className="w-full text-left px-3 py-2 hover:bg-[#F8FAFC] flex items-center gap-2 text-black transition-colors"
                  >
                    <FileDown className="w-3.5 h-3.5 text-red-600" />
                    <span>{isDe ? "PDF-Report (.pdf)" : "PDF Report (.pdf)"}</span>
                  </button>
                  <Link
                    href={`/dashboard/export?projectId=${projectId}`}
                    className="w-full text-left px-3 py-2 hover:bg-[#F8FAFC] flex items-center gap-2 text-[#475569] text-[11px] block border-t border-[#E2E8F0]"
                  >
                    <span>{isDe ? "In Export Control öffnen →" : "Open in Export Control →"}</span>
                  </Link>
                </div>
              )}
            </div>

            <span className="font-mono text-xs uppercase tracking-caps text-[#64748B] shrink-0 ml-1">
              {projectReceipts.length}{" "}
              {isDe
                ? projectReceipts.length === 1
                  ? "Beleg"
                  : "Belege"
                : projectReceipts.length === 1
                ? "receipt"
                : "receipts"}
            </span>
          </div>
        </div>
      </div>

      {projectReceipts.length === 0 ? (
        <div className="border border-dashed border-[#CBD5E1] p-12 text-center space-y-2">
          <FolderKanban className="w-8 h-8 mx-auto text-[#94A3B8]" />
          <p className="text-sm text-[#475569]">
            {isDe ? "Dieses Projekt enthält noch keine Belege." : "This project has no receipts yet."}
          </p>
          <p className="text-xs text-[#94A3B8]">
            {isDe
              ? 'Wähle Belege im Hauptdashboard aus und nutze "Projekt zuweisen", um sie hierher zu verschieben.'
              : 'Select receipts on the main dashboard and use "Move to Project" to bring them here.'}
          </p>
          <Link
            href="/dashboard"
            className="inline-block mt-2 font-mono text-xs uppercase tracking-caps text-black underline"
          >
            {isDe ? "Zum Hauptdashboard" : "Go to main dashboard"}
          </Link>
        </div>
      ) : (
        <>
          <KPICards
            receipts={projectReceipts}
            activePeriod={String(filterHook.activePeriod)}
            customDateRange={filterHook.customDateRange}
            activeStatus={filterHook.activeStatus}
            onFilterPeriod={(period) => filterHook.setPeriod(period)}
            onFilterStatus={(status) => filterHook.setStatus(status)}
            onResetFilters={filterHook.resetFilters}
          />

          <FilterChipsBar filterHook={filterHook} />

          <div className="w-full overflow-x-auto">
            <LiveTable
              receipts={filterHook.filteredReceipts}
              selectedIds={selectionHook.selectedIds}
              onToggleSelect={selectionHook.toggleSelect}
              onToggleSelectAll={() =>
                selectionHook.toggleSelectAll(filterHook.filteredReceipts.map((r) => r.id))
              }
              onClearSelection={selectionHook.clearSelection}
              onBulkDelete={handleBulkDelete}
              onBulkCategorize={handleBulkCategorize}
              onBulkStatusUpdate={handleBulkStatusUpdate}
              onUpdateReceipt={handleUpdateReceipt}
              onDeleteReceipt={handleDeleteReceipt}
              onViewDetails={async (rcpt) => {
                if (rcpt.previewUrl) {
                  setSelectedReceipt(rcpt);
                  return;
                }
                const full = await fetchServerReceipt(rcpt.id);
                setSelectedReceipt(full ?? rcpt);
              }}
              projects={otherProjects}
              onBulkMoveToProject={handleBulkMoveToProject}
            />
          </div>
        </>
      )}

      {selectedReceipt && (
        <ReceiptDetailModal
          receipt={selectedReceipt}
          currentIndex={projectReceipts.findIndex((r) => r.id === selectedReceipt.id)}
          totalCount={projectReceipts.length}
          onPersist={async (updated) => {
            await persistReceipts([updated]);
          }}
          onNavigate={async (direction) => {
            const currentIdx = projectReceipts.findIndex((r) => r.id === selectedReceipt.id);
            if (currentIdx === -1) return;
            const nextIdx =
              direction === "prev"
                ? Math.max(0, currentIdx - 1)
                : Math.min(projectReceipts.length - 1, currentIdx + 1);
            const next = projectReceipts[nextIdx];
            if (next.previewUrl) {
              setSelectedReceipt(next);
              return;
            }
            const full = await fetchServerReceipt(next.id);
            setSelectedReceipt(full ?? next);
          }}
          onClose={() => setSelectedReceipt(null)}
          onSave={handleUpdateReceipt}
        />
      )}
    </div>
  );
}
