"use client"

import { type PageBlock, type PageBlocks, parsePageBlocks, serializePageBlocks } from "@cms/content"
import { useMemo, useState } from "react"

type PageBlockEditorProps = {
  name: string
  initialContent: string
  label?: string
}

function randomId(prefix: string): string {
  return `${prefix}-${Math.random().toString(36).slice(2, 10)}`
}

function normalizeInitialBlocks(initialContent: string): PageBlocks {
  if (!initialContent.trim()) {
    return [
      {
        id: randomId("rich"),
        type: "rich_text",
        body: "",
      },
    ]
  }

  try {
    return parsePageBlocks(initialContent)
  } catch {
    return [
      {
        id: randomId("rich"),
        type: "rich_text",
        body: initialContent,
      },
    ]
  }
}

function updateBlock(blocks: PageBlocks, blockId: string, next: Partial<PageBlock>): PageBlocks {
  return blocks.map((block) =>
    block.id === blockId ? ({ ...block, ...next } as PageBlock) : block,
  )
}

function moveBlock(blocks: PageBlocks, blockId: string, direction: "up" | "down"): PageBlocks {
  const index = blocks.findIndex((entry) => entry.id === blockId)

  if (index < 0) {
    return blocks
  }

  const nextIndex = direction === "up" ? index - 1 : index + 1
  if (nextIndex < 0 || nextIndex >= blocks.length) {
    return blocks
  }

  const next = [...blocks]
  const current = next[index]
  next[index] = next[nextIndex]
  next[nextIndex] = current
  return next
}

