"use client";

import { useActionState, useState } from "react";
import {
  saveAboutValuesAction,
  saveFaqsAction,
  savePricingTiersAction,
  saveProcessStepsAction,
} from "@/app/admin/actions";
import type { ActionState } from "@/lib/form";
import type {
  CmsAboutValue,
  CmsFaq,
  CmsPricingTier,
  CmsProcessStep,
} from "@/lib/cms";

/* ------------------------------ primitives ------------------------------ */

function Alert({ state }: { state: ActionState }) {
  if (!state?.error) return null;
  return (
    <p
      role="alert"
      className="rounded-xl border border-coral/40 bg-coral-soft px-4 py-3 text-sm font-medium text-coral-dark"
    >
      {state.error}
    </p>
  );
}

function SaveButton({ pending, children }: { pending: boolean; children: string }) {
  return (
    <button
      type="submit"
      disabled={pending}
      className="btn btn-teal disabled:cursor-not-allowed disabled:opacity-60"
    >
      {pending ? "Saving…" : children}
    </button>
  );
}

function Arrow({ up }: { up: boolean }) {
  return (
    <svg
      viewBox="0 0 24 24"
      fill="none"
      stroke="currentColor"
      strokeWidth="2.5"
      strokeLinecap="round"
      strokeLinejoin="round"
      aria-hidden="true"
      className={`h-3.5 w-3.5 ${up ? "" : "rotate-180"}`}
    >
      <path d="M12 19V5" />
      <path d="m5 12 7-7 7 7" />
    </svg>
  );
}

function SwapButtons({
  onMove,
  position,
  count,
}: {
  onMove: (delta: -1 | 1) => void;
  position: number;
  count: number;
}) {
  return (
    <div className="flex flex-col gap-1.5">
      <button
        type="button"
        onClick={() => onMove(-1)}
        disabled={position <= 0}
        aria-label="Move up"
        title="Move up"
        className="flex h-8 w-8 items-center justify-center rounded-full border border-linen bg-white text-ink-soft transition-colors hover:border-teal hover:text-teal disabled:cursor-not-allowed disabled:opacity-35"
      >
        <Arrow up />
      </button>
      <button
        type="button"
        onClick={() => onMove(1)}
        disabled={position >= count - 1}
        aria-label="Move down"
        title="Move down"
        className="flex h-8 w-8 items-center justify-center rounded-full border border-linen bg-white text-ink-soft transition-colors hover:border-teal hover:text-teal disabled:cursor-not-allowed disabled:opacity-35"
      >
        <Arrow up={false} />
      </button>
    </div>
  );
}

const inputCls = "field-input";
const textareaCls = "field-textarea resize-y";

let keySeq = 0;
const nextKey = () => `row-${++keySeq}`;

/**
 * Row shell with a live title (updates as you type) and reorder/remove
 * controls. Rows get stable React keys so removing one never scrambles
 * the other rows' field values.
 */
function Row({
  index,
  count,
  title,
  liveTitle,
  onMove,
  onRemove,
  children,
}: {
  index: number;
  count: number;
  /** Prefix shown before the live title, e.g. "Step" */
  title: string;
  liveTitle: string;
  onMove: (delta: -1 | 1) => void;
  onRemove: () => void;
  children: React.ReactNode;
}) {
  return (
    <div className="rounded-2xl bg-mint p-5">
      <div className="mb-3 flex items-center gap-3">
        <SwapButtons onMove={onMove} position={index} count={count} />
        <p className="min-w-0 flex-1 truncate text-sm font-semibold text-ink">
          <span className="mr-2 text-[0.72rem] font-bold uppercase tracking-[0.16em] text-ink-mute">
            {title} {index + 1}
          </span>
          {liveTitle || <span className="font-normal text-ink-mute">Untitled</span>}
        </p>
        <button
          type="button"
          onClick={onRemove}
          className="shrink-0 rounded-full px-3 py-1.5 text-xs font-semibold text-coral-dark transition-colors hover:bg-coral-soft"
        >
          Remove
        </button>
      </div>
      <div className="space-y-3">{children}</div>
    </div>
  );
}

