"use client";

import { useMemo, useRef, useState, type DragEvent } from "react";
import Link from "next/link";
import { useRouter } from "next/navigation";
import { Icon } from "@/components/ui/Icon";
import { confirmDialog, alertDialog } from "@/components/ui/Dialog";
import { RowMenu, type RowMenuItem } from "@/components/ui/RowMenu";
import type { ShareTargets } from "@/components/ui/SharePicker";
import { deleteFileAction, deleteFolderAction } from "@/lib/cloud/actions";
import { KIND_COLOR, KIND_ICON, formatBytes, kindOf } from "@/lib/cloud/format";
import type { CloudListing, FileDTO, FolderDTO } from "@/lib/cloud/queries";
import { ViewSwitch } from "@/components/ui/ViewSwitch";
import { useViewMode } from "@/lib/ui/viewMode";
import { FileLightbox } from "./FileLightbox";
import { FileEditDialog } from "./FileEditDialog";
import { ShareDialog, type ShareSubject } from "./ShareDialog";
import { FolderDialog, DEFAULT_FOLDER_COLOR } from "./FolderDialog";

type Upload = { name: string; state: "läuft" | "fertig" | "fehler"; error?: string };

const TEAM_COLOR = "#9ed7ff";

export function CloudManager({
  userId,
  listing,
  targets,
  writableFolders,
  canManage,
}: {
  userId: string;
  listing: CloudListing;
  targets: ShareTargets;
  writableFolders: { id: string; name: string; parentId: string | null }[];
  canManage: boolean;
}) {
  const router = useRouter();
  const fileInput = useRef<HTMLInputElement>(null);
  const dragDepth = useRef(0);

  const [query, setQuery] = useState("");
  const [view, setView] = useViewMode(userId, "cloud");
  const [dragging, setDragging] = useState(false);
  const [uploads, setUploads] = useState<Upload[]>([]);

  // Jede Aktion hat ihre eigene Ansicht.
  const [preview, setPreview] = useState<FileDTO | null>(null);
  const [editFile, setEditFile] = useState<FileDTO | null>(null);
  const [editFolder, setEditFolder] = useState<FolderDTO | "new" | null>(null);
  const [share, setShare] = useState<ShareSubject | null>(null);

  const canWrite = canManage && listing.canWrite;

  const { teamFolders, folders, files } = useMemo(() => {
    const q = query.trim().toLowerCase();
    const hit = (name: string) => !q || name.toLowerCase().includes(q);
    return {
      teamFolders: listing.teamFolders.filter((f) => hit(f.name)),
      folders: listing.folders.filter((f) => hit(f.name)),
      files: listing.files.filter((f) => hit(f.name)),
    };
  }, [listing, query]);

  // ── Upload ──
  const uploadFiles = async (list: File[]) => {
    if (!canWrite || list.length === 0) return;
    setUploads(list.map((f) => ({ name: f.name, state: "läuft" as const })));

    for (const [index, file] of list.entries()) {
      try {
        const fd = new FormData();
        fd.append("file", file);
        if (listing.folderId) fd.append("folderId", listing.folderId);

        const res = await fetch("/api/cloud/upload", { method: "POST", body: fd });
        if (!res.ok) {
          const d = await res.json().catch(() => ({}));
          throw new Error(d.error ?? "Upload fehlgeschlagen.");
        }
        setUploads((prev) => prev.map((u, i) => (i === index ? { ...u, state: "fertig" } : u)));
      } catch (err) {
        setUploads((prev) =>
          prev.map((u, i) =>
            i === index
              ? { ...u, state: "fehler", error: err instanceof Error ? err.message : "Fehler" }
              : u,
          ),
        );
      }
    }

    router.refresh();
    setTimeout(
      () => setUploads((prev) => (prev.every((u) => u.state === "fertig") ? [] : prev)),
      2500,
    );
  };

  const onDrop = (e: DragEvent<HTMLDivElement>) => {
    e.preventDefault();
    dragDepth.current = 0;
    setDragging(false);
    const dropped = Array.from(e.dataTransfer?.files ?? []);
    if (dropped.length > 0) void uploadFiles(dropped);
  };
  const onDragEnter = (e: DragEvent<HTMLDivElement>) => {
    if (!canWrite || !e.dataTransfer?.types.includes("Files")) return;
    e.preventDefault();
    dragDepth.current += 1;
    setDragging(true);
  };
  const onDragLeave = () => {
    dragDepth.current = Math.max(0, dragDepth.current - 1);
    if (dragDepth.current === 0) setDragging(false);
  };

  // ── Löschen ──
  const removeFolder = async (f: FolderDTO) => {
    const ok = await confirmDialog({
      title: `Ordner „${f.name}“ löschen?`,
      message:
        f.fileCount + f.folderCount > 0
          ? `Der Ordner enthält ${f.fileCount} Datei(en) und ${f.folderCount} Unterordner. Alles wird endgültig gelöscht.`
          : "Der Ordner wird endgültig gelöscht.",
      confirmLabel: "Löschen",
      danger: true,
    });
    if (!ok) return;
    const res = await deleteFolderAction(f.id);
    if (res.error) await alertDialog({ title: "Fehler", message: res.error, danger: true });
    else router.refresh();
  };

  const removeFile = async (f: FileDTO) => {
    const ok = await confirmDialog({
      title: `„${f.name}“ löschen?`,
      message: "Die Datei wird endgültig entfernt — auch für alle Freigegebenen.",
      confirmLabel: "Löschen",
      danger: true,
    });
    if (!ok) return;
    const res = await deleteFileAction(f.id);
    if (res.error) await alertDialog({ title: "Fehler", message: res.error, danger: true });
    else router.refresh();
  };

  const shareFolder = (f: FolderDTO): ShareSubject => ({
    kind: "folder",
    id: f.id,
    name: f.name,
    users: f.users,
    teams: f.teams,
    roles: f.roles,
  });
  const shareFile = (f: FileDTO): ShareSubject => ({
    kind: "file",
    id: f.id,
    name: f.name,
    users: f.users,
    teams: f.teams,
    roles: f.roles,
  });

  const empty = teamFolders.length === 0 && folders.length === 0 && files.length === 0;
  const inRoot = listing.folderId === null;

  return (
    <>
      <section
        className="card"
        data-reveal
        onDragEnter={onDragEnter}
        onDragOver={(e) => canWrite && e.preventDefault()}
        onDragLeave={onDragLeave}
        onDrop={onDrop}
        style={{ position: "relative" }}
      >
        {/* Werkzeugleiste: Suche links, Aktionen rechts */}
        <div className="cl-bar">
          <div className="cl-search">
            <input
              className="input"
              value={query}
              onChange={(e) => setQuery(e.target.value)}
              placeholder="Ordner und Dateien durchsuchen …"
              style={{ paddingLeft: 38 }}
            />
            <span className="text-muted pointer-events-none absolute left-3 top-1/2 -translate-y-1/2">
              <Icon name="search" size={16} />
            </span>
          </div>

          <div className="flex flex-wrap items-center gap-2">
            <ViewSwitch value={view} onChange={setView} />
            {canWrite ? (
              <>
              <button className="btn btn-ghost btn-sm" onClick={() => setEditFolder("new")}>
                <Icon name="plus" size={15} /> Neuer Ordner
              </button>
              <button className="btn btn-primary btn-sm" onClick={() => fileInput.current?.click()}>
                <Icon name="cloud" size={15} /> Hochladen
              </button>
              <input
                ref={fileInput}
                type="file"
                multiple
                hidden
                onChange={(e) => {
                  const picked = Array.from(e.target.files ?? []);
                  e.target.value = "";
                  void uploadFiles(picked);
                }}
              />
              </>
            ) : null}
          </div>
        </div>

        {/* Pfad — nur außerhalb der Wurzel */}
        {!inRoot ? (
          <nav className="cl-crumbs">
            {listing.crumbs.map((c, i) => (
              <span key={c.id ?? "root"} className="flex min-w-0 items-center gap-1">
                {i > 0 ? <Icon name="chevron" size={12} className="shrink-0 opacity-40" /> : null}
                {i === listing.crumbs.length - 1 ? (
                  <span className="cl-crumb truncate" data-current="true">
                    {c.name}
                  </span>
                ) : (
                  <Link
                    href={c.id ? `/cloud?f=${c.id}` : "/cloud"}
                    className="cl-crumb truncate"
                    scroll={false}
                  >
                    {i === 0 ? <Icon name="cloud" size={14} /> : c.name}
                  </Link>
                )}
              </span>
            ))}
          </nav>
        ) : null}

        {/* Upload-Fortschritt */}
        {uploads.length > 0 ? (
          <div className="cl-uploads">
            {uploads.map((u, i) => (
              <div key={`${u.name}-${i}`} className="cl-upload" data-state={u.state}>
                <Icon
                  name={u.state === "fertig" ? "check" : u.state === "fehler" ? "alert" : "cloud"}
                  size={14}
                />
                <span className="min-w-0 flex-1 truncate">{u.name}</span>
                <span className="text-xs font-bold">{u.error ?? u.state}</span>
              </div>
            ))}
          </div>
        ) : null}

        {empty ? (
          <div className="ui-empty">
            <span className="ui-empty-mark">
              <Icon name={query ? "search" : "cloud"} size={26} />
            </span>
            <p className="ui-empty-title">{query ? "Nichts gefunden" : "Noch nichts abgelegt"}</p>
            <p className="ui-empty-text">
              {query
                ? "Für diese Suche gibt es hier keine Treffer."
                : canWrite
                  ? "Zieh Dateien einfach hierher — oder lege zuerst einen Ordner an."
                  : "Hier liegt noch nichts für dich bereit."}
            </p>
            {query ? (
              <button className="btn btn-ghost btn-sm ui-empty-actions" onClick={() => setQuery("")}>
                <Icon name="close" size={15} /> Suche zurücksetzen
              </button>
            ) : canWrite ? (
              <div className="ui-empty-actions">
                <button
                  className="btn btn-primary btn-sm"
                  onClick={() => fileInput.current?.click()}
                >
                  <Icon name="cloud" size={15} /> Dateien hochladen
                </button>
                <button className="btn btn-ghost btn-sm" onClick={() => setEditFolder("new")}>
                  <Icon name="plus" size={15} /> Neuer Ordner
                </button>
              </div>
            ) : null}
          </div>
        ) : (
          <div className="cl-sections">
            {/* ── Team-Ordner ── */}
            {teamFolders.length > 0 ? (
              <div>
                <div className="cl-section">
                  <Icon name="users" size={13} /> Team-Ordner
                  <span className="cl-section-count">{teamFolders.length}</span>
                  <span className="cl-section-hint">automatisch für deine Teams</span>
                </div>
                <div className={view === "grid" ? "cl-grid" : "cl-table"}>
                  {view === "list" ? (
                    <div className="cl-head">
                      <span>Name</span>
                      <span>Inhalt</span>
                      <span>Besitzer</span>
                      <span />
                    </div>
                  ) : null}
                  {teamFolders.map((f) => {
                    const color = f.color ?? TEAM_COLOR;
                    return (
                      <div
                        key={f.id}
                        className="cl-tile" data-view={view}
                        data-folder="true"
                        data-team="true"
                        style={{ ["--fc" as string]: color }}
                      >
                        <Link href={`/cloud?f=${f.id}`} className="cl-tile-main" scroll={false}>
                          <span className="cl-icon" style={{ color }}>
                            <Icon name="users" size={20} />
                          </span>
                          <span className="min-w-0 flex-1">
                            <span className="cl-name">{f.name}</span>
                            <span className="cl-meta">
                              {f.folderCount > 0 ? `${f.folderCount} Ordner · ` : ""}
                              {f.fileCount} Datei(en) · alle Mitglieder
                            </span>
                          </span>
                          <span className="cl-team-badge" style={{ color }}>
                            Team
                          </span>
                        </Link>
                        {view === "list" ? (
                          <>
                            <span className="cl-col">
                              {f.folderCount > 0 ? `${f.folderCount} Ordner · ` : ""}
                              {f.fileCount} Datei(en)
                            </span>
                            <span className="cl-col">alle Mitglieder</span>
                          </>
                        ) : null}
                        <RowMenu
                          id={`team-${f.id}`}
                          items={[
                            {
                              label: "Öffnen",
                              icon: "folder",
                              onSelect: () => router.push(`/cloud?f=${f.id}`),
                            },
                          ]}
                        />
                      </div>
                    );
                  })}
                </div>
              </div>
            ) : null}

            {/* ── Ordner ── */}
            {folders.length > 0 ? (
              <div>
                <div className="cl-section">
                  <Icon name="folder" size={13} /> Ordner
                  <span className="cl-section-count">{folders.length}</span>
                </div>
                <div className={view === "grid" ? "cl-grid" : "cl-table"}>
                  {view === "list" ? (
                    <div className="cl-head">
                      <span>Name</span>
                      <span>Inhalt</span>
                      <span>Besitzer</span>
                      <span />
                    </div>
                  ) : null}
                  {folders.map((f) => {
                    const color = f.color ?? DEFAULT_FOLDER_COLOR;
                    const items: RowMenuItem[] = [
                      {
                        label: "Öffnen",
                        icon: "folder",
                        onSelect: () => router.push(`/cloud?f=${f.id}`),
                      },
                    ];
                    if (canManage && f.canWrite) {
                      items.push({
                        label: "Bearbeiten",
                        icon: "edit",
                        onSelect: () => setEditFolder(f),
                      });
                    }
                    if (canManage && f.isOwner) {
                      items.push(
                        {
                          label: "Freigeben",
                          icon: "share",
                          onSelect: () => setShare(shareFolder(f)),
                        },
                        {
                          label: "Löschen",
                          icon: "trash",
                          danger: true,
                          onSelect: () => void removeFolder(f),
                        },
                      );
                    }
                    return (
                      <div
                        key={f.id}
                        className="cl-tile" data-view={view}
                        data-folder="true"
                        style={{ ["--fc" as string]: color }}
                      >
                        <Link href={`/cloud?f=${f.id}`} className="cl-tile-main" scroll={false}>
                          <span className="cl-icon" style={{ color }}>
                            <Icon name={f.icon ?? "folder"} size={20} />
                          </span>
                          <span className="min-w-0 flex-1">
                            <span className="cl-name">{f.name}</span>
                            <span className="cl-meta">
                              {f.folderCount > 0 ? `${f.folderCount} Ordner · ` : ""}
                              {f.fileCount} Datei(en)
                              {f.shared ? " · geteilt" : ""}
                            </span>
                          </span>
                        </Link>
                        {view === "list" ? (
                          <>
                            <span className="cl-col">
                              {f.folderCount > 0 ? `${f.folderCount} Ordner · ` : ""}
                              {f.fileCount} Datei(en)
                            </span>
                            <span className="cl-col">
                              {f.isOwner ? "du" : f.ownerName}
                              {f.shared ? " · geteilt" : ""}
                            </span>
                          </>
                        ) : null}
                        <RowMenu id={`folder-${f.id}`} items={items} />
                      </div>
                    );
                  })}
                </div>
              </div>
            ) : null}

            {/* ── Dateien ── */}
            {files.length > 0 ? (
              <div>
                <div className="cl-section">
                  <Icon name="file" size={13} /> Dateien
                  <span className="cl-section-count">{files.length}</span>
                </div>
                <div className={view === "grid" ? "cl-grid" : "cl-table"}>
                  {view === "list" ? (
                    <div className="cl-head">
                      <span>Name</span>
                      <span>Inhalt</span>
                      <span>Besitzer</span>
                      <span />
                    </div>
                  ) : null}
                  {files.map((f) => {
                    const kind = kindOf(f.mime, f.name);
                    const editable = canManage && f.canWrite;
                    const items: RowMenuItem[] = [
                      { label: "Vorschau", icon: "eye", onSelect: () => setPreview(f) },
                      {
                        label: "Herunterladen",
                        icon: "download",
                        href: `/api/cloud/file/${f.id}?download=1`,
                        onSelect: () => {},
                      },
                    ];
                    if (editable) {
                      items.push({
                        label: "Bearbeiten",
                        icon: "edit",
                        onSelect: () => setEditFile(f),
                      });
                    }
                    if (canManage && f.isOwner) {
                      items.push({
                        label: "Freigeben",
                        icon: "share",
                        onSelect: () => setShare(shareFile(f)),
                      });
                    }
                    if (editable) {
                      items.push({
                        label: "Löschen",
                        icon: "trash",
                        danger: true,
                        onSelect: () => void removeFile(f),
                      });
                    }
                    return (
                      <div key={f.id} className="cl-tile" data-view={view}>
                        <button className="cl-tile-main" onClick={() => setPreview(f)}>
                          {kind === "image" ? (
                            // eslint-disable-next-line @next/next/no-img-element
                            <img className="cl-thumb" src={`/api/cloud/file/${f.id}`} alt={f.name} />
                          ) : (
                            <span
                              className="cl-icon"
                              style={{
                                color: KIND_COLOR[kind],
                                background: `${KIND_COLOR[kind]}18`,
                                borderColor: `${KIND_COLOR[kind]}33`,
                              }}
                            >
                              <Icon name={KIND_ICON[kind]} size={20} />
                            </span>
                          )}
                          <span className="min-w-0 flex-1">
                            <span className="cl-name">{f.name}</span>
                            <span className="cl-meta">
                              {formatBytes(f.size)}
                              {f.shared ? " · geteilt" : ""}
                              {!f.isOwner ? ` · ${f.ownerName}` : ""}
                            </span>
                          </span>
                        </button>
                        {view === "list" ? (
                          <>
                            <span className="cl-col">{formatBytes(f.size)}</span>
                            <span className="cl-col">
                              {f.isOwner ? "du" : f.ownerName}
                              {f.shared ? " · geteilt" : ""}
                            </span>
                          </>
                        ) : null}
                        <RowMenu id={`file-${f.id}`} items={items} />
                      </div>
                    );
                  })}
                </div>
              </div>
            ) : null}
          </div>
        )}

        {/* Ablegen-Hinweis */}
        {dragging && canWrite ? (
          <div className="cl-dropzone">
            <span className="vault-mark" style={{ color: "var(--blue)" }}>
              <Icon name="cloud" size={20} />
            </span>
            <p className="mt-2 font-black">Dateien hier ablegen</p>
            <p className="text-muted text-sm">
              Ziel: {inRoot ? "Persönliche Ablage" : listing.folderName}
            </p>
          </div>
        ) : null}
      </section>

      {/* Getrennte Ansichten je Aktion */}
      {preview ? (
        <FileLightbox
          file={preview}
          canEdit={canManage && preview.canWrite}
          canShare={canManage && preview.isOwner}
          onEdit={() => {
            setEditFile(preview);
            setPreview(null);
          }}
          onShare={() => {
            setShare(shareFile(preview));
            setPreview(null);
          }}
          onClose={() => setPreview(null)}
        />
      ) : null}

      {editFile ? (
        <FileEditDialog
          file={editFile}
          folders={writableFolders}
          onClose={() => setEditFile(null)}
        />
      ) : null}

      {editFolder ? (
        <FolderDialog
          folder={editFolder === "new" ? null : editFolder}
          parentId={listing.folderId}
          onClose={() => setEditFolder(null)}
        />
      ) : null}

      {share ? (
        <ShareDialog subject={share} targets={targets} onClose={() => setShare(null)} />
      ) : null}
    </>
  );
}
