"use client";

import { useRouter, useSearchParams } from "next/navigation";
import { Suspense, useEffect, useRef, useState } from "react";
import { Download, Merge } from "lucide-react";
import { toast } from "sonner";
import type { FileDto, ListFilesResponseDto, MergePdfResponseDto } from "@use2pdf/shared-types";
import { FileUploadDropzone } from "@/components/file-upload-dropzone";
import { MergeReorderList } from "@/components/merge-reorder-list";
import { SiteHeader } from "@/components/site-header";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { apiFetch, ApiRequestError, downloadFile } from "@/lib/api-client";
import { useAuth } from "@/lib/auth-context";
import { formatBytes } from "@/lib/format";

function MergePdfTool() {
  const { user, isLoading: authLoading } = useAuth();
  const router = useRouter();
  const searchParams = useSearchParams();

  const [files, setFiles] = useState<FileDto[]>([]);
  const [isMerging, setIsMerging] = useState(false);
  const [result, setResult] = useState<MergePdfResponseDto | null>(null);
  const preloadedRef = useRef(false);

  // Pre-populate from ?files=id1,id2 when arriving via the dashboard's
  // "Merge selected" button.
  useEffect(() => {
    if (preloadedRef.current || authLoading || !user) return;
    const preselected = searchParams.get("files");
    if (!preselected) {
      preloadedRef.current = true;
      return;
    }
    preloadedRef.current = true;

    (async () => {
      try {
        const data = await apiFetch<ListFilesResponseDto>("/files?page=1&pageSize=100");
        const wantedIds = preselected.split(",");
        const byId = new Map(data.files.map((f) => [f.id, f]));
        const found = wantedIds
          .map((id) => byId.get(id))
          .filter((f): f is FileDto => f !== undefined);
        if (found.length > 0) setFiles(found);
      } catch {
        toast.error("Could not load your selected files");
      }
    })();
  }, [authLoading, user, searchParams]);

  function requireLogin(): boolean {
    if (user) return false;
    toast.info("Log in to merge PDF files");
    router.push("/login?next=/tools/merge-pdf");
    return true;
  }

  function handleUploaded(newFiles: FileDto[]) {
    setFiles((prev) => [...prev, ...newFiles]);
    setResult(null);
  }

  async function handleMerge() {
    if (requireLogin()) return;
    if (files.length < 2) {
      toast.error("Add at least 2 PDF files to merge");
      return;
    }

    setIsMerging(true);
    setResult(null);
    try {
      const data = await apiFetch<MergePdfResponseDto>("/tools/merge-pdf", {
        method: "POST",
        body: { fileIds: files.map((f) => f.id) },
      });
      setResult(data);
      toast.success("PDFs merged successfully!");
    } catch (err) {
      toast.error(err instanceof ApiRequestError ? err.message : "Merge failed. Please try again.");
    } finally {
      setIsMerging(false);
    }
  }

  async function handleDownloadResult() {
    if (!result) return;
    try {
      await downloadFile(result.outputFile.id, result.outputFile.originalName);
    } catch (err) {
      toast.error(err instanceof ApiRequestError ? err.message : "Download failed");
    }
  }

  return (
    <div className="min-h-screen bg-slate-50 dark:bg-slate-900">
      <SiteHeader />
      <main className="mx-auto max-w-3xl px-4 py-10">
        <div className="mb-8 text-center">
          <h1 className="text-3xl font-bold text-slate-900 dark:text-slate-100">Merge PDF</h1>
          <p className="mt-2 text-slate-500 dark:text-slate-400">
            Combine multiple PDFs into one file. Drag to set the order — free on Use2PDF.com.
          </p>
        </div>

        <div className="space-y-6">
          {user || authLoading ? (
            <FileUploadDropzone onUploaded={handleUploaded} />
          ) : (
            <Card>
              <CardContent className="py-10 text-center">
                <p className="font-medium text-slate-900">Log in to upload and merge PDFs</p>
                <p className="mt-1 text-sm text-slate-500">It only takes a moment — and it's free.</p>
                <Button className="mt-4" onClick={() => router.push("/login?next=/tools/merge-pdf")}>
                  Log in
                </Button>
              </CardContent>
            </Card>
          )}

          {files.length > 0 && (
            <Card>
              <CardHeader className="flex flex-row items-center justify-between">
                <CardTitle>Merge order ({files.length} files)</CardTitle>
                <Button
                  onClick={handleMerge}
                  isLoading={isMerging}
                  disabled={files.length < 2}
                  title={files.length < 2 ? "Add at least 2 files" : undefined}
                >
                  <Merge className="h-4 w-4" />
                  Merge {files.length >= 2 ? `${files.length} PDFs` : "PDFs"}
                </Button>
              </CardHeader>
              <CardContent>
                <MergeReorderList
                  files={files}
                  onReorder={setFiles}
                  onRemove={(fileId) => setFiles((prev) => prev.filter((f) => f.id !== fileId))}
                  disabled={isMerging}
                />
              </CardContent>
            </Card>
          )}

          {result && (
            <Card className="border-green-200 bg-green-50">
              <CardContent className="flex items-center justify-between gap-4 py-5">
                <div>
                  <p className="font-semibold text-green-900">Your merged PDF is ready</p>
                  <p className="text-sm text-green-700">
                    {result.outputFile.originalName} · {formatBytes(result.outputFile.sizeBytes)}
                  </p>
                </div>
                <Button onClick={handleDownloadResult}>
                  <Download className="h-4 w-4" />
                  Download
                </Button>
              </CardContent>
            </Card>
          )}
        </div>
      </main>
    </div>
  );
}

export default function MergePdfPage() {
  return (
    <Suspense>
      <MergePdfTool />
    </Suspense>
  );
}
