"use client";

import { useEffect, useState } from "react";
import { Button } from "@/components/ui/button";
import { toast } from "@/components/admin/Toast";
import {
  FetchError,
  apiDelete,
  apiGet,
  apiPatch,
  apiPost,
  slugify,
  type PublicAdvanceFolder,
  type PublicAdvanceModule,
} from "@/lib/client-api";

const STATUS_TONE: Record<string, string> = {
  active: "bg-emerald-100 text-emerald-700",
  disabled: "bg-slate-100 text-slate-700",
  archived: "bg-rose-100 text-rose-700",
};

export function AdvanceFoldersAdmin({
  initialFolders,
  total,
}: {
  initialFolders: PublicAdvanceFolder[];
  total: number;
}) {
  const [folders, setFolders] = useState<PublicAdvanceFolder[]>(initialFolders);
  const [activeFolderId, setActiveFolderId] = useState<string | null>(
    initialFolders[0]?.id ?? null,
  );
  const [creatingFolder, setCreatingFolder] = useState(false);
  const [editingFolder, setEditingFolder] = useState<PublicAdvanceFolder | null>(
    null,
  );

  const activeFolder =
    folders.find((f) => f.id === activeFolderId) ?? folders[0] ?? null;

  const onFolderSaved = (saved: PublicAdvanceFolder) => {
    setFolders((prev) => {
      const idx = prev.findIndex((f) => f.id === saved.id);
      if (idx >= 0) {
        const next = prev.slice();
        next[idx] = saved;
        return next;
      }
      return [saved, ...prev];
    });
    setActiveFolderId(saved.id);
    setCreatingFolder(false);
    setEditingFolder(null);
  };

  const onFolderDeleted = (id: string) => {
    setFolders((prev) => prev.filter((f) => f.id !== id));
    if (activeFolderId === id) {
      setActiveFolderId(null);
    }
    setEditingFolder(null);
  };

  return (
    <div className="space-y-4">
      <div className="flex flex-wrap items-center justify-between gap-3 rounded-2xl border border-border bg-surface p-4 shadow-sm">
        <div>
          <p className="text-[10px] font-semibold uppercase tracking-wide text-muted">
            Folders
          </p>
          <p className="text-2xl font-semibold">{folders.length}</p>
          <p className="text-[11px] text-muted">
            {total} in library · admins attach folders (not products) to a
            template.
          </p>
        </div>
        <Button size="sm" onClick={() => setCreatingFolder(true)}>
          + New folder
        </Button>
      </div>

      <div className="grid gap-6 lg:grid-cols-[280px_1fr]">
        <aside className="rounded-2xl border border-border bg-surface shadow-sm">
          <div className="border-b border-border px-3 py-2">
            <p className="text-xs font-semibold uppercase tracking-wide text-muted">
              Folders
            </p>
          </div>
          <ul className="max-h-[640px] overflow-y-auto p-2">
            {folders.length === 0 ? (
              <li className="p-4 text-xs text-muted">
                No folders yet. Create one (e.g. Ribbon).
              </li>
            ) : (
              folders.map((f) => {
                const isActive = f.id === activeFolder?.id;
                return (
                  <li key={f.id}>
                    <button
                      type="button"
                      onClick={() => setActiveFolderId(f.id)}
                      className={`flex w-full items-center justify-between gap-2 rounded-lg px-3 py-2 text-left text-sm transition ${
                        isActive
                          ? "bg-primary/10 text-primary"
                          : "text-foreground hover:bg-surface-muted"
                      }`}
                    >
                      <span className="truncate font-medium">{f.name}</span>
                      <span
                        className={`shrink-0 rounded-full px-2 py-0.5 text-[10px] font-semibold uppercase tracking-wide ${
                          STATUS_TONE[f.status] ?? STATUS_TONE.disabled
                        }`}
                      >
                        {f.status}
                      </span>
                    </button>
                  </li>
                );
              })
            )}
          </ul>
        </aside>

        <section className="space-y-4">
          {activeFolder ? (
            <div className="flex flex-wrap items-center justify-between gap-3 rounded-2xl border border-border bg-surface p-4 shadow-sm">
              <div className="min-w-0">
                <p className="text-xs uppercase tracking-wide text-muted">
                  Folder
                </p>
                <p className="truncate text-lg font-semibold">
                  {activeFolder.name}
                </p>
                {activeFolder.description ? (
                  <p className="text-xs text-muted">
                    {activeFolder.description}
                  </p>
                ) : null}
              </div>
              <Button
                size="sm"
                variant="secondary"
                onClick={() => setEditingFolder(activeFolder)}
              >
                Edit folder
              </Button>
            </div>
          ) : (
            <div className="rounded-2xl border border-dashed border-border bg-surface p-10 text-center">
              <p className="text-sm font-medium">No folder selected</p>
              <p className="mt-1 text-xs text-muted">
                Create a folder on the left to start adding products inside it.
              </p>
            </div>
          )}

          {activeFolder ? (
            <FolderProducts folder={activeFolder} />
          ) : null}
        </section>
      </div>

      {creatingFolder ? (
        <FolderEditModal
          mode="create"
          onClose={() => setCreatingFolder(false)}
          onSaved={onFolderSaved}
        />
      ) : null}
      {editingFolder ? (
        <FolderEditModal
          mode="edit"
          folder={editingFolder}
          onClose={() => setEditingFolder(null)}
          onSaved={onFolderSaved}
          onDeleted={onFolderDeleted}
        />
      ) : null}
    </div>
  );
}