/* --------------------------- Process steps ------------------------------ */

type StepRow = CmsProcessStep & { _key: string };

function ProcessStepsForm({ steps }: { steps: CmsProcessStep[] }) {
  const [state, action, pending] = useActionState<ActionState, FormData>(
    saveProcessStepsAction,
    null,
  );
  const [rows, setRows] = useState<StepRow[]>(
    steps.map((s) => ({ ...s, _key: nextKey() })),
  );

  const patch = (i: number, changes: Partial<StepRow>) =>
    setRows(rows.map((r, j) => (j === i ? { ...r, ...changes } : r)));

  return (
    <form action={action} className="space-y-4">
      <Alert state={state} />
      {rows.map((row, i) => (
        <Row
          key={row._key}
          index={i}
          count={rows.length}
          title="Step"
          liveTitle={row.title}
          onMove={(delta) => {
            const j = i + delta;
            const next = [...rows];
            [next[i], next[j]] = [next[j], next[i]];
            setRows(next);
          }}
          onRemove={() => setRows(rows.filter((_, j) => j !== i))}
        >
          <div className="grid grid-cols-[5rem_1fr] gap-3">
            <div>
              <label htmlFor={`step.${i}.number`} className="field-label">
                Number
              </label>
              <input
                id={`step.${i}.number`}
                name={`step.${i}.number`}
                defaultValue={row.number}
                className={inputCls}
              />
            </div>
            <div>
              <label htmlFor={`step.${i}.title`} className="field-label">
                Title
              </label>
              <input
                id={`step.${i}.title`}
                name={`step.${i}.title`}
                value={row.title}
                onChange={(e) => patch(i, { title: e.target.value })}
                className={inputCls}
              />
            </div>
          </div>
          <div>
            <label htmlFor={`step.${i}.text`} className="field-label">
              Text
            </label>
            <textarea
              id={`step.${i}.text`}
              name={`step.${i}.text`}
              rows={2}
              defaultValue={row.text}
              className={textareaCls}
            />
          </div>
        </Row>
      ))}
      <div className="flex flex-wrap items-center gap-4">
        <SaveButton pending={pending}>Save process steps</SaveButton>
        <button
          type="button"
          onClick={() =>
            setRows([
              ...rows,
              {
                _key: nextKey(),
                id: "",
                number: String(rows.length + 1).padStart(2, "0"),
                title: "",
                text: "",
              },
            ])
          }
          className="btn btn-outline"
        >
          Add step
        </button>
        <span className="text-xs text-ink-mute">{rows.length} steps</span>
      </div>
    </form>
  );
}

/* -------------------------------- FAQs ---------------------------------- */

type FaqRow = CmsFaq & { _key: string };

function FaqsForm({ faqs }: { faqs: CmsFaq[] }) {
  const [state, action, pending] = useActionState<ActionState, FormData>(
    saveFaqsAction,
    null,
  );
  const [rows, setRows] = useState<FaqRow[]>(
    faqs.map((f) => ({ ...f, _key: nextKey() })),
  );

  const patch = (i: number, changes: Partial<FaqRow>) =>
    setRows(rows.map((r, j) => (j === i ? { ...r, ...changes } : r)));

  return (
    <form action={action} className="space-y-4">
      <Alert state={state} />
      {rows.map((row, i) => (
        <Row
          key={row._key}
          index={i}
          count={rows.length}
          title="FAQ"
          liveTitle={row.q}
          onMove={(delta) => {
            const j = i + delta;
            const next = [...rows];
            [next[i], next[j]] = [next[j], next[i]];
            setRows(next);
          }}
          onRemove={() => setRows(rows.filter((_, j) => j !== i))}
        >
          <div>
            <label htmlFor={`faq.${i}.q`} className="field-label">
              Question
            </label>
            <input
              id={`faq.${i}.q`}
              name={`faq.${i}.q`}
              value={row.q}
              onChange={(e) => patch(i, { q: e.target.value })}
              className={inputCls}
            />
          </div>
          <div>
            <label htmlFor={`faq.${i}.a`} className="field-label">
              Answer
            </label>
            <textarea
              id={`faq.${i}.a`}
              name={`faq.${i}.a`}
              rows={3}
              defaultValue={row.a}
              className={textareaCls}
            />
          </div>
        </Row>
      ))}
      <div className="flex flex-wrap items-center gap-4">
        <SaveButton pending={pending}>Save FAQs</SaveButton>
        <button
          type="button"
          onClick={() => setRows([...rows, { _key: nextKey(), id: "", q: "", a: "" }])}
          className="btn btn-outline"
        >
          Add FAQ
        </button>
        <span className="text-xs text-ink-mute">{rows.length} FAQs</span>
      </div>
    </form>
  );
}

