"use client";

import { useState } from "react";
import { Button, Card } from "@/components/ui";
import { Field, inputClass } from "@/components/ui/form";
import { MediaPicker } from "@/components/features/page-editor/media-picker";
import { SOCIAL_KEYS, type SiteSettings, type ThirdPartyCode } from "@/lib/site-settings";
import { Check, Panel, SaveBar, Select, SubTabs, useSection } from "./section-kit";

const TABS = [{ id: "general", label: "General" }, { id: "security", label: "Security settings" }, { id: "code", label: "Third-party code" }, { id: "datetime", label: "Date / Time" }, { id: "wishlist", label: "Wishlist" }, { id: "email", label: "Email" }] as const;
type Tab = (typeof TABS)[number]["id"];

interface Props {
  siteId: string;
  settings: SiteSettings;
  timezone: string;
  timezones: string[];
  pages: { id: string; title: string }[];
  libraries: { key: string; label: string }[];
  recaptchaSecretSet: boolean;
  isSuperAdmin: boolean;
  thirdPartyCount: number;
  primaryHost: string | null;
}

const LAYOUTS = [{ value: "default", label: "Default" }, { value: "narrow", label: "Narrow" }, { value: "homepage", label: "Homepage" }] as const;

/** ShowOff "Site Settings": General, Security Settings, Third-party Code, Date / Time, Wishlist (+ Email). */
export function SiteSettingsTabs(p: Props) {
  const [tab, setTab] = useState<Tab>("general");
  const tabs = TABS.filter((t) => t.id !== "code" || p.isSuperAdmin);
  return (
    <div>
      <SubTabs label="Site settings" tabs={tabs} value={tab} onChange={setTab} />
      <Panel label="Site settings" tab={tab}>
        {tab === "general" ? <General {...p} /> : null}
        {tab === "security" ? <Security {...p} /> : null}
        {tab === "code" && p.isSuperAdmin ? <ThirdParty {...p} /> : null}
        {tab === "datetime" ? <DateTime {...p} /> : null}
        {tab === "wishlist" ? <Wishlist {...p} /> : null}
        {tab === "email" ? <Email {...p} /> : null}
      </Panel>
    </div>
  );
}