function FolderProducts({ folder }: { folder: PublicAdvanceFolder }) {
  const [items, setItems] = useState<PublicAdvanceModule[]>([]);
  const [loading, setLoading] = useState(true);
  const [editing, setEditing] = useState<PublicAdvanceModule | null>(null);
  const [creating, setCreating] = useState(false);

  const reload = async () => {
    try {
      setLoading(true);
      const res = await apiGet<{
        items: PublicAdvanceModule[];
      }>(
        `/api/admin/advance-modules?folderId=${encodeURIComponent(folder.id)}&pageSize=500`,
      );
      setItems(res.items ?? []);
    } catch (err) {
      toast(
        err instanceof FetchError ? err.message : "Failed to load products.",
        "error",
      );
    } finally {
      setLoading(false);
    }
  };

  useEffect(() => {
    // eslint-disable-next-line react-hooks/set-state-in-effect
    reload();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [folder.id]);

  const onSaved = (saved: PublicAdvanceModule) => {
    setItems((prev) => {
      const idx = prev.findIndex((m) => m.id === saved.id);
      if (idx >= 0) {
        const next = prev.slice();
        next[idx] = saved;
        return next;
      }
      return [saved, ...prev];
    });
    setEditing(null);
    setCreating(false);
  };

  const onDeleted = (id: string) => {
    setItems((prev) => prev.filter((m) => m.id !== id));
    setEditing(null);
  };

  return (
    <div className="space-y-3">
      <div className="flex flex-wrap items-center justify-between gap-2 rounded-2xl border border-border bg-surface p-4 shadow-sm">
        <div>
          <p className="text-sm font-semibold">
            Products inside &quot;{folder.name}&quot;
          </p>
          <p className="text-[11px] text-muted">
            Name, image, and description are enough.
          </p>
        </div>
        <Button size="sm" onClick={() => setCreating(true)}>
          + New product
        </Button>
      </div>

      {loading ? (
        <p className="text-xs text-muted">Loading…</p>
      ) : items.length === 0 ? (
        <div className="rounded-2xl border border-dashed border-border bg-surface p-10 text-center">
          <p className="text-sm font-medium">No products yet</p>
          <p className="mt-1 text-xs text-muted">
            Add products to this folder with name + image + description.
          </p>
        </div>
      ) : (
        <ul className="grid gap-3 sm:grid-cols-2 lg:grid-cols-3">
          {items.map((m) => (
            <li
              key={m.id}
              className="overflow-hidden rounded-2xl border border-border bg-surface shadow-sm transition-all hover:-translate-y-0.5 hover:shadow-md"
            >
              <div className="relative h-32 w-full bg-gradient-to-br from-indigo-100 via-violet-50 to-pink-50">
                {m.image ? (
                  // eslint-disable-next-line @next/next/no-img-element
                  <img
                    src={m.image}
                    alt={m.name}
                    className="h-full w-full object-cover"
                  />
                ) : (
                  <div className="grid h-full w-full place-items-center text-sm text-muted">
                    No image
                  </div>
                )}
                <span
                  className={`absolute right-2 top-2 rounded-full px-2 py-0.5 text-[10px] font-semibold uppercase tracking-wide ${
                    STATUS_TONE[m.status] ?? STATUS_TONE.disabled
                  }`}
                >
                  {m.status}
                </span>
              </div>
              <div className="space-y-2 p-3">
                <p className="truncate text-sm font-semibold">{m.name}</p>
                <p className="line-clamp-2 text-[11px] text-muted">
                  {m.description || "No description."}
                </p>
                <div className="flex gap-2">
                  <Button
                    size="sm"
                    variant="secondary"
                    className="flex-1"
                    onClick={() => setEditing(m)}
                  >
                    Edit
                  </Button>
                </div>
              </div>
            </li>
          ))}
        </ul>
      )}

      {creating ? (
        <ProductEditModal
          mode="create"
          folderId={folder.id}
          onClose={() => setCreating(false)}
          onSaved={onSaved}
        />
      ) : null}
      {editing ? (
        <ProductEditModal
          mode="edit"
          folderId={folder.id}
          product={editing}
          onClose={() => setEditing(null)}
          onSaved={onSaved}
          onDeleted={onDeleted}
        />
      ) : null}
    </div>
  );
}

function FolderEditModal({
  mode,
  folder,
  onClose,
  onSaved,
  onDeleted,
}: {
  mode: "create" | "edit";
  folder?: PublicAdvanceFolder;
  onClose: () => void;
  onSaved: (f: PublicAdvanceFolder) => void;
  onDeleted?: (id: string) => void;
}) {
  const [name, setName] = useState(folder?.name ?? "");
  const [slug, setSlug] = useState(folder?.slug ?? "");
  const [description, setDescription] = useState(folder?.description ?? "");
  const [status, setStatus] = useState(folder?.status ?? "active");
  const [saving, setSaving] = useState(false);

  const onSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    setSaving(true);
    try {
      const payload = {
        name,
        slug: slug || undefined,
        description,
        status,
      };
      const saved =
        mode === "create"
          ? await apiPost<PublicAdvanceFolder>(
              "/api/admin/advance-folders",
              payload,
            )
          : await apiPatch<PublicAdvanceFolder>(
              `/api/admin/advance-folders/${folder!.id}`,
              payload,
            );
      toast(mode === "create" ? "Folder created." : "Folder saved.", "success");
      onSaved(saved);
    } catch (err) {
      toast(
        err instanceof FetchError ? err.message : "Save failed.",
        "error",
      );
    } finally {
      setSaving(false);
    }
  };

  const onDelete = async () => {
    if (!folder) return;
    if (
      !confirm(
        `Delete folder "${folder.name}" and all its products? This cannot be undone.`,
      )
    )
      return;
    try {
      await apiDelete(`/api/admin/advance-folders/${folder.id}`);
      toast("Folder deleted.", "info");
      onDeleted?.(folder.id);
    } catch (err) {
      toast(
        err instanceof FetchError ? err.message : "Delete failed.",
        "error",
      );
    }
  };

  return (
    <div className="fixed inset-0 z-50 grid place-items-center bg-black/40 p-4">
      <form
        onSubmit={onSubmit}
        className="w-full max-w-md overflow-hidden rounded-2xl border border-border bg-surface shadow-2xl"
      >
        <div className="flex items-center justify-between border-b border-border bg-surface-muted/40 px-5 py-3">
          <h2 className="text-base font-semibold">
            {mode === "create" ? "New folder" : "Edit folder"}
          </h2>
          <button
            type="button"
            onClick={onClose}
            aria-label="Close"
            className="rounded-md p-1 text-muted hover:bg-surface-muted"
          >
            ✕
          </button>
        </div>
        <div className="space-y-3 p-5">
          <div>
            <label className="mb-1 block text-xs font-medium text-muted">
              Name
            </label>
            <input
              value={name}
              onChange={(e) => {
                const v = e.target.value;
                setName(v);
                if (mode === "create" || !folder || slug === folder.slug) {
                  setSlug(slugify(v));
                }
              }}
              className="input"
              required
              placeholder="e.g. Ribbon"
            />
          </div>
          <div>
            <label className="mb-1 block text-xs font-medium text-muted">
              Slug
            </label>
            <input
              value={slug}
              onChange={(e) => setSlug(slugify(e.target.value))}
              className="input"
              placeholder="auto from name"
            />
          </div>
          <div>
            <label className="mb-1 block text-xs font-medium text-muted">
              Description
            </label>
            <textarea
              value={description}
              onChange={(e) => setDescription(e.target.value)}
              rows={3}
              className="input min-h-[60px]"
              placeholder="Optional description."
            />
          </div>
          <div>
            <label className="mb-1 block text-xs font-medium text-muted">
              Status
            </label>
            <select
              value={status}
              onChange={(e) => setStatus(e.target.value)}
              className="input"
            >
              <option value="active">active</option>
              <option value="disabled">disabled</option>
              <option value="archived">archived</option>
            </select>
          </div>
        </div>
        <div className="flex items-center justify-between border-t border-border bg-surface-muted/40 px-5 py-3">
          <div>
            {mode === "edit" && folder && !folder.isSystem ? (
              <button
                type="button"
                onClick={onDelete}
                className="text-xs font-medium text-rose-600 hover:text-rose-700"
              >
                Delete folder &amp; products
              </button>
            ) : null}
          </div>
          <div className="flex gap-2">
            <Button
              type="button"
              variant="secondary"
              size="sm"
              onClick={onClose}
              disabled={saving}
            >
              Cancel
            </Button>
            <Button type="submit" size="sm" isLoading={saving}>
              {mode === "create" ? "Create" : "Save"}
            </Button>
          </div>
        </div>
        <style jsx>{`
          :global(.input) {
            width: 100%;
            border-radius: 0.5rem;
            border: 1px solid var(--border);
            background: var(--surface);
            padding: 0.5rem 0.75rem;
            font-size: 0.875rem;
            color: var(--foreground);
          }
          :global(.input:focus) {
            outline: none;
            border-color: var(--primary);
          }
        `}</style>
      </form>
    </div>
  );
}

