"use client";

import React, { useCallback, useEffect, useMemo, useState } from "react";
import { Loader2, Download, Folder, FileText, RefreshCw, ArrowUp, Home } from "lucide-react";

type FileItem = { name: string; type: "dir" | "file"; size?: number; mtimeMs?: number };
type ListResponse =
| { path: string; items: FileItem[] }
| { path: string; entries: FileItem[] }
| { items?: FileItem[]; entries?: FileItem[]; path?: string };

const BASE = (process.env.NEXT_PUBLIC_FILE_API_BASE_URL || "").replace(/\/$/, "") || "";

function joinPath(a: string, b: string) {
    if (!a || a === "/") return b.startsWith("/") ? b : `/${b}`;
    return `${a.replace(/\/$/, "")}/${b.replace(/^\//, "")}`;
}
function parentPath(path: string) {
    if (!path || path === "/") return "/";
    const parts = path.replace(/\/+$/, "").split("/");
    parts.pop();
    const p = parts.join("/");
    return p === "" ? "/" : p;
}
function formatSize(bytes?: number) {
    if (bytes == null) return "—";
    const units = ["B", "KB", "MB", "GB", "TB"];
    let v = bytes;
    let u = 0;
    while (v >= 1024 && u < units.length - 1) { v /= 1024; u++; }
    return `${v.toFixed(u ? 1 : 0)} ${units[u]}`;
}
function formatDate(ms?: number) {
    if (!ms) return "—";
    const d = new Date(ms);
    return d.toLocaleDateString(undefined, { year: "numeric", month: "numeric", day: "numeric" });
}

