"use client";

import { useState } from "react";
import { Button } from "@/components/ui/button";
import { toast } from "@/components/admin/Toast";
import {
  FetchError,
  apiDelete,
  apiPatch,
  type PublicModule,
  slugify,
} from "@/lib/client-api";
import { ModuleIcon } from "@/components/icons";

const CATEGORY_TONE: Record<string, string> = {
  people: "bg-blue-100 text-blue-700",
  planning: "bg-indigo-100 text-indigo-700",
  finance: "bg-emerald-100 text-emerald-700",
  communication: "bg-sky-100 text-sky-700",
  guests: "bg-pink-100 text-pink-700",
  logistics: "bg-amber-100 text-amber-700",
  vendors: "bg-orange-100 text-orange-700",
  food: "bg-rose-100 text-rose-700",
  media: "bg-violet-100 text-violet-700",
  experience: "bg-fuchsia-100 text-fuchsia-700",
  custom: "bg-slate-100 text-slate-700",
};

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 ModuleLibraryAdmin({
  initialItems,
  total,
  systemCount,
}: {
  initialItems: PublicModule[];
  total: number;
  systemCount: number;
}) {
  const [items, setItems] = useState<PublicModule[]>(initialItems);
  const [editing, setEditing] = useState<PublicModule | null>(null);

  const onSaved = (saved: PublicModule) => {
    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);
  };

  return (
    <div className="space-y-4">
      <div className="grid gap-3 sm:grid-cols-3">
        <Stat label="Total modules" value={total} tone="bg-rose-50 text-rose-700" />
        <Stat label="System modules" value={systemCount} tone="bg-amber-50 text-amber-700" />
        <Stat
          label="Custom modules"
          value={total - systemCount}
          tone="bg-indigo-50 text-indigo-700"
        />
      </div>

      <ul className="grid gap-4 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-rose-100 via-pink-50 to-amber-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">
                  <span className="grid h-14 w-14 place-items-center overflow-hidden rounded-2xl bg-gradient-to-br from-rose-500 to-pink-600 text-white shadow-lg shadow-rose-500/30">
                    {m.iconImage ? (
                      // eslint-disable-next-line @next/next/no-img-element
                      <img
                        src={m.iconImage}
                        alt=""
                        className="h-full w-full object-contain"
                      />
                    ) : (
                      <ModuleIcon name={m.icon} className="h-7 w-7 text-white" />
                    )}
                  </span>
                </div>
              )}
              <div className="absolute right-3 top-3 flex flex-col items-end gap-1">
                <span
                  className={`rounded-full px-2 py-0.5 text-[10px] font-semibold uppercase tracking-wide ${
                    STATUS_TONE[m.status] ?? STATUS_TONE.disabled
                  }`}
                >
                  {m.status}
                </span>
                <span
                  className={`rounded-full px-2 py-0.5 text-[10px] font-semibold uppercase tracking-wide ${
                    CATEGORY_TONE[m.category] ?? CATEGORY_TONE.custom
                  }`}
                >
                  {m.category}
                </span>
              </div>
            </div>

            <div className="p-4">
              <div className="flex items-start gap-2">
                <span className="grid h-9 w-9 shrink-0 place-items-center overflow-hidden rounded-lg bg-gradient-to-br from-rose-500 to-pink-600 text-white shadow-sm">
                  {m.iconImage ? (
                    // eslint-disable-next-line @next/next/no-img-element
                    <img
                      src={m.iconImage}
                      alt=""
                      className="h-full w-full object-contain"
                    />
                  ) : (
                    <ModuleIcon name={m.icon} className="h-4 w-4 text-white" />
                  )}
                </span>
                <div className="min-w-0">
                  <p className="truncate text-sm font-semibold text-foreground">
                    {m.name}
                  </p>
                  <p className="truncate text-[11px] text-muted">{m.slug}</p>
                </div>
              </div>
              <p className="mt-2 line-clamp-2 text-xs text-muted">
                {m.description || "No description."}
              </p>
              <div className="mt-3 flex gap-2">
                <Button
                  size="sm"
                  variant="secondary"
                  className="flex-1"
                  onClick={() => setEditing(m)}
                >
                  Edit
                </Button>
              </div>
            </div>
          </li>
        ))}
      </ul>

      {editing ? (
        <ModuleEditModal
          module={editing}
          onClose={() => setEditing(null)}
          onSaved={onSaved}
        />
      ) : null}
    </div>
  );
}