/* ---------------------------- Pricing tiers ------------------------------ */

type TierRow = Omit<CmsPricingTier, "features"> & {
  features: string;
  _key: string;
};

function PricingTiersForm({ tiers }: { tiers: CmsPricingTier[] }) {
  const [state, action, pending] = useActionState<ActionState, FormData>(
    savePricingTiersAction,
    null,
  );
  const [rows, setRows] = useState<TierRow[]>(
    tiers.map((t) => ({
      ...t,
      features: t.features.join("\n"),
      _key: nextKey(),
    })),
  );

  const patch = (i: number, changes: Partial<TierRow>) =>
    setRows(rows.map((r, j) => (j === i ? { ...r, ...changes } : r)));

  return (
    <form action={action} className="space-y-4">
      <Alert state={state} />
      {rows.map((row, i) => (
        <Row
          key={row._key}
          index={i}
          count={rows.length}
          title="Tier"
          liveTitle={row.name}
          onMove={(delta) => {
            const j = i + delta;
            const next = [...rows];
            [next[i], next[j]] = [next[j], next[i]];
            setRows(next);
          }}
          onRemove={() => setRows(rows.filter((_, j) => j !== i))}
        >
          <div className="grid gap-3 sm:grid-cols-2">
            <div>
              <label htmlFor={`tier.${i}.name`} className="field-label">
                Name
              </label>
              <input
                id={`tier.${i}.name`}
                name={`tier.${i}.name`}
                value={row.name}
                onChange={(e) => patch(i, { name: e.target.value })}
                className={inputCls}
              />
            </div>
            <div>
              <label htmlFor={`tier.${i}.tagline`} className="field-label">
                Tagline
              </label>
              <input
                id={`tier.${i}.tagline`}
                name={`tier.${i}.tagline`}
                defaultValue={row.tagline}
                className={inputCls}
              />
            </div>
            <div>
              <label htmlFor={`tier.${i}.price`} className="field-label">
                Price
              </label>
              <input
                id={`tier.${i}.price`}
                name={`tier.${i}.price`}
                defaultValue={row.price}
                placeholder="from $3,800"
                className={inputCls}
              />
            </div>
            <div>
              <label htmlFor={`tier.${i}.unit`} className="field-label">
                Unit
              </label>
              <input
                id={`tier.${i}.unit`}
                name={`tier.${i}.unit`}
                defaultValue={row.unit}
                placeholder="per room"
                className={inputCls}
              />
            </div>
          </div>
          <div>
            <label htmlFor={`tier.${i}.features`} className="field-label">
              Features (one per line)
            </label>
            <textarea
              id={`tier.${i}.features`}
              name={`tier.${i}.features`}
              rows={4}
              defaultValue={row.features}
              className={`${textareaCls} font-mono text-[0.9rem]`}
            />
          </div>
          <label className="flex items-center gap-3 text-sm text-ink-soft">
            <input
              type="checkbox"
              name={`tier.${i}.featured`}
              defaultChecked={row.featured}
              className="h-4 w-4 accent-[#0f7b7b]"
            />
            Highlight as “Most popular”
          </label>
        </Row>
      ))}
      <div className="flex flex-wrap items-center gap-4">
        <SaveButton pending={pending}>Save pricing tiers</SaveButton>
        <button
          type="button"
          onClick={() =>
            setRows([
              ...rows,
              {
                _key: nextKey(),
                id: "",
                name: "",
                price: "",
                unit: "",
                tagline: "",
                features: "",
                featured: false,
              },
            ])
          }
          className="btn btn-outline"
        >
          Add tier
        </button>
        <span className="text-xs text-ink-mute">{rows.length} tiers</span>
      </div>
    </form>
  );
}