export default function FileBrowserPanel() {
    const [path, setPath] = useState<string>("/");
    const [items, setItems] = useState<FileItem[]>([]);
    const [loading, setLoading] = useState(false);
    const [error, setError] = useState<string | null>(null);
    const [previewHref, setPreviewHref] = useState<string | null>(null);

    const urlList = useMemo(() => {
        const p = encodeURIComponent(path || "/");
        return `${BASE}/api/files/list?path=${p}`;
    }, [path]);

    const urlDownload = useCallback((p: string) => {
        const qp = encodeURIComponent(p || "/");
        return `${BASE}/api/files/download?path=${qp}`;
    }, []);
    const urlRaw = useCallback((p: string) => {
        const qp = encodeURIComponent(p || "/");
        return `${BASE}/api/files/raw?path=${qp}`;
    }, []);

    const fetchList = useCallback(async () => {
        setLoading(true);
        setError(null);
        setPreviewHref(null);
        try {
            const res = await fetch(urlList, { headers: { Accept: "application/json" }, cache: "no-store" });
            if (!res.ok) throw new Error(`HTTP ${res.status}`);
            const json: ListResponse = await res.json();
            const arr = (json as any).items || (json as any).entries || [];
            if (!Array.isArray(arr)) throw new Error("Malformed list response");
            arr.sort((a: FileItem, b: FileItem) => (a.type !== b.type ? (a.type === "dir" ? -1 : 1) : a.name.localeCompare(b.name)));
            setItems(arr);
        } catch (e: any) {
            setError(e?.message || String(e));
            setItems([]);
        } finally {
            setLoading(false);
        }
    }, [urlList]);

    useEffect(() => { fetchList(); }, [fetchList]);

    const onOpen = (it: FileItem) => {
        if (it.type === "dir") setPath((p) => joinPath(p, it.name));
        else setPreviewHref(urlRaw(joinPath(path, it.name)));
    };
        const onUp = () => setPath((p) => parentPath(p));
        const onHome = () => setPath("/");
        const onDownload = (it: FileItem) => {
            const href = urlDownload(joinPath(path, it.name));
            const a = document.createElement("a");
            a.href = href; a.download = it.name; document.body.appendChild(a); a.click(); a.remove();
        };

        return (
            <div className="space-y-3">
            {/* compact, consistent type + strict columns */}
            <style>{`
                .fs-cell{ font-size:13.5px; line-height:1.3 }
                .fs-tight{ letter-spacing:.01em }
                .fs-table{
                    --col-name-min: 260px;
                    --col-type: 56px;
                    --col-size: 72px;
                    --col-date: 96px;
                    --col-actions: 44px; /* icon-only */
                    display:grid;
                    grid-template-columns:minmax(var(--col-name-min),1fr) var(--col-type) var(--col-size) var(--col-date) var(--col-actions);
                }
                .fs-nowrap{ white-space:nowrap }
                .fs-iconbtn{
                    width:28px; height:28px; display:inline-flex; align-items:center; justify-content:center;
                    border:1px solid var(--border); border-radius:8px;
                }
                `}</style>

                {/* Toolbar */}
                <div className="flex items-center gap-2">
                <button onClick={onHome} className="inline-flex items-center gap-2 rounded-md border px-3 py-1.5 text-sm hover:bg-muted" title="Root">
                <Home className="h-4 w-4" /> root
                </button>
                <div className="ml-auto flex items-center gap-2">
                <button onClick={fetchList} className="inline-flex items-center gap-2 rounded-md border px-3 py-1.5 text-sm hover:bg-muted" title="Refresh">
                <RefreshCw className="h-4 w-4" /> Refresh
                </button>
                <button onClick={onUp} className="inline-flex items-center gap-2 rounded-md border px-3 py-1.5 text-sm hover:bg-muted" title="Up one folder">
                <ArrowUp className="h-4 w-4" /> Up
                </button>
                </div>
                </div>

                <div className="text-xs text-muted-foreground select-all">{path || "/"}</div>

                {/* Layout: left flex, right fixed min; no horizontal scroll on left */}
                <div className="grid grid-cols-[minmax(560px,1fr)_minmax(420px,42vw)] gap-3 items-start">
                {/* LEFT: Table */}
                <div className="rounded-md border overflow-hidden">
                {/* Header */}
                <div className="fs-table bg-muted px-2 py-2 fs-cell fs-tight">
                <div className="px-1">Name</div>
                <div className="text-center">Type</div>
                <div className="text-right">Size</div>
                <div className="text-center">Date</div>
                <div className="text-right pr-1 fs-nowrap">Act</div>
                </div>

                <div className="divide-y">
                {loading ? (
                    <div className="p-6 text-sm text-muted-foreground flex items-center gap-2">
                    <Loader2 className="h-4 w-4 animate-spin" /> Loading…
                    </div>
                ) : error ? (
                    <div className="p-6 text-sm text-rose-400">Error: {error}</div>
                ) : items.length === 0 ? (
                    <div className="p-6 text-sm text-muted-foreground">Empty folder.</div>
                ) : (
                    items.map((it) => (
                        <div key={it.name + it.type} className="fs-table items-center px-2 py-2 hover:bg-muted/50 fs-cell">
                        {/* Name */}
                        <button
                        className="text-left inline-flex items-center gap-2 hover:underline min-w-0 px-1"
                        onClick={() => onOpen(it)}
                        title={it.name}
                        >
                        {it.type === "dir" ? <Folder className="h-4 w-4 shrink-0" /> : <FileText className="h-4 w-4 shrink-0" />}
                        <span className="truncate">{it.name}</span>
                        </button>

                        {/* Type */}
                        <div className="text-center uppercase tracking-wide text-[11px] text-muted-foreground">{it.type}</div>

                        {/* Size */}
                        <div className="text-right text-muted-foreground">{formatSize(it.size)}</div>

                        {/* Date only */}
                        <div className="text-center text-muted-foreground">{formatDate(it.mtimeMs)}</div>

                        {/* Actions (icon-only, fits in 44px) */}
                        <div className="text-right pr-1">
                        {it.type === "file" && (
                            <button
                            onClick={() => onDownload(it)}
                            className="fs-iconbtn hover:bg-muted"
                            title="Download"
                            aria-label={`Download ${it.name}`}
                            >
                            <Download className="h-4 w-4" />
                            </button>
                        )}
                        </div>
                        </div>
                    ))
                )}
                </div>
                </div>

                {/* RIGHT: Preview */}
                <div className="rounded-md border p-3">
                <div className="mb-2 text-sm font-medium">Preview</div>
                <div className="border rounded overflow-hidden" style={{ height: 520 }}>
                {previewHref ? (
                    <iframe key={previewHref} src={previewHref} className="w-full h-full" title="Preview" />
                ) : (
                    <div className="p-3 text-sm text-muted-foreground">Select a file to preview.</div>
                )}
                </div>
                </div>
                </div>
                </div>
        );
}