function General({ siteId, settings, pages, primaryHost }: Props) {
  const { pending, msg, errors, save } = useSection(siteId);
  const [g, setG] = useState(settings.general);
  const [site, setSite] = useState({ siteTitle: settings.siteTitle, tagline: settings.tagline, footerText: settings.footerText, logoMediaId: settings.logoMediaId, faviconMediaId: settings.faviconMediaId, social: settings.social });
  const patchSite = (x: Partial<typeof site>) => setSite((v) => ({ ...v, ...x }));
  return (
    <>
      <Card className="space-y-4 p-4">
        <h2 className="text-sm font-semibold">Site details</h2>
        <div className="grid gap-4 sm:grid-cols-2">
          <Field id="g-title" label="Site title" error={errors["siteTitle"]}><input id="g-title" className={inputClass} maxLength={80} value={site.siteTitle} onChange={(e) => patchSite({ siteTitle: e.target.value })} /></Field>
          <Field id="g-tag" label="Tagline" error={errors["tagline"]}><input id="g-tag" className={inputClass} maxLength={160} value={site.tagline} onChange={(e) => patchSite({ tagline: e.target.value })} /></Field>
          <Field id="g-footer" label="Footer text" error={errors["footerText"]} className="sm:col-span-2"><input id="g-footer" className={inputClass} maxLength={500} value={site.footerText} onChange={(e) => patchSite({ footerText: e.target.value })} /></Field>
        </div>
        <div className="grid gap-4 sm:grid-cols-2">
          <div className="space-y-1"><span className="block text-xs font-medium">Logo (shown in the website header)</span><MediaPicker siteId={siteId} label="Logo" value={site.logoMediaId} onChange={(v) => patchSite({ logoMediaId: v })} /></div>
          <div className="space-y-1"><span className="block text-xs font-medium">Favicon (small browser-tab icon)</span><MediaPicker siteId={siteId} label="Favicon" value={site.faviconMediaId} onChange={(v) => patchSite({ faviconMediaId: v })} /></div>
        </div>
      </Card>
      <Card className="space-y-4 p-4">
        <h2 className="text-sm font-semibold">Social links</h2>
        <div className="grid gap-4 sm:grid-cols-2">
          {SOCIAL_KEYS.map((k) => (
            <Field key={k} id={`g-so-${k}`} label={k.charAt(0).toUpperCase() + k.slice(1)} error={errors[`social.${k}`]}><input id={`g-so-${k}`} className={inputClass} placeholder="https://" value={site.social[k]} onChange={(e) => patchSite({ social: { ...site.social, [k]: e.target.value } })} /></Field>
          ))}
        </div>
      </Card>
      <Card className="space-y-4 p-4">
        <h2 className="text-sm font-semibold">&lsquo;Page Not Found&rsquo; 404 redirection</h2>
        <Field id="g-404" label="404 Page" help="The page shown when someone opens an address that doesn't exist. Search engines are told not to index it, so a custom page made for this purpose is best." error={errors["notFoundPageId"]}>
          <select id="g-404" className={inputClass} value={g.notFoundPageId} onChange={(e) => setG({ ...g, notFoundPageId: e.target.value })} aria-describedby="g-404-help">
            <option value="">- Default -</option>
            {pages.map((x) => <option key={x.id} value={x.id}>{x.title}</option>)}
          </select>
        </Field>
      </Card>
      <Card className="space-y-4 p-4">
        <h2 className="text-sm font-semibold">Page layout</h2>
        <div className="grid gap-4 sm:grid-cols-2">
          <Field id="g-layout" label="Default page layout" help="Used for new pages."><Select id="g-layout" value={g.defaultPageLayout} onChange={(v) => setG({ ...g, defaultPageLayout: v })} options={LAYOUTS} /></Field>
          <Field id="g-form" label="Default form preview layout"><Select id="g-form" value={g.formPreviewLayout} onChange={(v) => setG({ ...g, formPreviewLayout: v })} options={[{ value: "inherit", label: "- inherit -" }, ...LAYOUTS]} /></Field>
        </div>
      </Card>
      {primaryHost ? (
        <Card className="space-y-2 p-4 text-sm">
          <h2 className="text-sm font-semibold">Domain</h2>
          <p className="text-muted-foreground">Primary address: <span className="font-mono text-xs">{primaryHost}</span>. A platform administrator can change or add domains under Organizations &rarr; the organization &rarr; Websites &rarr; Domains.</p>
        </Card>
      ) : null}
      <SaveBar pending={pending} msg={msg} onSave={() => save("general", { ...g, ...site })} />
    </>
  );
}

