﻿"use client";

import { useEffect, useRef, useState } from "react";
import { API, fallbackSettings, resolveImageUrl, type SiteSettings } from "@/lib/api";

type FieldDef = {
  name: keyof SiteSettings;
  label: string;
  hint?: string;
  span?: boolean;
};

type GroupDef = {
  id: string;
  title: string;
  description: string;
  icon: React.ReactNode;
  fields: FieldDef[];
};

const icon = (d: string) => (
  <svg viewBox="0 0 24 24" width="15" height="15" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
    <path d={d} />
  </svg>
);

const groups: GroupDef[] = [
  {
    id: "identity",
    title: "Organization identity",
    description: "Name, tagline and logo used across the website and on printed certificates, ID cards and receipts.",
    icon: icon("M13 2 3 14h7l-1 8 10-12h-7l1-8z"),
    fields: [
      { name: "site_name", label: "Organization name", span: true },
      { name: "short_name", label: "Short name", hint: "Shown on badges, the browser tab and the card footer." },
      { name: "tagline", label: "Tagline", span: true },
      { name: "logo_url", label: "Logo image URL", hint: "A transparent PNG works best on every background." },
      { name: "favicon_url", label: "Favicon URL", hint: "Small icon shown in the browser tab." },
    ],
  },
  {
    id: "colors",
    title: "Color palette",
    description: "Colors that drive the website header, buttons, cards and printed documents.",
    icon: icon("M12 22a10 10 0 1 1 10-10c0 2-1.5 3-3 3h-2a3 3 0 0 0-2 5c1 1 1 2 0 2z"),
    fields: [
      { name: "primary_color", label: "Primary" },
      { name: "secondary_color", label: "Secondary" },
      { name: "accent_color", label: "Accent" },
      { name: "background_color", label: "Page background" },
      { name: "text_color", label: "Body text" },
    ],
  },
  {
    id: "contact",
    title: "Contact information",
    description: "Shown in the website footer and on the back of the identity card.",
    icon: icon("M4 4h16c1.1 0 2 .9 2 2v12a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V6c0-1.1.9-2 2-2zm16 4-8 5-8-5"),
    fields: [
      { name: "address", label: "Registered address", span: true },
      { name: "phone", label: "Phone" },
      { name: "email", label: "Email" },
    ],
  },
  {
    id: "social",
    title: "Social links",
    description: "Links shown in the website footer.",
    icon: icon("M10 13a5 5 0 0 0 7.5.5l3-3a5 5 0 0 0-7-7l-1.5 1.5M14 11a5 5 0 0 0-7.5-.5l-3 3a5 5 0 0 0 7 7l1.5-1.5"),
    fields: [
      { name: "facebook_url", label: "Facebook URL", span: true },
      { name: "instagram_url", label: "Instagram URL", span: true },
      { name: "whatsapp_url", label: "WhatsApp URL", span: true },
    ],
  },
];