/* ----------------------------- About values ------------------------------ */

type ValueRow = CmsAboutValue & { _key: string };

function AboutValuesForm({ values }: { values: CmsAboutValue[] }) {
  const [state, action, pending] = useActionState<ActionState, FormData>(
    saveAboutValuesAction,
    null,
  );
  const [rows, setRows] = useState<ValueRow[]>(
    values.map((v) => ({ ...v, _key: nextKey() })),
  );

  const patch = (i: number, changes: Partial<ValueRow>) =>
    setRows(rows.map((r, j) => (j === i ? { ...r, ...changes } : r)));

  return (
    <form action={action} className="space-y-4">
      <Alert state={state} />
      {rows.map((row, i) => (
        <Row
          key={row._key}
          index={i}
          count={rows.length}
          title="Value"
          liveTitle={row.title}
          onMove={(delta) => {
            const j = i + delta;
            const next = [...rows];
            [next[i], next[j]] = [next[j], next[i]];
            setRows(next);
          }}
          onRemove={() => setRows(rows.filter((_, j) => j !== i))}
        >
          <div>
            <label htmlFor={`value.${i}.title`} className="field-label">
              Title
            </label>
            <input
              id={`value.${i}.title`}
              name={`value.${i}.title`}
              value={row.title}
              onChange={(e) => patch(i, { title: e.target.value })}
              className={inputCls}
            />
          </div>
          <div>
            <label htmlFor={`value.${i}.text`} className="field-label">
              Text
            </label>
            <textarea
              id={`value.${i}.text`}
              name={`value.${i}.text`}
              rows={3}
              defaultValue={row.text}
              className={textareaCls}
            />
          </div>
        </Row>
      ))}
      <div className="flex flex-wrap items-center gap-4">
        <SaveButton pending={pending}>Save about values</SaveButton>
        <button
          type="button"
          onClick={() => setRows([...rows, { _key: nextKey(), id: "", title: "", text: "" }])}
          className="btn btn-outline"
        >
          Add value
        </button>
        <span className="text-xs text-ink-mute">{rows.length} values</span>
      </div>
    </form>
  );
}

/* --------------------------------- Page ---------------------------------- */

export function BlocksForm({
  processSteps,
  faqs,
  pricingTiers,
  aboutValues,
}: {
  processSteps: CmsProcessStep[];
  faqs: CmsFaq[];
  pricingTiers: CmsPricingTier[];
  aboutValues: CmsAboutValue[];
}) {
  return (
    <div className="space-y-6">
      <section className="card-soft space-y-5 p-7">
        <div>
          <h2 className="display-3">Process steps</h2>
          <p className="mt-1 text-sm text-ink-mute">
            The “How it works” timeline on the home and services pages ·{" "}
            {processSteps.length} steps
          </p>
        </div>
        <ProcessStepsForm steps={processSteps} />
      </section>

      <section className="card-soft space-y-5 p-7">
        <div>
          <h2 className="display-3">Pricing tiers</h2>
          <p className="mt-1 text-sm text-ink-mute">
            The pricing cards on the pricing page · {pricingTiers.length} tiers
          </p>
        </div>
        <PricingTiersForm tiers={pricingTiers} />
      </section>

      <section className="card-soft space-y-5 p-7">
        <div>
          <h2 className="display-3">About values</h2>
          <p className="mt-1 text-sm text-ink-mute">
            The “What we believe” cards on the about page · {aboutValues.length} values
          </p>
        </div>
        <AboutValuesForm values={aboutValues} />
      </section>

      <section className="card-soft space-y-5 p-7">
        <div>
          <h2 className="display-3">FAQs</h2>
          <p className="mt-1 text-sm text-ink-mute">
            The accordion on the pricing page · {faqs.length} FAQs
          </p>
        </div>
        <FaqsForm faqs={faqs} />
      </section>
    </div>
  );
}
