'use client'

import { useEffect, useRef, useState } from 'react'
import { normalizeSlug, validateSlug } from '@actuate-media/cms-core/client'
import { Modal } from '../../components/ui/Modal.js'
import { Button } from '../../components/ui/Button.js'
import { cmsApi } from '../../lib/api.js'
import type { EditorPage } from '../../lib/page-editor-service.js'

interface PageSettingsModalProps {
  open: boolean
  page: EditorPage
  canEdit: boolean
  onClose: () => void
  onSave: (patch: Partial<EditorPage>) => void
}

const LABEL = 'text-foreground mb-1 block text-xs font-medium'
const INPUT =
  'border-input bg-input-background text-foreground focus-visible:ring-ring w-full rounded-md border px-2.5 py-1.5 text-sm focus-visible:ring-2 focus-visible:outline-none'

const slugify = normalizeSlug

interface ParentOption {
  id: string
  title: string
}

/** Edits page-level fields: title, slug, path, and parent page. SEO lives in the SEO tab. */
export function PageSettingsModal({
  open,
  page,
  canEdit,
  onClose,
  onSave,
}: PageSettingsModalProps) {
  const [title, setTitle] = useState(page.title)
  const [slug, setSlug] = useState(page.slug)
  const [path, setPath] = useState(page.path)
  const [parentPageId, setParentPageId] = useState(page.parentPageId ?? '')
  // Auto-derive slug/path from title until the user edits slug manually.
  const [slugTouched, setSlugTouched] = useState(Boolean(page.slug))
  const [parentOptions, setParentOptions] = useState<ParentOption[] | null>(null)
  // Land the user in the Title field (WordPress-style "name it first"),
  // rather than Radix's default focus on the header close button.
  const titleRef = useRef<HTMLInputElement | null>(null)

  useEffect(() => {
    if (!open) return
    setTitle(page.title)
    setSlug(page.slug)
    setPath(page.path)
    setParentPageId(page.parentPageId ?? '')
    setSlugTouched(Boolean(page.slug))
  }, [open, page])

  // Load the parent-page choices lazily the first time the modal opens.
  // The page itself is excluded (a page can't be its own parent); deeper
  // cycle protection lives in the tree builder, which breaks bad chains.
  useEffect(() => {
    if (!open || parentOptions !== null) return
    let cancelled = false
    cmsApi<{ docs: Array<{ id: string; title: string | null }> }>(
      '/collections/pages?pageSize=500&sort=updatedAt&order=desc',
    )
      .then((res) => {
        if (cancelled) return
        const docs = res.data?.docs ?? []
        const options = docs
          .filter((d) => d.id !== page.id)
          .map((d) => ({ id: d.id, title: d.title ?? '(untitled)' }))
          .sort((a, b) => a.title.localeCompare(b.title))
        setParentOptions(options)
      })
      .catch(() => {
        // Leave the picker in its loading state note; the rest of the
        // settings form stays fully usable.
        if (!cancelled) setParentOptions([])
      })
    return () => {
      cancelled = true
    }
  }, [open, parentOptions, page.id])

  function handleTitle(next: string) {
    setTitle(next)
    if (!slugTouched) {
      const s = slugify(next)
      setSlug(s)
      if (!page.path || page.path === `/${slug}`) setPath(s ? `/${s}` : '')
    }
  }

  const slugError = validateSlug(slug)

  function handleSave() {
    if (slugError) return
    onSave({
      title,
      slug,
      path: path || (slug ? `/${slug}` : '/'),
      parentPageId: parentPageId || null,
    })
    onClose()
  }

  return (
    <Modal
      open={open}
      onClose={onClose}
      title="Page settings"
      initialFocusRef={titleRef}
      actions={
        <>
          <Button variant="ghost" onClick={onClose}>
            Cancel
          </Button>
          <Button
            variant="primary"
            form="page-settings-form"
            type="submit"
            disabled={!canEdit || Boolean(slugError)}
          >
            Done
          </Button>
        </>
      }
    >
      {/* A real form so Enter in any field confirms the dialog — matters
          for the new-page flow where this modal is the first stop. */}
      <form
        id="page-settings-form"
        className="space-y-3"
        onSubmit={(e) => {
          e.preventDefault()
          handleSave()
        }}
      >
        <div>
          <label className={LABEL} htmlFor="ps-title">
            Title <span className="text-destructive">*</span>
          </label>
          <input
            id="ps-title"
            ref={titleRef}
            className={INPUT}
            value={title}
            disabled={!canEdit}
            placeholder="e.g. About Us"
            onChange={(e) => handleTitle(e.target.value)}
          />
          <p className="text-muted-foreground mt-1 text-xs">
            The slug and path below follow the title until you edit them.
          </p>
        </div>
        <div className="grid grid-cols-2 gap-3">
          <div>
            <label className={LABEL} htmlFor="ps-slug">
              Slug
            </label>
            <input
              id="ps-slug"
              className={INPUT}
              value={slug}
              disabled={!canEdit}
              aria-invalid={Boolean(slugError)}
              aria-describedby={slugError ? 'ps-slug-error' : undefined}
              onChange={(e) => {
                setSlugTouched(true)
                setSlug(slugify(e.target.value))
              }}
            />
            {slugError && (
              <p id="ps-slug-error" className="text-destructive mt-1 text-xs">
                {slugError}
              </p>
            )}
          </div>
          <div>
            <label className={LABEL} htmlFor="ps-path">
              Path <span className="text-destructive">*</span>
            </label>
            <input
              id="ps-path"
              className={INPUT}
              value={path}
              disabled={!canEdit}
              placeholder="/about/story"
              onChange={(e) => setPath(e.target.value)}
            />
          </div>
        </div>
        <div>
          <label className={LABEL} htmlFor="ps-parent">
            Parent page
          </label>
          <select
            id="ps-parent"
            className={INPUT}
            value={parentPageId}
            disabled={!canEdit || parentOptions === null}
            onChange={(e) => setParentPageId(e.target.value)}
          >
            <option value="">None — top level</option>
            {/* Keep a preselected parent (e.g. from "Add sub-page") valid
                while the options load or if it's missing from the list. */}
            {parentPageId && !(parentOptions ?? []).some((p) => p.id === parentPageId) && (
              <option value={parentPageId}>
                {parentOptions === null ? 'Loading…' : 'Current parent'}
              </option>
            )}
            {(parentOptions ?? []).map((p) => (
              <option key={p.id} value={p.id}>
                {p.title}
              </option>
            ))}
          </select>
          <p className="text-muted-foreground mt-1 text-xs">
            Nests this page under a parent in the Pages tree view.
          </p>
        </div>
      </form>
    </Modal>
  )
}
