"use client";

import { useState } from "react";
import { Card } from "@/components/ui";
import { Field, inputClass } from "@/components/ui/form";
import { BUTTON_SIZES, FONT_SOURCES, IMAGE_RATIOS, LAYOUT_BLOCKS, PALETTE_KEYS, type FontSpec, type LayoutBlock, type LayoutOrder, type SiteDesign } from "@/lib/site-settings";
import { Check, Colour, Panel, SaveBar, Select, SubTabs, useSection } from "./section-kit";

const TABS = [{ id: "general", label: "General" }, { id: "layout", label: "Layout" }, { id: "colours", label: "Colours" }, { id: "typography", label: "Typography" }, { id: "elements", label: "Elements" }] as const;
type Tab = (typeof TABS)[number]["id"];
const FONTS = [{ value: "sans", label: "Sans-serif" }, { value: "serif", label: "Serif" }, { value: "mono", label: "Monospace" }] as const;
const RATIO_LABEL: Record<(typeof IMAGE_RATIOS)[number], string> = { auto: "Original", "3:2": "3:2 Standard", "1:1": "1:1 Square", "2:3": "2:3 Standard (Vertical)", "4:3": "4:3 Four-Three", "3:4": "3:4 Three-Four (Vertical)", "16:9": "16:9 Widescreen" };
const SOURCE_LABEL: Record<FontSpec["source"], string> = { system: "System", google: "Google Fonts", adobe: "Adobe", custom: "Custom" };
const WEIGHT_OPTIONS = [100, 200, 300, 400, 500, 600, 700, 800, 900].map((n) => ({ value: String(n), label: String(n) }));

function FontEditor({ id, title, value, onChange, err }: { id: string; title: string; value: FontSpec; onChange: (v: FontSpec) => void; err: (k: string) => string | undefined }) {
  const set = (p: Partial<FontSpec>) => onChange({ ...value, ...p });
  return (
    <fieldset className="space-y-3 rounded-md border border-border p-4">
      <legend className="px-1 text-sm font-medium">{title}</legend>
      <div role="radiogroup" aria-label={`${title}: font directory`} className="flex flex-wrap gap-4">
        {FONT_SOURCES.map((src) => (
          <label key={src} className="flex items-center gap-2 text-sm"><input type="radio" name={`${id}-src`} checked={value.source === src} onChange={() => set({ source: src })} />{SOURCE_LABEL[src]}</label>
        ))}
      </div>
      <div className="grid gap-4 sm:grid-cols-2">
        {value.source !== "system" ? <Field id={`${id}-name`} label="Name" help="The family name, for example Montserrat." error={err("name")}><input id={`${id}-name`} className={inputClass} maxLength={80} value={value.name} onChange={(e) => set({ name: e.target.value })} aria-describedby={`${id}-name-help`} /></Field> : null}
        <Field id={`${id}-generic`} label={value.source === "system" ? "System font" : "Fallback while loading"}><Select id={`${id}-generic`} value={value.generic} onChange={(v) => set({ generic: v })} options={FONTS} /></Field>
        {value.source !== "system" ? (
          <>
            <Field id={`${id}-reg`} label="Weight: regular"><Select id={`${id}-reg`} value={String(value.regular)} onChange={(v) => set({ regular: Number(v) })} options={WEIGHT_OPTIONS} /></Field>
            <Field id={`${id}-bold`} label="Weight: bold"><Select id={`${id}-bold`} value={String(value.bold)} onChange={(v) => set({ bold: Number(v) })} options={WEIGHT_OPTIONS} /></Field>
          </>
        ) : null}
        {value.source === "adobe" ? <Field id={`${id}-kit`} label="Adobe Fonts project id" help="The code in your Adobe Fonts web project." error={err("adobeKit")}><input id={`${id}-kit`} className={inputClass} maxLength={12} value={value.adobeKit} onChange={(e) => set({ adobeKit: e.target.value })} aria-describedby={`${id}-kit-help`} /></Field> : null}
        {value.source === "custom" ? <Field id={`${id}-url`} label="Font stylesheet URL" help="An https:// stylesheet that defines the font (@font-face)." error={err("customUrl")} className="sm:col-span-2"><input id={`${id}-url`} className={inputClass} maxLength={2048} value={value.customUrl} onChange={(e) => set({ customUrl: e.target.value })} aria-describedby={`${id}-url-help`} /></Field> : null}
      </div>
      {value.source !== "system" && value.name === "" ? <p className="text-xs text-muted-foreground">Enter the font name, otherwise the fallback font is used.</p> : null}
    </fieldset>
  );
}
const NAMES: Record<string, string> = { one: "One", two: "Two", three: "Three", four: "Four", five: "Five", six: "Six", seven: "Seven", eight: "Eight", muted: "Muted" };