function Field({ field, value, onChange }: { field: FieldDef; value: string; onChange: (name: keyof SiteSettings, value: string) => void }) {
  const isColor = field.name.endsWith("_color");
  const id = `field-${field.name}`;
  return (
    <label htmlFor={id} className={`block ${field.span ? "sm:col-span-2" : ""}`}>
      <span className="mb-1.5 flex items-center justify-between gap-2 text-[11.5px] font-black text-[var(--color-ink)]">
        {field.label}
      </span>
      {isColor ? (
        <div className="flex items-center gap-2">
          <span className="relative h-9 w-11 shrink-0 overflow-hidden rounded-md border border-[var(--color-hairline)] shadow-inner">
            <input
              type="color"
              value={/^#[0-9a-fA-F]{6}$/.test(value) ? value : "#000000"}
              onChange={(e) => onChange(field.name, e.target.value)}
              aria-label={`${field.label} picker`}
              className="absolute -inset-2 h-14 w-14 cursor-pointer"
            />
          </span>
          <input
            id={id}
            name={field.name}
            type="text"
            value={value}
            onChange={(e) => onChange(field.name, e.target.value)}
            className="w-full rounded-md border border-[var(--color-hairline)] bg-[var(--color-canvas-soft)] px-2.5 py-2 font-mono text-[12px] font-semibold uppercase text-[var(--color-ink)] outline-none focus:border-[var(--color-primary)] focus:ring-4 focus:ring-[var(--color-primary)]/10"
          />
        </div>
      ) : (
        <input
          id={id}
          name={field.name}
          type="text"
          value={value}
          onChange={(e) => onChange(field.name, e.target.value)}
          className="w-full rounded-md border border-[var(--color-hairline)] bg-[var(--color-canvas-soft)] px-2.5 py-2 text-[12px] font-medium text-[var(--color-ink)] outline-none focus:border-[var(--color-primary)] focus:ring-4 focus:ring-[var(--color-primary)]/10"
        />
      )}
      {field.hint ? <span className="mt-1 block text-[10.5px] font-semibold text-[var(--color-ink-mute)]">{field.hint}</span> : null}
    </label>
  );
}

export function AdminBrandSettings() {
  const [settings, setSettings] = useState<SiteSettings>(fallbackSettings);
  const [saved, setSaved] = useState<SiteSettings>(fallbackSettings);
  const [message, setMessage] = useState<{ tone: "ok" | "error"; text: string } | null>(null);
  const [uploading, setUploading] = useState(false);
  const [saving, setSaving] = useState(false);
  const toastTimer = useRef<ReturnType<typeof setTimeout> | null>(null);

  const dirty = JSON.stringify(settings) !== JSON.stringify(saved);

  useEffect(() => {
    const token = localStorage.getItem("ngo_admin_token");
    fetch(`${API}/admin/settings`, { headers: { Authorization: `Bearer ${token}` } })
      .then((res) => res.json())
      .then((data) => {
        if (!data) return;
        const merged = { ...fallbackSettings, ...data };
        setSettings(merged);
        setSaved(merged);
      })
      .catch(() => setMessage({ tone: "error", text: "Could not load settings." }));
  }, []);

  useEffect(() => () => {
    if (toastTimer.current) clearTimeout(toastTimer.current);
  }, []);

  const notify = (tone: "ok" | "error", text: string) => {
    setMessage({ tone, text });
    if (toastTimer.current) clearTimeout(toastTimer.current);
    toastTimer.current = setTimeout(() => setMessage(null), 4000);
  };

  const update = (name: keyof SiteSettings, value: string) => {
    setSettings((prev) => ({ ...prev, [name]: value }));
  };

  const save = async (payload?: SiteSettings) => {
    setSaving(true);
    const token = localStorage.getItem("ngo_admin_token");
    try {
      const res = await fetch(`${API}/admin/settings`, {
        method: "PUT",
        headers: { "Content-Type": "application/json", Authorization: `Bearer ${token}` },
        body: JSON.stringify(payload || settings),
      });
      if (!res.ok) throw new Error("Save failed");
      const result = await res.json();
      const merged = { ...fallbackSettings, ...result };
      setSettings(merged);
      setSaved(merged);
      notify("ok", "Changes saved. Public pages may take up to a minute to refresh.");
    } catch {
      notify("error", "Could not save settings. Please try again.");
    } finally {
      setSaving(false);
    }
  };

  const onSignatureFile = async (event: React.ChangeEvent<HTMLInputElement>) => {
    const file = event.target.files?.[0];
    event.target.value = "";
    if (!file) return;
    setUploading(true);
    setMessage(null);
    try {
      const fd = new FormData();
      fd.append("file", file);
      const upRes = await fetch(`${API}/upload`, { method: "POST", body: fd });
      if (!upRes.ok) throw new Error("Upload failed");
      const upData = await upRes.json();
      if (!upData?.url) throw new Error("Upload failed");
      await save({ ...settings, signature_url: upData.url });
      notify("ok", "Signature uploaded and saved. It now appears on certificates, ID cards and receipts.");
    } catch {
      notify("error", "Signature upload failed. Please try again.");
    } finally {
      setUploading(false);
    }
  };

  const removeSignature = async () => {
    await save({ ...settings, signature_url: "" });
    notify("ok", "Signature removed.");
  };

  const signatureUrl = settings.signature_url ? resolveImageUrl(settings.signature_url) : "";

  return (
    <div className="mx-auto max-w-7xl">
      {/* â”€â”€ Header â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */}
      <div className="mb-5 flex flex-wrap items-end justify-between gap-3">
        <div>
          <p className="text-[10px] font-black uppercase tracking-[0.14em] text-[var(--color-primary)]">Settings</p>
          <h1 className="mt-0.5 text-xl font-black text-[var(--color-ink)] md:text-2xl">Brand &amp; identity</h1>
          <p className="mt-1 max-w-2xl text-[11.5px] font-medium text-[var(--color-ink-mute)]">
            Everything that defines how your organization looks â€” on the website and on printed documents.
          </p>
        </div>
        <div className="flex items-center gap-2">
          {dirty ? (
            <span className="flex items-center gap-1.5 rounded-full border border-[var(--color-hairline)] bg-[var(--color-canvas-soft)] px-3 py-1.5 text-[11px] font-black text-[#c2410c]">
              <span className="h-1.5 w-1.5 rounded-full bg-[#d97706]" /> Unsaved changes
            </span>
          ) : (
            <span className="flex items-center gap-1.5 rounded-full border border-[var(--color-canvas-soft)] bg-[var(--color-canvas-soft)] px-3 py-1.5 text-[11px] font-black text-[var(--color-primary-deep)]">
              <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="3" strokeLinecap="round" strokeLinejoin="round">
                <polyline points="20 6 9 17 4 12" />
              </svg>
              All changes saved
            </span>
          )}
          <button
            onClick={() => save()}
            disabled={!dirty || saving}
            className="rounded-md bg-gradient-to-r from-[var(--color-primary)] to-[var(--color-primary-deep)] px-4 py-2 text-[11.5px] font-black text-white shadow-[0_8px_18px_rgba(93,111,241,0.28)] transition hover:brightness-105 disabled:cursor-not-allowed disabled:opacity-50"
          >
            {saving ? "Saving..." : "Save changes"}
          </button>
        </div>
      </div>

      {/* â”€â”€ Toast â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */}
      {message ? (
        <div
          role="status"
          className={`mb-4 flex items-center gap-2.5 rounded-md border px-3.5 py-2.5 text-[11.5px] font-bold shadow-sm ${
            message.tone === "ok" ? "border-[var(--color-canvas-soft)] bg-[var(--color-canvas-soft)] text-[var(--color-primary-deep)]" : "border-[var(--color-hairline)] bg-[var(--color-canvas-soft)] text-[var(--color-ink)]"
          }`}
        >
          {message.tone === "ok" ? (
            <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.6" strokeLinecap="round" strokeLinejoin="round">
              <polyline points="20 6 9 17 4 12" />
            </svg>
          ) : (
            <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round">
              <circle cx="12" cy="12" r="10" />
              <line x1="12" y1="8" x2="12" y2="12" />
              <line x1="12" y1="16" x2="12.01" y2="16" />
            </svg>
          )}
          {message.text}
        </div>
      ) : null}

      {/* â”€â”€ Jump nav â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */}
      <div className="no-print mb-4 flex flex-wrap gap-1.5">
        {groups.map((group) => (
          <a
            key={group.id}
            href={`#section-${group.id}`}
            className="rounded-full border border-[var(--color-hairline)] bg-white px-3 py-1.5 text-[11px] font-black text-[var(--color-ink)] transition hover:border-[var(--color-hairline)] hover:text-[var(--color-primary)]"
          >
            {group.title}
          </a>
        ))}
      </div>

      <div className="grid items-start gap-5 lg:grid-cols-[1fr_340px]">
        {/* â”€â”€ Left: sections â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */}
        <div className="grid gap-4">
          {groups.map((group) => (
            <section
              key={group.id}
              id={`section-${group.id}`}
              className="scroll-mt-24 rounded-lg border border-[var(--color-hairline)] bg-white p-4 shadow-sm sm:p-5"
            >
              <div className="mb-4 flex items-start gap-3">
                <span className="grid h-8 w-8 shrink-0 place-items-center rounded-md bg-[var(--color-canvas-soft)] text-[var(--color-primary)]">{group.icon}</span>
                <div>
                  <h2 className="text-[14px] font-black text-[var(--color-ink)]">{group.title}</h2>
                  <p className="mt-0.5 text-[11px] font-medium leading-snug text-[var(--color-ink-mute)]">{group.description}</p>
                </div>
              </div>
              <div className="grid gap-3.5 sm:grid-cols-2">
                {group.fields.map((field) => (
                  <Field key={field.name} field={field} value={settings[field.name] || ""} onChange={update} />
                ))}
              </div>
            </section>
          ))}

          {/* â”€â”€ Signature section â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */}
          <section id="section-signature" className="scroll-mt-24 rounded-lg border border-[var(--color-hairline)] bg-white p-4 shadow-sm sm:p-5">
            <div className="mb-4 flex items-start gap-3">
              <span className="grid h-8 w-8 shrink-0 place-items-center rounded-md bg-[var(--color-canvas-soft)] text-[var(--color-primary)]">
                <svg viewBox="0 0 24 24" width="15" height="15" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
                  <path d="M20 4c-6.5 0-10 4-13 8-1.5 2-3 4-3 4" />
                  <path d="M17 21c-2.5-1.5-4-4.5-4-8" />
                </svg>
              </span>
              <div>
                <h2 className="text-[14px] font-black text-[var(--color-ink)]">Authorised signatory</h2>
                <p className="mt-0.5 text-[11px] font-medium leading-snug text-[var(--color-ink-mute)]">
                  Upload a transparent PNG of your signature. It is placed under the {"\u201CAuthorised Signatory\u201D"} line on certificates, ID cards and receipts.
                </p>
              </div>
            </div>

            <div className="flex flex-wrap items-center gap-4">
              {signatureUrl ? (
                <div className="flex items-center gap-3 rounded-md border border-[var(--color-hairline)] bg-[var(--color-canvas-soft)] p-2 pr-3">
                  {/* eslint-disable-next-line @next/next/no-img-element */}
                  <img src={signatureUrl} alt="Authorised signatory signature" className="h-12 w-40 rounded border border-[var(--color-hairline)] bg-white object-contain p-1" />
                  <div>
                    <p className="text-[11px] font-black text-[var(--color-ink)]">Signature active</p>
                    <button type="button" onClick={removeSignature} className="mt-0.5 text-[11px] font-bold text-[var(--color-ink)] hover:underline">
                      Remove signature
                    </button>
                  </div>
                </div>
              ) : (
                <div className="grid h-14 w-40 place-items-center rounded-md border border-dashed border-[var(--color-hairline)] bg-[var(--color-canvas-soft)] text-[10.5px] font-black uppercase tracking-wide text-[var(--color-ink-mute)]">
                  No signature set
                </div>
              )}
              <div className="min-w-[220px] flex-1">
                <label className="mb-1.5 block text-[11.5px] font-black text-[var(--color-ink)]">Upload signature (PNG)</label>
                <label className="inline-block cursor-pointer rounded-md bg-gradient-to-r from-[var(--color-primary)] to-[var(--color-primary-deep)] px-4 py-2 text-[11.5px] font-black text-white shadow-[0_8px_18px_rgba(93,111,241,0.28)] transition hover:brightness-105 disabled:opacity-60">
                  <input type="file" accept="image/png,image/*" className="sr-only" disabled={uploading} onChange={onSignatureFile} />
                  {uploading ? "Uploading..." : signatureUrl ? "Replace signature" : "Choose PNG file"}
                </label>
                <p className="mt-1.5 text-[10.5px] font-semibold text-[var(--color-ink-mute)]">Or paste an image URL in the {"\u201CSignature URL\u201D"} field above.</p>
              </div>
            </div>
          </section>
        </div>

        {/* â”€â”€ Right: live preview â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */}
        <aside className="lg:sticky lg:top-24">
          <div className="overflow-hidden rounded-lg border border-[var(--color-hairline)] bg-white shadow-sm">
            <div className="flex items-center justify-between border-b border-[var(--color-canvas-soft)] px-4 py-2.5">
              <span className="text-[10px] font-black uppercase tracking-[0.14em] text-[var(--color-ink-mute)]">Live preview</span>
              <span className="h-1.5 w-1.5 animate-pulse rounded-full bg-[var(--color-primary-deep)]" />
            </div>

            <div className="p-4 text-white" style={{ background: `linear-gradient(135deg, ${settings.primary_color}, ${settings.secondary_color})` }}>
              <div className="flex items-center gap-3">
                {settings.logo_url ? (
                  // eslint-disable-next-line @next/next/no-img-element
                  <img src={resolveImageUrl(settings.logo_url)} alt="Logo" className="h-11 w-11 rounded-md object-contain ring-4 ring-white/25" />
                ) : (
                  <div className="grid h-11 w-11 shrink-0 place-items-center rounded-md bg-white/20 text-[15px] font-black">
                    {settings.short_name.slice(0, 2).toUpperCase()}
                  </div>
                )}
                <div className="min-w-0">
                  <p className="truncate text-[14px] font-black">{settings.site_name}</p>
                  <p className="truncate text-[11px] font-medium text-white/80">{settings.tagline}</p>
                </div>
              </div>
            </div>

            <div className="grid gap-3 p-4">
              <div className="flex items-center justify-between rounded-md border border-[var(--color-hairline)] bg-[var(--color-canvas-soft)] px-3 py-2">
                <span className="text-[10px] font-black uppercase tracking-[0.1em] text-[var(--color-ink-mute)]">Short name</span>
                <span className="text-[12px] font-black text-[var(--color-ink)]">{settings.short_name}</span>
              </div>

              <div>
                <p className="mb-1.5 text-[10px] font-black uppercase tracking-[0.1em] text-[var(--color-ink-mute)]">Color palette</p>
                <div className="grid grid-cols-5 gap-1.5">
                  {[
                    { name: "Primary", value: settings.primary_color },
                    { name: "Secondary", value: settings.secondary_color },
                    { name: "Accent", value: settings.accent_color },
                    { name: "Background", value: settings.background_color },
                    { name: "Text", value: settings.text_color },
                  ].map((c) => (
                    <div key={c.name} title={`${c.name}: ${c.value}`}>
                      <div className="h-8 rounded-md border border-[var(--color-canvas-soft)]" style={{ background: c.value }} />
                      <p className="mt-1 text-center text-[8.5px] font-bold uppercase text-[var(--color-ink-mute)]">{c.name}</p>
                    </div>
                  ))}
                </div>
              </div>

              {signatureUrl ? (
                <div>
                  <p className="mb-1.5 text-[10px] font-black uppercase tracking-[0.1em] text-[var(--color-ink-mute)]">Signature</p>
                  <div className="rounded-md border border-[var(--color-hairline)] bg-white p-2">
                    {/* eslint-disable-next-line @next/next/no-img-element */}
                    <img src={signatureUrl} alt="Signature preview" className="h-10 w-full object-contain object-left" />
                  </div>
                </div>
              ) : null}

              <div className="rounded-md border border-[var(--color-hairline)] bg-[var(--color-canvas-soft)] p-3">
                <p className="mb-1.5 text-[10px] font-black uppercase tracking-[0.1em] text-[var(--color-ink-mute)]">Appears on</p>
                <div className="flex flex-wrap gap-1.5">
                  {["Website", "Certificates", "ID cards", "Receipts"].map((label) => (
                    <span key={label} className="rounded-full bg-white px-2.5 py-1 text-[9.5px] font-black text-[var(--color-primary)] ring-1 ring-[var(--color-hairline)]">
                      {label}
                    </span>
                  ))}
                </div>
              </div>
            </div>
          </div>
        </aside>
      </div>

      {/* â”€â”€ Sticky save bar â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */}
      {dirty ? (
        <div className="fixed inset-x-0 bottom-0 z-40 border-t border-[var(--color-hairline)] bg-white/95 backdrop-blur">
          <div className="mx-auto flex max-w-7xl items-center justify-between gap-3 px-5 py-3">
            <p className="text-[11.5px] font-bold text-[var(--color-ink)]">
              You have unsaved changes to your brand settings.
            </p>
            <div className="flex items-center gap-2">
              <button
                onClick={() => setSettings(saved)}
                className="rounded-md border border-[var(--color-hairline)] px-4 py-2 text-[11.5px] font-black text-[var(--color-ink)] transition hover:border-[var(--color-hairline)] hover:text-[var(--color-primary)]"
              >
                Discard
              </button>
              <button
                onClick={() => save()}
                disabled={saving}
                className="rounded-md bg-gradient-to-r from-[var(--color-primary)] to-[var(--color-primary-deep)] px-5 py-2 text-[11.5px] font-black text-white shadow-[0_8px_18px_rgba(93,111,241,0.28)] transition hover:brightness-105 disabled:opacity-60"
              >
                {saving ? "Saving..." : "Save changes"}
              </button>
            </div>
          </div>
        </div>
      ) : null}

      {dirty ? <div className="h-16" /> : null}
    </div>
  );
}