export function PageBlockEditor({
  name,
  initialContent,
  label = "Page Blocks",
}: PageBlockEditorProps) {
  const [blocks, setBlocks] = useState<PageBlocks>(() => normalizeInitialBlocks(initialContent))

  const serialized = useMemo(() => serializePageBlocks(blocks), [blocks])

  function addBlock(type: PageBlock["type"]) {
    if (type === "hero") {
      setBlocks((prev) => [
        ...prev,
        {
          id: randomId("hero"),
          type,
          heading: "Hero heading",
          subheading: null,
          ctaHref: null,
          ctaLabel: null,
        },
      ])
      return
    }

    if (type === "rich_text") {
      setBlocks((prev) => [...prev, { id: randomId("rich"), type, body: "" }])
      return
    }

    if (type === "gallery") {
      setBlocks((prev) => [...prev, { id: randomId("gallery"), type, title: null, imageIds: [] }])
      return
    }

    if (type === "cta") {
      setBlocks((prev) => [
        ...prev,
        { id: randomId("cta"), type, label: "Open", href: "/", variant: "primary" },
      ])
      return
    }

    if (type === "form") {
      setBlocks((prev) => [
        ...prev,
        { id: randomId("form"), type, formKey: "contact", title: null, description: null },
      ])
      return
    }

    setBlocks((prev) => [
      ...prev,
      { id: randomId("price"), type: "price_cards", title: null, cards: [] },
    ])
  }

  return (
    <div className="space-y-3 rounded border border-neutral-200 p-3">
      <input type="hidden" name={name} value={serialized} />
      <div className="flex flex-wrap items-center gap-2">
        <span className="text-xs text-neutral-600">{label}</span>
        <button
          type="button"
          className="rounded border px-2 py-1 text-xs"
          onClick={() => addBlock("hero")}
        >
          + Hero
        </button>
        <button
          type="button"
          className="rounded border px-2 py-1 text-xs"
          onClick={() => addBlock("rich_text")}
        >
          + Rich text
        </button>
        <button
          type="button"
          className="rounded border px-2 py-1 text-xs"
          onClick={() => addBlock("gallery")}
        >
          + Gallery
        </button>
        <button
          type="button"
          className="rounded border px-2 py-1 text-xs"
          onClick={() => addBlock("cta")}
        >
          + CTA
        </button>
        <button
          type="button"
          className="rounded border px-2 py-1 text-xs"
          onClick={() => addBlock("form")}
        >
          + Form
        </button>
        <button
          type="button"
          className="rounded border px-2 py-1 text-xs"
          onClick={() => addBlock("price_cards")}
        >
          + Price cards
        </button>
      </div>

      <div className="space-y-3">
        {blocks.map((block, index) => (
          <article key={block.id} className="space-y-2 rounded border border-neutral-200 p-3">
            <div className="flex items-center justify-between text-xs text-neutral-600">
              <span>
                #{index + 1} {block.type}
              </span>
              <div className="flex items-center gap-2">
                <button
                  type="button"
                  className="rounded border px-2 py-1"
                  onClick={() => setBlocks((prev) => moveBlock(prev, block.id, "up"))}
                >
                  Up
                </button>
                <button
                  type="button"
                  className="rounded border px-2 py-1"
                  onClick={() => setBlocks((prev) => moveBlock(prev, block.id, "down"))}
                >
                  Down
                </button>
                <button
                  type="button"
                  className="rounded border px-2 py-1"
                  onClick={() => setBlocks((prev) => prev.filter((entry) => entry.id !== block.id))}
                >
                  Remove
                </button>
              </div>
            </div>

            {block.type === "hero" ? (
              <div className="grid gap-2 md:grid-cols-2">
                <input
                  value={block.heading}
                  onChange={(event) =>
                    setBlocks((prev) =>
                      updateBlock(prev, block.id, { heading: event.target.value }),
                    )
                  }
                  placeholder="Heading"
                  className="rounded border border-neutral-300 px-2 py-1 text-sm"
                />
                <input
                  value={block.subheading ?? ""}
                  onChange={(event) =>
                    setBlocks((prev) =>
                      updateBlock(prev, block.id, { subheading: event.target.value || null }),
                    )
                  }
                  placeholder="Subheading"
                  className="rounded border border-neutral-300 px-2 py-1 text-sm"
                />
                <input
                  value={block.ctaLabel ?? ""}
                  onChange={(event) =>
                    setBlocks((prev) =>
                      updateBlock(prev, block.id, { ctaLabel: event.target.value || null }),
                    )
                  }
                  placeholder="CTA label"
                  className="rounded border border-neutral-300 px-2 py-1 text-sm"
                />
                <input
                  value={block.ctaHref ?? ""}
                  onChange={(event) =>
                    setBlocks((prev) =>
                      updateBlock(prev, block.id, { ctaHref: event.target.value || null }),
                    )
                  }
                  placeholder="CTA href"
                  className="rounded border border-neutral-300 px-2 py-1 text-sm"
                />
              </div>
            ) : null}

            {block.type === "rich_text" ? (
              <textarea
                rows={5}
                value={block.body}
                onChange={(event) =>
                  setBlocks((prev) => updateBlock(prev, block.id, { body: event.target.value }))
                }
                placeholder="Text"
                className="w-full rounded border border-neutral-300 px-2 py-1 text-sm"
              />
            ) : null}

            {block.type === "gallery" ? (
              <div className="space-y-2">
                <input
                  value={block.title ?? ""}
                  onChange={(event) =>
                    setBlocks((prev) =>
                      updateBlock(prev, block.id, { title: event.target.value || null }),
                    )
                  }
                  placeholder="Gallery title"
                  className="w-full rounded border border-neutral-300 px-2 py-1 text-sm"
                />
                <textarea
                  rows={3}
                  value={block.imageIds.join(",")}
                  onChange={(event) =>
                    setBlocks((prev) =>
                      updateBlock(prev, block.id, {
                        imageIds: event.target.value
                          .split(",")
                          .map((entry) => entry.trim())
                          .filter((entry) => entry.length > 0),
                      }),
                    )
                  }
                  placeholder="Media asset IDs (comma separated UUIDs)"
                  className="w-full rounded border border-neutral-300 px-2 py-1 text-sm"
                />
              </div>
            ) : null}

            {block.type === "cta" ? (
              <div className="grid gap-2 md:grid-cols-2">
                <input
                  value={block.label}
                  onChange={(event) =>
                    setBlocks((prev) => updateBlock(prev, block.id, { label: event.target.value }))
                  }
                  placeholder="Button label"
                  className="rounded border border-neutral-300 px-2 py-1 text-sm"
                />
                <input
                  value={block.href}
                  onChange={(event) =>
                    setBlocks((prev) => updateBlock(prev, block.id, { href: event.target.value }))
                  }
                  placeholder="Link href"
                  className="rounded border border-neutral-300 px-2 py-1 text-sm"
                />
                <select
                  value={block.variant}
                  onChange={(event) =>
                    setBlocks((prev) =>
                      updateBlock(prev, block.id, {
                        variant: event.target.value as "primary" | "secondary",
                      }),
                    )
                  }
                  className="rounded border border-neutral-300 px-2 py-1 text-sm"
                >
                  <option value="primary">Primary</option>
                  <option value="secondary">Secondary</option>
                </select>
              </div>
            ) : null}

            {block.type === "form" ? (
              <div className="space-y-2">
                <input
                  value={block.formKey}
                  onChange={(event) =>
                    setBlocks((prev) =>
                      updateBlock(prev, block.id, { formKey: event.target.value }),
                    )
                  }
                  placeholder="Form key (e.g. contact, commission)"
                  className="w-full rounded border border-neutral-300 px-2 py-1 text-sm"
                />
                <input
                  value={block.title ?? ""}
                  onChange={(event) =>
                    setBlocks((prev) =>
                      updateBlock(prev, block.id, { title: event.target.value || null }),
                    )
                  }
                  placeholder="Form title"
                  className="w-full rounded border border-neutral-300 px-2 py-1 text-sm"
                />
                <textarea
                  rows={2}
                  value={block.description ?? ""}
                  onChange={(event) =>
                    setBlocks((prev) =>
                      updateBlock(prev, block.id, { description: event.target.value || null }),
                    )
                  }
                  placeholder="Form description"
                  className="w-full rounded border border-neutral-300 px-2 py-1 text-sm"
                />
              </div>
            ) : null}

            {block.type === "price_cards" ? (
              <div className="space-y-2">
                <input
                  value={block.title ?? ""}
                  onChange={(event) =>
                    setBlocks((prev) =>
                      updateBlock(prev, block.id, { title: event.target.value || null }),
                    )
                  }
                  placeholder="Price card section title"
                  className="w-full rounded border border-neutral-300 px-2 py-1 text-sm"
                />
                <textarea
                  rows={4}
                  value={block.cards
                    .map((card) => [card.name, card.price ?? "", card.description ?? ""].join("|"))
                    .join("\n")}
                  onChange={(event) =>
                    setBlocks((prev) =>
                      updateBlock(prev, block.id, {
                        cards: event.target.value
                          .split("\n")
                          .map((line) => line.trim())
                          .filter((line) => line.length > 0)
                          .map((line, lineIndex) => {
                            const [name, price, description] = line
                              .split("|")
                              .map((entry) => entry.trim())
                            return {
                              id: `card-${lineIndex}`,
                              name: name || `Card ${lineIndex + 1}`,
                              price: price || null,
                              description: description || null,
                            }
                          }),
                      }),
                    )
                  }
                  placeholder="One card per line: Name|Price|Description"
                  className="w-full rounded border border-neutral-300 px-2 py-1 text-sm"
                />
              </div>
            ) : null}
          </article>
        ))}
      </div>
    </div>
  )
}
