"use client";

import React, { useEffect, useState, useRef } from "react";
import Link from "next/link";
import {
  FileSpreadsheet,
  UploadCloud,
  ArrowRight,
  Layers,
  CheckCircle2,
  X,
} from "lucide-react";
import { useI18n } from "@/lib/i18n/context";
import { ProcessedReceipt, ReceiptCategory } from "@/lib/schema/receipt";
import {
  assignReceiptsToProject,
  deleteServerReceipt,
  deleteServerReceipts,
  fetchProjects,
  fetchServerReceipt,
  fetchServerReceipts,
  getCurrentUserId,
  ServerProject,
} from "@/lib/storage/server";
import { usePersistReceipts } from "@/lib/hooks/usePersistReceipts";
import { LiveTable } from "@/components/dashboard/LiveTable";
import { ReceiptDetailModal } from "@/components/dashboard/ReceiptDetailModal";
import { GlobalDropzoneOverlay } from "@/components/dashboard/GlobalDropzoneOverlay";
import { BatchUploadDropzone } from "@/components/dashboard/BatchUploadDropzone";
import { BatchUploadDrawer } from "@/components/dashboard/BatchUploadDrawer";
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 { PaywallModal } from "@/components/paywall/PaywallModal";
import { Zap, ShieldCheck } from "lucide-react";
import { apiFetch } from "@/lib/csrf/client";
import { FREE_SCAN_LIMIT, LAUNCH_BONUS_SCANS } from "@/lib/limits";
import { RECEIPT_FILE_ACCEPT } from "@/lib/ingest/acceptedTypes";