function ProductEditModal({
  mode,
  folderId,
  product,
  onClose,
  onSaved,
  onDeleted,
}: {
  mode: "create" | "edit";
  folderId: string;
  product?: PublicAdvanceModule;
  onClose: () => void;
  onSaved: (m: PublicAdvanceModule) => void;
  onDeleted?: (id: string) => void;
}) {
  const [name, setName] = useState(product?.name ?? "");
  const [slug, setSlug] = useState(product?.slug ?? "");
  const [description, setDescription] = useState(product?.description ?? "");
  const [status, setStatus] = useState(product?.status ?? "active");
  const [image, setImage] = useState<string | null>(product?.image ?? null);
  const [uploading, setUploading] = useState(false);
  const [uploadError, setUploadError] = useState<string | null>(null);
  const [saving, setSaving] = useState(false);

  const onUpload = async (file: File | null) => {
    if (!file) return;
    setUploadError(null);
    setUploading(true);
    try {
      const form = new FormData();
      form.append("file", file);
      const res = await fetch("/api/uploads", {
        method: "POST",
        body: form,
        credentials: "include",
      });
      const payload = (await res.json().catch(() => ({}))) as
        | { success: true; data: { url: string } }
        | { success: false; message: string };
      if (!res.ok || !("data" in payload) || !payload.success) {
        throw new Error("message" in payload ? payload.message : "Upload failed.");
      }
      setImage(payload.data.url);
    } catch (err) {
      setUploadError(err instanceof Error ? err.message : "Upload failed.");
    } finally {
      setUploading(false);
    }
  };

  const onSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    setSaving(true);
    try {
      const payload = {
        folderId,
        name,
        slug: slug || undefined,
        description,
        image,
        status,
      };
      const saved =
        mode === "create"
          ? await apiPost<PublicAdvanceModule>(
              "/api/admin/advance-modules",
              payload,
            )
          : await apiPatch<PublicAdvanceModule>(
              `/api/admin/advance-modules/${product!.id}`,
              payload,
            );
      toast(mode === "create" ? "Product created." : "Product saved.", "success");
      onSaved(saved);
    } catch (err) {
      toast(
        err instanceof FetchError ? err.message : "Save failed.",
        "error",
      );
    } finally {
      setSaving(false);
    }
  };

  const onDelete = async () => {
    if (!product) return;
    if (!confirm(`Delete product "${product.name}"?`)) return;
    try {
      await apiDelete(`/api/admin/advance-modules/${product.id}`);
      toast("Product deleted.", "info");
      onDeleted?.(product.id);
    } catch (err) {
      toast(
        err instanceof FetchError ? err.message : "Delete failed.",
        "error",
      );
    }
  };

  return (
    <div className="fixed inset-0 z-50 grid place-items-center bg-black/40 p-4">
      <form
        onSubmit={onSubmit}
        className="w-full max-w-xl overflow-hidden rounded-2xl border border-border bg-surface shadow-2xl"
      >
        <div className="relative h-36 w-full bg-gradient-to-br from-indigo-100 via-violet-50 to-pink-50">
          {image ? (
            // eslint-disable-next-line @next/next/no-img-element
            <img
              src={image}
              alt={name || "Product"}
              className="h-full w-full object-cover"
            />
          ) : (
            <div className="grid h-full w-full place-items-center text-sm text-muted">
              No image preview
            </div>
          )}
          <button
            type="button"
            onClick={onClose}
            aria-label="Close"
            className="absolute right-3 top-3 grid h-8 w-8 place-items-center rounded-full bg-white/90 text-rose-600 shadow-md hover:bg-white"
          >
            ✕
          </button>
        </div>

        <div className="space-y-4 p-5">
          <div className="grid gap-3 sm:grid-cols-2">
            <div className="sm:col-span-2">
              <label className="mb-1 block text-xs font-medium text-muted">
                Name
              </label>
              <input
                value={name}
                onChange={(e) => {
                  const v = e.target.value;
                  setName(v);
                  if (mode === "create" || !product || slug === product.slug) {
                    setSlug(slugify(v));
                  }
                }}
                className="input"
                required
                placeholder="e.g. Silk ribbon"
              />
            </div>
            <div>
              <label className="mb-1 block text-xs font-medium text-muted">
                Slug
              </label>
              <input
                value={slug}
                onChange={(e) => setSlug(slugify(e.target.value))}
                className="input"
                placeholder="auto from name"
              />
            </div>
            <div>
              <label className="mb-1 block text-xs font-medium text-muted">
                Status
              </label>
              <select
                value={status}
                onChange={(e) => setStatus(e.target.value)}
                className="input"
              >
                <option value="active">active</option>
                <option value="disabled">disabled</option>
                <option value="archived">archived</option>
              </select>
            </div>
            <div className="sm:col-span-2">
              <label className="mb-1 block text-xs font-medium text-muted">
                Description
              </label>
              <textarea
                value={description}
                onChange={(e) => setDescription(e.target.value)}
                className="input min-h-[60px]"
                rows={2}
              />
            </div>
            <div className="sm:col-span-2 rounded-xl border border-border bg-surface-muted/40 p-3">
              <p className="mb-2 text-xs font-semibold text-foreground">
                Image (URL or upload)
              </p>
              <div className="flex items-start gap-3">
                <div className="grid h-16 w-24 place-items-center overflow-hidden rounded-lg border border-dashed border-border bg-white">
                  {image ? (
                    // eslint-disable-next-line @next/next/no-img-element
                    <img
                      src={image}
                      alt=""
                      className="h-full w-full object-cover"
                    />
                  ) : (
                    <span className="text-[10px] text-muted">no image</span>
                  )}
                </div>
                <div className="flex-1 space-y-2">
                  <input
                    type="url"
                    value={image ?? ""}
                    onChange={(e) => setImage(e.target.value || null)}
                    placeholder="https://… or upload below"
                    className="input"
                  />
                  <div className="flex items-center gap-2">
                    <label className="inline-flex cursor-pointer items-center gap-1.5 rounded-lg border border-border bg-white px-3 py-1.5 text-xs font-medium text-foreground hover:bg-surface-muted">
                      <input
                        type="file"
                        accept="image/png,image/jpeg,image/webp,image/gif,image/svg+xml"
                        className="hidden"
                        onChange={(e) => {
                          const file = e.target.files?.[0] ?? null;
                          onUpload(file);
                          e.target.value = "";
                        }}
                      />
                      {uploading ? "Uploading…" : "Upload image"}
                    </label>
                    {image ? (
                      <button
                        type="button"
                        onClick={() => setImage(null)}
                        className="text-xs text-muted hover:text-red-600"
                      >
                        Remove
                      </button>
                    ) : null}
                  </div>
                  {uploadError ? (
                    <p className="text-xs text-red-600">{uploadError}</p>
                  ) : null}
                </div>
              </div>
            </div>
          </div>
        </div>

        <div className="flex items-center justify-between border-t border-border bg-surface-muted/40 px-5 py-3">
          <div>
            {mode === "edit" && product && !product.isSystem ? (
              <button
                type="button"
                onClick={onDelete}
                className="text-xs font-medium text-rose-600 hover:text-rose-700"
              >
                Delete product
              </button>
            ) : null}
          </div>
          <div className="flex gap-2">
            <Button
              type="button"
              variant="secondary"
              size="sm"
              onClick={onClose}
              disabled={saving}
            >
              Cancel
            </Button>
            <Button type="submit" size="sm" isLoading={saving}>
              {mode === "create" ? "Create" : "Save"}
            </Button>
          </div>
        </div>

        <style jsx>{`
          :global(.input) {
            width: 100%;
            border-radius: 0.5rem;
            border: 1px solid var(--border);
            background: var(--surface);
            padding: 0.5rem 0.75rem;
            font-size: 0.875rem;
            color: var(--foreground);
          }
          :global(.input:focus) {
            outline: none;
            border-color: var(--primary);
          }
        `}</style>
      </form>
    </div>
  );
}