function Security({ siteId, settings, recaptchaSecretSet }: Props) {
  const { pending, msg, errors, save } = useSection(siteId);
  const [s, setS] = useState(settings.security);
  const [an, setAn] = useState(settings.analytics);
  const [secret, setSecret] = useState("");
  const [set, setSet] = useState(recaptchaSecretSet);
  return (
    <>
      <Card className="space-y-4 p-4">
        <h2 className="text-sm font-semibold">Response headers</h2>
        <p className="text-xs text-muted-foreground">These values are saved with the website. A platform administrator applies them at the hosting layer.</p>
        <Field id="sec-xfo" label="X-Frame-Options (header)" help="Whether your site can be loaded inside another web page, for example in an iframe."><Select id="sec-xfo" value={s.xFrameOptions} onChange={(v) => setS({ ...s, xFrameOptions: v })} options={[{ value: "DENY", label: "Deny (the page cannot be displayed in a frame)" }, { value: "SAMEORIGIN", label: "Same origin (only this site can frame it)" }]} /></Field>
        <Field id="sec-ref" label="Referrer-Policy (header)" help="How much referrer information is included with requests."><Select id="sec-ref" value={s.referrerPolicy} onChange={(v) => setS({ ...s, referrerPolicy: v })} options={(["no-referrer", "same-origin", "strict-origin", "strict-origin-when-cross-origin", "origin", "no-referrer-when-downgrade"] as const).map((v) => ({ value: v, label: v }))} /></Field>
        <Field id="sec-csp" label="Content-Security-Policy (header)" help="An extra layer of protection against cross-site scripting and data injection. One line." error={errors["contentSecurityPolicy"]}><input id="sec-csp" className={`${inputClass} font-mono`} maxLength={2000} value={s.contentSecurityPolicy} onChange={(e) => setS({ ...s, contentSecurityPolicy: e.target.value })} aria-describedby="sec-csp-help" /></Field>
        <Field id="sec-cache" label="Cache-Control (header)" error={errors["cacheControl"]}><input id="sec-cache" className={`${inputClass} font-mono`} maxLength={200} value={s.cacheControl} onChange={(e) => setS({ ...s, cacheControl: e.target.value })} /></Field>
      </Card>
      <Card className="space-y-4 p-4">
        <h2 className="text-sm font-semibold">Forms</h2>
        <Field id="sec-block" label="Blocked email addresses" help="Comma-separated addresses or @domains. Submissions from them are marked as spam." error={errors["blockedEmails"]}>
          <textarea id="sec-block" rows={3} className={inputClass} maxLength={5000} value={s.blockedEmails} onChange={(e) => setS({ ...s, blockedEmails: e.target.value })} placeholder="spam@example.com, @badcompany.com" aria-describedby="sec-block-help" />
        </Field>
        <h3 className="text-sm font-semibold">Google reCAPTCHA</h3>
        <div className="grid gap-4 sm:grid-cols-2">
          <Field id="sec-site" label="Site key" error={errors["recaptchaSiteKey"]}><input id="sec-site" className={inputClass} maxLength={100} value={s.recaptchaSiteKey} onChange={(e) => setS({ ...s, recaptchaSiteKey: e.target.value })} autoComplete="off" /></Field>
          <Field id="sec-secret" label="Secret key" help={set ? "A secret key is saved and is not shown again. Enter a new one to replace it." : undefined} error={errors["recaptchaSecret"]}>
            <input id="sec-secret" type="password" className={inputClass} maxLength={100} value={secret} placeholder={set ? "••••••••••••" : ""} onChange={(e) => setSecret(e.target.value)} autoComplete="off" aria-describedby={set ? "sec-secret-help" : undefined} />
          </Field>
        </div>
      </Card>
      <Card className="space-y-4 p-4">
        <h2 className="text-sm font-semibold">Analytics</h2>
        <div className="grid gap-4 sm:grid-cols-2">
          <Field id="an-provider" label="Provider"><Select id="an-provider" value={an.provider} onChange={(v) => setAn({ provider: v, id: "" })} options={[{ value: "none", label: "None" }, { value: "ga4", label: "Google Analytics 4" }, { value: "plausible", label: "Plausible" }]} /></Field>
          {an.provider !== "none" ? <Field id="an-id" label={an.provider === "ga4" ? "Measurement ID" : "Domain"} help={an.provider === "ga4" ? "Looks like G-XXXXXXXXXX." : "The domain registered in Plausible."} error={errors["analytics.id"]}><input id="an-id" className={inputClass} value={an.id} onChange={(e) => setAn({ ...an, id: e.target.value })} aria-describedby="an-id-help" /></Field> : null}
        </div>
      </Card>
      <SaveBar pending={pending} msg={msg} onSave={() => save("security", { ...s, analytics: an, ...(secret ? { recaptchaSecret: secret } : {}) }, () => { if (secret) setSet(true); setSecret(""); })} />
    </>
  );
}