export default function DashboardOverviewPage() {
  const { language } = useI18n();
  const isDe = language === "de";
  const [receipts, setReceipts] = useState<ProcessedReceipt[]>([]);
  const [projects, setProjects] = useState<ServerProject[]>([]);
  const [userId, setUserId] = useState<string>("guest_default");
  const [selectedReceipt, setSelectedReceipt] = useState<ProcessedReceipt | null>(null);

  // First-Scan Guide State
  const [isFirstScanGuided, setIsFirstScanGuided] = useState(false);

  // Quota & Paywall State
  const [isPaywallOpen, setIsPaywallOpen] = useState(false);
  const [quotaInfo, setQuotaInfo] = useState<{
    isPro: boolean;
    scanCount: number;
    scanLimit: number;
    launchBonus: boolean;
  }>({
    isPro: false,
    scanCount: 0,
    scanLimit: FREE_SCAN_LIMIT,
    launchBonus: false,
  });

  // Filter & Selection hooks
  const filterHook = useReceiptFilters(receipts);
  const selectionHook = useTableSelection();

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

  // Post-Stripe-redirect confirmation (?checkout_success=true from /api/checkout's success_url)
  const [checkoutConfirmation, setCheckoutConfirmation] = useState<"success" | "canceled" | null>(null);

  const refreshQuota = async () => {
    try {
      const res = await apiFetch("/api/auth/session");
      if (res.ok) {
        const data = await res.json();
        if (data?.user) {
          const u = data.user;
          const isPro = Boolean(u.isPro);
          const launchBonus = Boolean(u.launchBonus);
          const limit = isPro
            ? Infinity
            : launchBonus
            ? LAUNCH_BONUS_SCANS
            : (u.freeScanAllowance || FREE_SCAN_LIMIT);
          setQuotaInfo({
            isPro,
            scanCount: Number(u.scanCount ?? 0),
            scanLimit: limit,
            launchBonus,
          });
        }
      }
    } catch {}
  };

  useEffect(() => {
    async function loadData() {
      const uid = await getCurrentUserId();
      setUserId(uid);
      const stored = await fetchServerReceipts(uid);
      setReceipts(stored);
      await refreshQuota();
      const projectRows = await fetchProjects();
      setProjects(projectRows);
    }
    loadData();
  }, []);

  // One-time pickup of the Stripe redirect params, then scrub them from the
  // URL so a page refresh doesn't keep re-showing the confirmation.
  useEffect(() => {
    if (typeof window === "undefined") return;
    const params = new URLSearchParams(window.location.search);
    if (params.get("checkout_success") === "true") {
      setCheckoutConfirmation("success");
      void refreshQuota();
    } else if (params.get("checkout_canceled") === "true") {
      setCheckoutConfirmation("canceled");
    } else {
      return;
    }
    window.history.replaceState({}, "", window.location.pathname);
  }, []);

  // One-time pickup of the post-onboarding "first scan" guide flag: when the
  // user finishes onboarding we land on /dashboard?firstScan=1, which opens the
  // upload dropzone automatically so they can immediately capture a receipt.
  useEffect(() => {
    if (typeof window === "undefined") return;
    const params = new URLSearchParams(window.location.search);
    if (params.get("firstScan") === "1") {
      window.history.replaceState({}, "", window.location.pathname);
      setIsFirstScanGuided(true);
    }
  }, []);

  // When the first-scan guide is active, scroll the dropzone into view and
  // highlight it so the user can immediately capture their first receipt.
  const dropzoneRef = useRef<HTMLDivElement>(null);
  useEffect(() => {
    if (isFirstScanGuided) {
      const t = setTimeout(() => {
        dropzoneRef.current?.scrollIntoView({ behavior: "smooth", block: "center" });
      }, 300);
      return () => clearTimeout(t);
    }
  }, [isFirstScanGuided]);

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

  const handleReceiptProcessed = (receipt: ProcessedReceipt) => {
    setReceipts((prev) => {
      if (prev.some((r) => r.id === receipt.id)) return prev;
      return [receipt, ...prev];
    });
    void persistReceipts([receipt]);
    void refreshQuota();
  };

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

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

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

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

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

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

  const handleBulkStatusUpdate = async (ids: string[], status: ReceiptStatusTier) => {
    const updatedList: ProcessedReceipt[] = receipts.map((r) => {
      if (!ids.includes(r.id)) return r;
      if (status === "confirmed") {
        return {
          ...r,
          status: "ready" as const,
          validation: { ...r.validation, needsUserReview: false, userConfirmed: true },
        };
      }
      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 },
      };
    });
    setReceipts(updatedList);
    await persistReceipts(updatedList.filter((r) => ids.includes(r.id)));
    selectionHook.clearSelection();
  };

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

      {/* Batch Upload Drawer / Queue Tray */}
      <BatchUploadDrawer
        isOpen={isBatchDrawerOpen}
        onClose={() => setIsBatchDrawerOpen(false)}
        files={batchFiles}
        existingReceipts={receipts}
        onReceiptProcessed={handleReceiptProcessed}
        onComplete={handleBatchComplete}
        projects={projects}
      />

      {/* Post-Checkout Confirmation */}
      {checkoutConfirmation === "success" && (
        <div className="p-3.5 bg-emerald-50 border border-emerald-300 font-mono text-xs text-emerald-900 flex items-center justify-between gap-3">
          <span className="flex items-center gap-2">
            <CheckCircle2 className="w-4 h-4 text-emerald-600 shrink-0" />
            <span>
              {isDe
                ? "Zahlung erfolgreich — dein Pro-Zugang ist jetzt aktiv."
                : "Payment successful — your Pro access is now active."}
            </span>
          </span>
          <button
            type="button"
            onClick={() => setCheckoutConfirmation(null)}
            aria-label={isDe ? "Schließen" : "Dismiss"}
            className="shrink-0 text-emerald-700 hover:text-emerald-900"
          >
            <X className="w-3.5 h-3.5" />
          </button>
        </div>
      )}
      {checkoutConfirmation === "canceled" && (
        <div className="p-3.5 bg-[#F8FAFC] border border-[#E2E8F0] font-mono text-xs text-[#475569] flex items-center justify-between gap-3">
          <span>{isDe ? "Checkout abgebrochen — es wurde nichts berechnet." : "Checkout canceled — nothing was charged."}</span>
          <button
            type="button"
            onClick={() => setCheckoutConfirmation(null)}
            aria-label={isDe ? "Schließen" : "Dismiss"}
            className="shrink-0 text-[#64748B] hover:text-black"
          >
            <X className="w-3.5 h-3.5" />
          </button>
        </div>
      )}

      {/* Header Section */}
      <div className="flex flex-col sm:flex-row sm:items-center justify-between gap-4 pb-6 border-b border-[#E2E8F0]">
        <div>
          <div className="flex items-center gap-2 mb-1">
            <span className="w-2.5 h-2.5 bg-black"></span>
            <span className="font-mono text-xs uppercase tracking-caps font-semibold text-[#475569]">
              DASHBOARD OVERVIEW
            </span>
          </div>
          <h1 className="font-display text-2xl sm:text-3xl lg:text-4xl font-bold tracking-tight text-black">
            {isDe ? "Beleg- & Spesen-Zentrale" : "Expense & Ingestion Hub"}
          </h1>
        </div>

        <div className="flex flex-wrap items-center gap-2 sm:gap-3">
          <button
            onClick={() => fileInputRef.current?.click()}
            className="px-4 sm:px-5 py-2 sm:py-2.5 bg-black text-white font-mono text-xs uppercase tracking-caps hover:bg-[#334155] cursor-pointer flex items-center gap-2 transition-colors font-medium shadow-sm"
          >
            <UploadCloud className="w-4 h-4" />
            <span>{isDe ? "+ Beleg hochladen" : "+ Upload Receipt"}</span>
          </button>

          <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"
          />
        </div>
      </div>

      {/* Interactive KPI Statistics Cards with Click-to-Filter */}
      <KPICards
        receipts={receipts}
        activePeriod={String(filterHook.activePeriod)}
        customDateRange={filterHook.customDateRange}
        activeStatus={filterHook.activeStatus}
        onFilterPeriod={(period) => filterHook.setPeriod(period)}
        onFilterStatus={(status) => filterHook.setStatus(status)}
        onResetFilters={filterHook.resetFilters}
      />

      {/* Dedicated High-Visibility Batch Dropzone Card */}
      <div ref={dropzoneRef}>
        <BatchUploadDropzone
          onFilesSelected={handleFilesSelected}
          quotaInfo={quotaInfo}
          onOpenUpgrade={() => setIsPaywallOpen(true)}
          highlight={isFirstScanGuided}
          onHighlightDismiss={() => setIsFirstScanGuided(false)}
        />
      </div>

      {/* Main Table Preview & Quick Actions */}
      <div className="space-y-4 overflow-x-hidden w-full">
        <div className="flex flex-col sm:flex-row sm:items-center justify-between gap-3">
          <div className="flex items-center gap-2">
            <Layers className="w-4 h-4 text-black" />
            <span className="font-mono text-xs uppercase tracking-caps font-semibold text-black">
              {isDe ? "AKTUELLE BELEGE" : "RECENT RECEIPTS"} ({filterHook.filteredReceipts.length})
            </span>
          </div>

          <div className="flex flex-wrap items-center gap-3">
            <Link
              href="/dashboard/activity"
              className="font-mono text-xs uppercase tracking-caps text-black hover:underline flex items-center gap-1 font-medium"
            >
              <span>{isDe ? "Vollständiges Archiv öffnen" : "Open Full Archive"}</span>
              <ArrowRight className="w-3.5 h-3.5" />
            </Link>
            <Link
              href="/dashboard/export"
              className="px-3.5 py-1.5 bg-black text-white font-mono text-xs uppercase tracking-caps hover:bg-[#334155] flex items-center gap-1.5 shadow-sm"
            >
              <FileSpreadsheet className="w-3.5 h-3.5" />
              <span>{isDe ? "Exportieren" : "Export"}</span>
            </Link>
          </div>
        </div>

        {/* Filter Chips Bar */}
        <FilterChipsBar filterHook={filterHook} />

        {/* Live Table with horizontal scroll wrapper */}
        <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={projects}
            onBulkMoveToProject={handleBulkMoveToProject}
          />
        </div>
      </div>

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

      {/* Paywall Upgrade Modal */}
      <PaywallModal
        isOpen={isPaywallOpen}
        onClose={() => {
          setIsPaywallOpen(false);
          void refreshQuota();
        }}
        onSuccessUpgrade={() => {
          setIsPaywallOpen(false);
          void refreshQuota();
        }}
      />

      {/* Onboarding first-scan guide is handled by the layout redirect to
          /dashboard/onboarding; the dropzone auto-opens via ?firstScan=1. */}
    </div>
  );
}