const BLOCK_LABEL: Record<LayoutBlock, string> = { header: "Header panels", hero: "Hero panels", title: "Page title", above: "Panels above content", content: "Page content", below: "Panels below content", footer: "Footer panels" };
const LAYOUT_NAMES: Array<[keyof LayoutOrder, string]> = [["default", "Default"], ["homepage", "Homepage"], ["narrow", "Narrow"]];

const num = (v: string, min: number, max: number) => Math.min(max, Math.max(min, Math.floor(Number(v)) || 0));

/** ShowOff "Design and Appearance": General, Colours, Typography, Elements. */
export function DesignForm({ siteId, design, textColour, primaryColour, backgroundColour }: { siteId: string; design: SiteDesign; textColour: string; primaryColour: string; backgroundColour: string }) {
  const { pending, msg, errors, save } = useSection(siteId);
  const [d, setD] = useState(design);
  const [text, setText] = useState(textColour);
  const [primary, setPrimary] = useState(primaryColour);
  const [background, setBackground] = useState(backgroundColour);
  const [tab, setTab] = useState<Tab>("general");
  const patch = (p: Partial<SiteDesign>) => setD((x) => ({ ...x, ...p }));
  const patchImg = (p: Partial<SiteDesign["elements"]["image"]>) => patch({ elements: { ...d.elements, image: { ...d.elements.image, ...p } } });
  const patchBtn = (p: Partial<SiteDesign["elements"]["button"]>) => patch({ elements: { ...d.elements, button: { ...d.elements.button, ...p } } });
  const err = (k: string) => errors[`design.${k}`] ?? errors[k];

  return (
    <div className="space-y-4">
      <SubTabs label="Design and appearance" tabs={TABS} value={tab} onChange={setTab} />
      <Panel label="Design and appearance" tab={tab}>
        {tab === "general" ? (
          <>
            <Card className="space-y-3 p-4">
              <h2 className="text-sm font-semibold">Text direction</h2>
              <fieldset className="space-y-1">
                <legend className="sr-only">Text direction</legend>
                <label className="flex items-center gap-2 text-sm"><input type="radio" name="dir" checked={d.direction === "ltr"} onChange={() => patch({ direction: "ltr" })} />Left to Right</label>
                <label className="flex items-center gap-2 text-sm"><input type="radio" name="dir" checked={d.direction === "rtl"} onChange={() => patch({ direction: "rtl" })} />Right to Left</label>
              </fieldset>
            </Card>
            <Card className="space-y-4 p-4">
              <h2 className="text-sm font-semibold">Scroll bar</h2>
              <Check id="sb-on" label="Use custom scroll bar" checked={d.scrollbar.enabled} onChange={(v) => patch({ scrollbar: { ...d.scrollbar, enabled: v } })} />
              {d.scrollbar.enabled ? (
                <div className="grid gap-4 sm:grid-cols-3">
                  <Field id="sb-w" label="Width (px)"><input id="sb-w" type="number" min={2} max={24} className={inputClass} value={d.scrollbar.width} onChange={(e) => patch({ scrollbar: { ...d.scrollbar, width: num(e.target.value, 2, 24) } })} /></Field>
                  <Colour id="sb-track" label="Track colour" value={d.scrollbar.track} onChange={(v) => patch({ scrollbar: { ...d.scrollbar, track: v } })} error={err("scrollbar.track")} />
                  <Colour id="sb-thumb" label="Thumb colour" value={d.scrollbar.thumb} onChange={(v) => patch({ scrollbar: { ...d.scrollbar, thumb: v } })} error={err("scrollbar.thumb")} />
                </div>
              ) : null}
            </Card>
            <Card className="space-y-4 p-4">
              <h2 className="text-sm font-semibold">Scroll to top</h2>
              <Check id="st-on" label="Use scroll to top" checked={d.scrollTop.enabled} onChange={(v) => patch({ scrollTop: { ...d.scrollTop, enabled: v } })} />
              {d.scrollTop.enabled ? (
                <div className="grid gap-4 sm:grid-cols-2">
                  <Colour id="st-bg" label="Background colour" value={d.scrollTop.background} onChange={(v) => patch({ scrollTop: { ...d.scrollTop, background: v } })} error={err("scrollTop.background")} />
                  <Colour id="st-icon" label="Icon colour" value={d.scrollTop.icon} onChange={(v) => patch({ scrollTop: { ...d.scrollTop, icon: v } })} error={err("scrollTop.icon")} />
                  <Field id="st-r" label="Border radius (px)"><input id="st-r" type="number" min={0} max={50} className={inputClass} value={d.scrollTop.radius} onChange={(e) => patch({ scrollTop: { ...d.scrollTop, radius: num(e.target.value, 0, 50) } })} /></Field>
                  <Field id="st-pos" label="Position"><Select id="st-pos" value={d.scrollTop.position} onChange={(v) => patch({ scrollTop: { ...d.scrollTop, position: v } })} options={[{ value: "right", label: "Right" }, { value: "left", label: "Left" }]} /></Field>
                </div>
              ) : null}
            </Card>
            <Card className="space-y-4 p-4">
              <h2 className="text-sm font-semibold">Page title</h2>
              <div className="grid gap-4 sm:grid-cols-2">
                <Field id="pt-pad" label="Padding top (px)" help="Space above the title, useful when the header sits over the page."><input id="pt-pad" type="number" min={0} max={200} className={inputClass} value={d.pageTitle.paddingTop} onChange={(e) => patch({ pageTitle: { ...d.pageTitle, paddingTop: num(e.target.value, 0, 200) } })} aria-describedby="pt-pad-help" /></Field>
                <Field id="pt-font" label="Font family"><Select id="pt-font" value={d.pageTitle.font} onChange={(v) => patch({ pageTitle: { ...d.pageTitle, font: v } })} options={[{ value: "one", label: "One (body)" }, { value: "two", label: "Two (headings)" }]} /></Field>
                <Field id="pt-align" label="Alignment"><Select id="pt-align" value={d.pageTitle.align} onChange={(v) => patch({ pageTitle: { ...d.pageTitle, align: v } })} options={[{ value: "left", label: "Left" }, { value: "center", label: "Center" }, { value: "right", label: "Right" }]} /></Field>
                <Field id="pt-size" label="Size"><Select id="pt-size" value={d.pageTitle.size} onChange={(v) => patch({ pageTitle: { ...d.pageTitle, size: v } })} options={[{ value: "md", label: "Normal" }, { value: "lg", label: "Large" }, { value: "xl", label: "X-Large" }, { value: "2xl", label: "XX-Large" }, { value: "3xl", label: "XXX-Large" }]} /></Field>
                <Colour id="pt-colour" label="Colour" value={d.pageTitle.color} onChange={(v) => patch({ pageTitle: { ...d.pageTitle, color: v } })} error={err("pageTitle.color")} />
                <div className="space-y-2 self-end">
                  <Check id="pt-bold" label="Bold" checked={d.pageTitle.bold} onChange={(v) => patch({ pageTitle: { ...d.pageTitle, bold: v } })} />
                  <Check id="pt-up" label="Uppercase" checked={d.pageTitle.uppercase} onChange={(v) => patch({ pageTitle: { ...d.pageTitle, uppercase: v } })} />
                </div>
              </div>
            </Card>
          </>
        ) : null}

        {tab === "layout" ? (
          <Card className="space-y-6 p-4">
            <div>
              <h2 className="text-sm font-semibold">Order</h2>
              <p className="text-xs text-muted-foreground">Choose the order in which the parts of a page appear for each page layout. The website header, navigation and footer are not affected.</p>
            </div>
            {LAYOUT_NAMES.map(([key, name]) => {
              const order = d.layoutOrder[key];
              const move = (i: number, by: -1 | 1) => {
                const next = [...order]; const j = i + by;
                if (j < 0 || j >= next.length) return;
                [next[i], next[j]] = [next[j]!, next[i]!];
                patch({ layoutOrder: { ...d.layoutOrder, [key]: next } });
              };
              return (
                <section key={key} aria-labelledby={`lo-${key}`} className="space-y-2">
                  <div className="flex items-center justify-between">
                    <h3 id={`lo-${key}`} className="text-sm font-medium">{name}</h3>
                    <button type="button" className="text-xs text-primary underline" onClick={() => patch({ layoutOrder: { ...d.layoutOrder, [key]: [...LAYOUT_BLOCKS] } })}>Reset order</button>
                  </div>
                  <ol className="space-y-1">
                    {order.map((b, i) => (
                      <li key={b} className="flex items-center justify-between rounded-md border border-border bg-card px-3 py-2 text-sm">
                        <span>{BLOCK_LABEL[b]}</span>
                        <span className="flex gap-1">
                          <button type="button" className="rounded border border-border px-2 py-0.5 text-xs disabled:opacity-40" disabled={i === 0} onClick={() => move(i, -1)} aria-label={`Move ${BLOCK_LABEL[b]} up in ${name}`}>Up</button>
                          <button type="button" className="rounded border border-border px-2 py-0.5 text-xs disabled:opacity-40" disabled={i === order.length - 1} onClick={() => move(i, 1)} aria-label={`Move ${BLOCK_LABEL[b]} down in ${name}`}>Down</button>
                        </span>
                      </li>
                    ))}
                  </ol>
                </section>
              );
            })}
          </Card>
        ) : null}
        {tab === "colours" ? (
          <>
            <Card className="space-y-4 p-4">
              <h2 className="text-sm font-semibold">Palette</h2>
              <div className="grid gap-4 sm:grid-cols-3">
                {PALETTE_KEYS.map((k) => <Colour key={k} id={`pal-${k}`} label={NAMES[k] ?? k} value={d.palette[k]} onChange={(v) => patch({ palette: { ...d.palette, [k]: v } })} error={err(`palette.${k}`)} />)}
              </div>
            </Card>
            <Card className="space-y-4 p-4">
              <h2 className="text-sm font-semibold">Elements</h2>
              <div className="grid gap-4 sm:grid-cols-3">
                <Colour id="c-primary" label="Primary" value={primary} onChange={setPrimary} error={errors["primary"]} />
                <Colour id="c-bg" label="Background" value={background} onChange={setBackground} error={errors["background"]} />
                <Colour id="c-text" label="Text" value={text} onChange={setText} error={errors["text"]} />
                <Colour id="c-muted" label="Text muted" value={d.textMuted} onChange={(v) => patch({ textMuted: v })} error={err("textMuted")} />
                <Colour id="c-link" label="Links" value={d.link} onChange={(v) => patch({ link: v })} error={err("link")} />
              </div>
              <p className="text-xs text-muted-foreground">Keep strong contrast between text and background for readability.</p>
            </Card>
          </>
        ) : null}

        {tab === "typography" ? (
          <Card className="space-y-6 p-4">
            <h2 className="text-sm font-semibold">Font families</h2>
            <FontEditor id="f-one" title="Font family one (primary · body text)" value={d.fontOne} onChange={(v) => patch({ fontOne: v })} err={(k) => err(`fontOne.${k}`)} />
            <FontEditor id="f-two" title="Font family two (secondary · headings)" value={d.fontTwo} onChange={(v) => patch({ fontTwo: v })} err={(k) => err(`fontTwo.${k}`)} />
          </Card>
        ) : null}

        {tab === "elements" ? (
          <>
            <Card className="space-y-4 p-4">
              <h2 className="text-sm font-semibold">Image</h2>
              <p className="text-xs text-muted-foreground">Applies to images placed in page text.</p>
              <div className="grid gap-4 sm:grid-cols-2">
                <Field id="el-ratio" label="Aspect ratio"><Select id="el-ratio" value={d.elements.image.ratio} onChange={(v) => patchImg({ ratio: v })} options={IMAGE_RATIOS.map((r) => ({ value: r, label: RATIO_LABEL[r] }))} /></Field>
                <Field id="el-ir" label="Corner radius (px)"><input id="el-ir" type="number" min={0} max={50} className={inputClass} value={d.elements.image.radius} onChange={(e) => patchImg({ radius: num(e.target.value, 0, 50) })} /></Field>
                <Field id="el-ibw" label="Border width (px)"><input id="el-ibw" type="number" min={0} max={20} className={inputClass} value={d.elements.image.borderWidth} onChange={(e) => patchImg({ borderWidth: num(e.target.value, 0, 20) })} /></Field>
                <Colour id="el-ibc" label="Border colour (blank = text colour)" value={d.elements.image.borderColour} onChange={(v) => patchImg({ borderColour: v })} error={err("elements.image.borderColour")} />
              </div>
            </Card>
            <Card className="space-y-4 p-4">
              <h2 className="text-sm font-semibold">Buttons</h2>
              <p className="text-xs text-muted-foreground">Leave a colour blank to use the website&apos;s primary colour.</p>
              <div className="grid gap-4 sm:grid-cols-3">
                <Field id="el-bf" label="Font family"><Select id="el-bf" value={d.elements.button.font} onChange={(v) => patchBtn({ font: v })} options={[{ value: "one", label: "One (body)" }, { value: "two", label: "Two (headings)" }]} /></Field>
                <Field id="el-bs" label="Size"><Select id="el-bs" value={d.elements.button.size} onChange={(v) => patchBtn({ size: v })} options={BUTTON_SIZES.map((x) => ({ value: x, label: x.replace("x-", "X-").replace(/^./, (c) => c.toUpperCase()) }))} /></Field>
                <Field id="el-br" label="Corner radius (px)"><input id="el-br" type="number" min={0} max={50} className={inputClass} value={d.elements.button.radius} onChange={(e) => patchBtn({ radius: num(e.target.value, 0, 50) })} /></Field>
                <Colour id="el-btc" label="Text colour" value={d.elements.button.textColour} onChange={(v) => patchBtn({ textColour: v })} error={err("elements.button.textColour")} />
                <Colour id="el-bbg" label="Background" value={d.elements.button.background} onChange={(v) => patchBtn({ background: v })} error={err("elements.button.background")} />
                <Colour id="el-bbc" label="Border colour" value={d.elements.button.borderColour} onChange={(v) => patchBtn({ borderColour: v })} error={err("elements.button.borderColour")} />
                <Field id="el-bbw" label="Border width (px)"><input id="el-bbw" type="number" min={0} max={10} className={inputClass} value={d.elements.button.borderWidth} onChange={(e) => patchBtn({ borderWidth: num(e.target.value, 0, 10) })} /></Field>
                <Colour id="el-bhb" label="Hover background" value={d.elements.button.hoverBackground} onChange={(v) => patchBtn({ hoverBackground: v })} error={err("elements.button.hoverBackground")} />
                <Colour id="el-bht" label="Hover text colour" value={d.elements.button.hoverText} onChange={(v) => patchBtn({ hoverText: v })} error={err("elements.button.hoverText")} />
                <div className="space-y-2 self-end">
                  <Check id="el-bb" label="Bold" checked={d.elements.button.bold} onChange={(v) => patchBtn({ bold: v })} />
                  <Check id="el-bu" label="Uppercase" checked={d.elements.button.uppercase} onChange={(v) => patchBtn({ uppercase: v })} />
                </div>
              </div>
            </Card>
          </>
        ) : null}
      </Panel>
      <SaveBar pending={pending} msg={msg} onSave={() => save("design", { ...d, text, primary, background })} label="Save design" />
    </div>
  );
}