function ThirdParty({ siteId, settings, thirdPartyCount }: Props) {
  const { pending, msg, errors, save } = useSection(siteId);
  const [items, setItems] = useState<ThirdPartyCode[]>(settings.thirdParty);
  const [draft, setDraft] = useState<ThirdPartyCode | null>(null);
  const [armed, setArmed] = useState<string | null>(null);
  const persist = (next: ThirdPartyCode[], onOk?: () => void) => save("thirdParty", next, () => { setItems(next); onOk?.(); });
  return (
    <>
      <p role="note" className="rounded-md border border-border bg-muted p-3 text-sm">You&apos;re welcome to add custom or AI-generated code to this website. Custom code is not tested or supported, so use it at your own discretion. It runs on every public page of this website. Only platform administrators can change it.</p>
      <Card className="space-y-3 p-4">
        <div className="flex items-center justify-between gap-3">
          <h2 className="text-sm font-semibold">Third-party code ({items.length || thirdPartyCount})</h2>
          <Button variant="secondary" onClick={() => setDraft({ id: crypto.randomUUID().slice(0, 12), title: "", kind: "css", active: true, code: "" })}>Add third-party code</Button>
        </div>
        {items.length === 0 ? <p className="text-sm text-muted-foreground">No custom code yet.</p> : (
          <table className="w-full text-left text-sm">
            <caption className="sr-only">Third-party code</caption>
            <thead className="border-b border-border text-xs text-muted-foreground"><tr><th scope="col" className="py-2 font-medium">Title</th><th scope="col" className="py-2 font-medium">Type</th><th scope="col" className="py-2 font-medium">Status</th><th scope="col" className="py-2"><span className="sr-only">Actions</span></th></tr></thead>
            <tbody className="divide-y divide-border">
              {items.map((c) => (
                <tr key={c.id}>
                  <td className="py-2">{c.title}</td><td className="py-2 uppercase">{c.kind}</td><td className="py-2">{c.active ? "Active" : "Off"}</td>
                  <td className="space-x-2 py-2 text-right">
                    <Button variant="secondary" onClick={() => setDraft(c)}>Edit<span className="sr-only"> {c.title}</span></Button>
                    {armed === c.id ? (<><Button variant="danger" disabled={pending} onClick={() => { setArmed(null); persist(items.filter((x) => x.id !== c.id)); }}>Confirm delete</Button><Button variant="secondary" onClick={() => setArmed(null)}>Cancel</Button></>) : <Button variant="secondary" onClick={() => setArmed(c.id)}>Delete<span className="sr-only"> {c.title}</span></Button>}
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        )}
        <p role="status" aria-live="polite" className={msg ? (msg.ok ? "text-sm text-success" : "text-sm text-danger") : "sr-only"}>{msg?.text}</p>
      </Card>
      {draft ? (
        <Card className="space-y-4 p-4">
          <h2 className="text-sm font-semibold">{items.some((x) => x.id === draft.id) ? "Edit code" : "New code"}</h2>
          <div className="grid gap-4 sm:grid-cols-2">
            <Field id="tp-title" label="Title" error={errors["0.title"]}><input id="tp-title" className={inputClass} maxLength={80} value={draft.title} onChange={(e) => setDraft({ ...draft, title: e.target.value })} /></Field>
            <Field id="tp-kind" label="Type"><Select id="tp-kind" value={draft.kind} onChange={(v) => setDraft({ ...draft, kind: v })} options={[{ value: "css", label: "CSS (added as a stylesheet)" }, { value: "js", label: "JavaScript (runs after the page loads)" }]} /></Field>
          </div>
          <Field id="tp-code" label="Code" error={errors["0.code"]}><textarea id="tp-code" rows={8} className={`${inputClass} font-mono`} maxLength={20000} value={draft.code} onChange={(e) => setDraft({ ...draft, code: e.target.value })} spellCheck={false} /></Field>
          <Check id="tp-active" label="Active" checked={draft.active} onChange={(v) => setDraft({ ...draft, active: v })} />
          <div className="flex gap-2">
            <Button disabled={pending || !draft.title.trim() || !draft.code.trim()} onClick={() => persist(items.some((x) => x.id === draft.id) ? items.map((x) => (x.id === draft.id ? draft : x)) : [...items, draft], () => setDraft(null))}>{pending ? "Saving…" : "Save code"}</Button>
            <Button variant="secondary" onClick={() => setDraft(null)}>Cancel</Button>
          </div>
        </Card>
      ) : null}
    </>
  );
}

function DateTime({ siteId, settings, timezone, timezones }: Props) {
  const { pending, msg, errors, save } = useSection(siteId);
  const [d, setD] = useState(settings.datetime);
  const [tz, setTz] = useState(timezone);
  const zones = timezones.includes(tz) ? timezones : [tz, ...timezones];
  return (
    <>
      <Card className="space-y-4 p-4">
        <Field id="dt-tz" label="Time zone" help="Used for event times and the dates shown on the website." error={errors["timezone"]}>
          <select id="dt-tz" className={inputClass} value={tz} onChange={(e) => setTz(e.target.value)} aria-describedby="dt-tz-help">{zones.map((z) => <option key={z} value={z}>{z.replace(/_/g, " ")}</option>)}</select>
        </Field>
        <div className="grid gap-4 sm:grid-cols-2">
          <Field id="dt-date" label="Date format"><Select id="dt-date" value={d.dateFormat} onChange={(v) => setD({ ...d, dateFormat: v })} options={[{ value: "d MMM yyyy", label: "20 Oct 2026" }, { value: "dd/MM/yyyy", label: "20/10/2026" }, { value: "MM/dd/yyyy", label: "10/20/2026" }, { value: "yyyy-MM-dd", label: "2026-10-20" }]} /></Field>
          <Field id="dt-time" label="Time format"><Select id="dt-time" value={d.timeFormat} onChange={(v) => setD({ ...d, timeFormat: v })} options={[{ value: "24", label: "14:30 (24 hour)" }, { value: "12", label: "2:30 PM (12 hour)" }]} /></Field>
        </div>
      </Card>
      <SaveBar pending={pending} msg={msg} onSave={() => save("datetime", { ...d, timezone: tz })} />
    </>
  );
}

function Wishlist({ siteId, settings, libraries }: Props) {
  const { pending, msg, errors, save } = useSection(siteId);
  const [w, setW] = useState(settings.wishlist);
  return (
    <>
      <Card className="space-y-4 p-4">
        <h2 className="text-sm font-semibold">Wishlist settings</h2>
        <Check id="wl-on" label="Enable the wishlist" checked={w.enabled} onChange={(v) => setW({ ...w, enabled: v })} />
        <Field id="wl-alias" label="Wishlist title alias" help="The name visitors see for the wishlist." error={errors["alias"]}><input id="wl-alias" className={inputClass} maxLength={40} value={w.alias} onChange={(e) => setW({ ...w, alias: e.target.value })} aria-describedby="wl-alias-help" /></Field>
        <fieldset className="space-y-1">
          <legend className="text-xs font-medium">Wishlist icon</legend>
          {(["heart", "star", "bookmark"] as const).map((i) => (
            <label key={i} className="flex items-center gap-2 text-sm capitalize"><input type="radio" name="wl-icon" checked={w.icon === i} onChange={() => setW({ ...w, icon: i })} />{i}</label>
          ))}
        </fieldset>
        <fieldset className="space-y-1">
          <legend className="text-xs font-medium">Enabled libraries</legend>
          {libraries.map((l) => (
            <label key={l.key} className="flex items-center gap-2 text-sm"><input type="checkbox" checked={w.libraries.includes(l.key)} onChange={(e) => setW({ ...w, libraries: e.target.checked ? [...w.libraries, l.key] : w.libraries.filter((x) => x !== l.key) })} />{l.label}</label>
          ))}
        </fieldset>
      </Card>
      <SaveBar pending={pending} msg={msg} onSave={() => save("wishlist", w)} />
    </>
  );
}

function Email({ siteId, settings }: Props) {
  const { pending, msg, errors, save } = useSection(siteId);
  const [e, setE] = useState(settings.email);
  return (
    <>
      <Card className="space-y-4 p-4">
        <h2 className="text-sm font-semibold">Email settings</h2>
        <div className="grid gap-4 sm:grid-cols-2">
          <Field id="em-name" label="Sender name" error={errors["fromName"]}><input id="em-name" className={inputClass} maxLength={80} value={e.fromName} onChange={(x) => setE({ ...e, fromName: x.target.value })} /></Field>
          <Field id="em-reply" label="Reply-to address" error={errors["replyTo"]}><input id="em-reply" type="email" className={inputClass} maxLength={254} value={e.replyTo} onChange={(x) => setE({ ...e, replyTo: x.target.value })} /></Field>
          <Field id="em-notify" label="Send form notifications to" help="Where new form submissions are announced." error={errors["notifyTo"]} className="sm:col-span-2"><input id="em-notify" type="email" className={inputClass} maxLength={254} value={e.notifyTo} onChange={(x) => setE({ ...e, notifyTo: x.target.value })} aria-describedby="em-notify-help" /></Field>
        </div>
      </Card>
      <SaveBar pending={pending} msg={msg} onSave={() => save("email", e)} />
    </>
  );
}