function Stat({
  label,
  value,
  tone,
}: {
  label: string;
  value: number;
  tone: string;
}) {
  return (
    <div className={`rounded-2xl border border-border p-4 ${tone}`}>
      <p className="text-[10px] font-semibold uppercase tracking-wide opacity-70">
        {label}
      </p>
      <p className="mt-1 text-2xl font-semibold">{value}</p>
    </div>
  );
}

function ModuleEditModal({
  module,
  onClose,
  onSaved,
}: {
  module: PublicModule;
  onClose: () => void;
  onSaved: (m: PublicModule) => void;
}) {
  const [name, setName] = useState(module.name);
  const [slug, setSlug] = useState(module.slug);
  const [description, setDescription] = useState(module.description);
  const [category, setCategory] = useState(module.category);
  const [status, setStatus] = useState(module.status);
  const [icon, setIcon] = useState(module.icon);
  const [iconImage, setIconImage] = useState<string | null>(module.iconImage);
  const [image, setImage] = useState<string | null>(module.image);
  const [uploading, setUploading] = useState(false);
  const [uploadError, setUploadError] = useState<string | null>(null);
  const [saving, setSaving] = useState(false);

  const onUpload = async (
    file: File | null,
    target: "image" | "iconImage",
  ) => {
    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.");
      }
      if (target === "image") setImage(payload.data.url);
      else setIconImage(payload.data.url);
    } catch (err) {
      setUploadError(err instanceof Error ? err.message : "Upload failed.");
    } finally {
      setUploading(false);
    }
  };

  const onSave = async (e: React.FormEvent) => {
    e.preventDefault();
    setSaving(true);
    try {
      const updated = await apiPatch<PublicModule>(
        `/api/admin/modules/${module.id}`,
        {
          name,
          slug,
          description,
          category,
          status,
          icon,
          iconImage,
          image,
          isSystemModule: module.isSystemModule,
        },
      );
      toast("Module saved.", "success");
      onSaved(updated);
    } catch (err) {
      toast(
        err instanceof FetchError ? err.message : "Save failed.",
        "error",
      );
    } finally {
      setSaving(false);
    }
  };

  const onDelete = async () => {
    if (!confirm(`Delete module "${module.name}"?`)) return;
    try {
      await apiDelete(`/api/admin/modules/${module.id}`);
      toast("Module deleted.", "info");
      onSaved({ ...module, id: "__deleted__" } as PublicModule);
    } 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={onSave}
        className="w-full max-w-2xl overflow-hidden rounded-2xl border border-border bg-surface shadow-2xl"
      >
        <div className="relative h-36 w-full bg-gradient-to-br from-rose-100 via-pink-50 to-amber-50">
          {image ? (
            // eslint-disable-next-line @next/next/no-img-element
            <img
              src={image}
              alt={name}
              className="h-full w-full object-cover"
            />
          ) : (
            <div className="grid h-full w-full place-items-center">
              <span className="grid h-16 w-16 place-items-center overflow-hidden rounded-2xl bg-gradient-to-br from-rose-500 to-pink-600 text-white shadow-xl shadow-rose-500/30">
                {iconImage ? (
                  // eslint-disable-next-line @next/next/no-img-element
                  <img
                    src={iconImage}
                    alt=""
                    className="h-full w-full object-contain"
                  />
                ) : (
                  <ModuleIcon name={icon} className="h-8 w-8 text-white" />
                )}
              </span>
            </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">
            <Field label="Name">
              <input
                value={name}
                onChange={(e) => {
                  const v = e.target.value;
                  setName(v);
                  if (slug === slugify(module.name)) {
                    setSlug(slugify(v));
                  }
                }}
                className="input"
                required
              />
            </Field>
            <Field label="Slug">
              <input
                value={slug}
                onChange={(e) => setSlug(slugify(e.target.value))}
                className="input"
                required
              />
            </Field>
            <Field label="Icon name (Calendar / MapPin / Users / Wallet / Gift …)">
              <input
                value={icon}
                onChange={(e) => setIcon(e.target.value)}
                className="input"
              />
            </Field>
            <Field label="Custom icon image (optional, overrides the system icon)">
              <div className="flex items-center gap-3">
                <span className="grid h-12 w-12 shrink-0 place-items-center overflow-hidden rounded-lg border border-dashed border-border bg-surface-muted">
                  {iconImage ? (
                    // eslint-disable-next-line @next/next/no-img-element
                    <img
                      src={iconImage}
                      alt=""
                      className="h-full w-full object-contain"
                    />
                  ) : (
                    <ModuleIcon name={icon} className="h-6 w-6 text-muted" />
                  )}
                </span>
                <div className="flex-1 space-y-2">
                  <input
                    type="url"
                    value={iconImage ?? ""}
                    onChange={(e) => setIconImage(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, "iconImage");
                          e.target.value = "";
                        }}
                      />
                      {uploading ? "Uploading…" : "Upload icon"}
                    </label>
                    {iconImage ? (
                      <button
                        type="button"
                        onClick={() => setIconImage(null)}
                        className="text-xs text-muted hover:text-red-600"
                      >
                        Remove
                      </button>
                    ) : null}
                  </div>
                </div>
              </div>
            </Field>
            <Field label="Category">
              <select
                value={category}
                onChange={(e) => setCategory(e.target.value)}
                className="input"
              >
                {[
                  "people",
                  "planning",
                  "finance",
                  "communication",
                  "guests",
                  "logistics",
                  "vendors",
                  "food",
                  "media",
                  "experience",
                  "custom",
                ].map((c) => (
                  <option key={c} value={c}>
                    {c}
                  </option>
                ))}
              </select>
            </Field>
            <Field label="Status">
              <select
                value={status}
                onChange={(e) => setStatus(e.target.value)}
                className="input"
              >
                {["active", "disabled", "archived"].map((s) => (
                  <option key={s} value={s}>
                    {s}
                  </option>
                ))}
              </select>
            </Field>
            <Field label="Description" full>
              <textarea
                value={description}
                onChange={(e) => setDescription(e.target.value)}
                className="input min-h-[60px]"
                rows={2}
              />
            </Field>
          </div>

          <div className="rounded-xl border border-border bg-surface-muted/40 p-3">
            <p className="mb-2 text-xs font-semibold text-foreground">
              Cover image
            </p>
            <div className="flex items-center gap-3">
              <div className="grid h-16 w-24 place-items-center overflow-hidden rounded-lg border border-dashed border-border bg-white text-[10px] text-muted">
                {image ? (
                  // eslint-disable-next-line @next/next/no-img-element
                  <img src={image} alt="" className="h-full w-full object-cover" />
                ) : (
                  "no image"
                )}
              </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, "image");
                        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 className="flex items-center justify-between border-t border-border bg-surface-muted/40 px-5 py-3">
          <button
            type="button"
            disabled={module.isSystemModule}
            onClick={onDelete}
            className="text-xs font-medium text-rose-600 hover:text-rose-700 disabled:cursor-not-allowed disabled:opacity-40"
            title={
              module.isSystemModule
                ? "System modules cannot be deleted"
                : "Delete module"
            }
          >
            Delete module
          </button>
          <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}>
              Save changes
            </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 Field({
  label,
  full,
  children,
}: {
  label: string;
  full?: boolean;
  children: React.ReactNode;
}) {
  return (
    <div className={full ? "sm:col-span-2" : ""}>
      <label className="mb-1 block text-xs font-medium text-muted">{label}</label>
      {children}
    </div>
  );
}
