'use client'

import { useEffect, 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 { MediaPickerModal } from '../../components/MediaPickerModal.js'
import { TagInput } from '../../components/TagInput.js'
import { RichTextField } from '../../fields/RichTextField.js'
import { SeoCharCount } from '../../components/seo/SeoCharCount.js'
import type { EditorPost } from '../../lib/post-editor-service.js'

const SEO_TITLE_MIN = 30
const SEO_TITLE_MAX = 60
const SEO_DESC_MIN = 120
const SEO_DESC_MAX = 160

/**
 * The slice of a collection's field config the modal reads to pick controls:
 * a `select` category renders a dropdown (structured vocabulary), an `array`
 * tags field renders the chip input with autocomplete.
 */
export interface PostFieldConfig {
  type?: string
  options?: Array<{ label: string; value: string }>
  maxRows?: number
}

interface PostFieldsModalProps {
  open: boolean
  post: EditorPost
  canEdit: boolean
  /** Field definitions from the post type's collection config. */
  fields?: Record<string, PostFieldConfig | undefined>
  onClose: () => void
  onSave: (patch: Partial<EditorPost>) => 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

/** Edits post-level fields: title, slug, excerpt, featured image, category, tags, body, SEO. */
export function PostFieldsModal({
  open,
  post,
  canEdit,
  fields,
  onClose,
  onSave,
}: PostFieldsModalProps) {
  const [title, setTitle] = useState(post.title)
  const [slug, setSlug] = useState(post.slug)
  const [excerpt, setExcerpt] = useState(post.excerpt)
  const [featuredImage, setFeaturedImage] = useState(post.featuredImage)
  const [category, setCategory] = useState(post.category)
  const [tags, setTags] = useState<string[]>(post.tags)
  const [body, setBody] = useState(post.body)
  const [seoTitle, setSeoTitle] = useState(post.seoTitle)
  const [seoDescription, setSeoDescription] = useState(post.seoDescription)
  const [slugTouched, setSlugTouched] = useState(Boolean(post.slug))
  const [mediaOpen, setMediaOpen] = useState(false)

  const categoryField = fields?.category
  const categoryOptions =
    categoryField?.type === 'select' && Array.isArray(categoryField.options)
      ? categoryField.options
      : null
  const tagsField = fields?.tags
  const hasTags = tagsField?.type === 'array'

  useEffect(() => {
    if (!open) return
    setTitle(post.title)
    setSlug(post.slug)
    setExcerpt(post.excerpt)
    setFeaturedImage(post.featuredImage)
    setCategory(post.category)
    setTags(post.tags)
    setBody(post.body)
    setSeoTitle(post.seoTitle)
    setSeoDescription(post.seoDescription)
    setSlugTouched(Boolean(post.slug))
  }, [open, post])

  function handleTitle(next: string) {
    setTitle(next)
    if (!slugTouched) setSlug(slugify(next))
  }

  const slugError = validateSlug(slug)

  function handleSave() {
    if (slugError) return
    onSave({ title, slug, excerpt, featuredImage, category, tags, body, seoTitle, seoDescription })
    onClose()
  }

  return (
    <Modal
      open={open}
      onClose={onClose}
      title="Post details"
      actions={
        <>
          <Button variant="ghost" onClick={onClose}>
            Cancel
          </Button>
          <Button variant="primary" onClick={handleSave} disabled={!canEdit || Boolean(slugError)}>
            Done
          </Button>
        </>
      }
    >
      <div className="space-y-3">
        <div>
          <label className={LABEL} htmlFor="pf-title">
            Title <span className="text-destructive">*</span>
          </label>
          <input
            id="pf-title"
            className={INPUT}
            value={title}
            disabled={!canEdit}
            onChange={(e) => handleTitle(e.target.value)}
          />
        </div>
        <div className="grid grid-cols-2 gap-3">
          <div>
            <label className={LABEL} htmlFor="pf-slug">
              Slug <span className="text-destructive">*</span>
            </label>
            <input
              id="pf-slug"
              className={INPUT}
              value={slug}
              disabled={!canEdit}
              aria-invalid={Boolean(slugError)}
              aria-describedby={slugError ? 'pf-slug-error' : undefined}
              onChange={(e) => {
                setSlugTouched(true)
                setSlug(slugify(e.target.value))
              }}
            />
            {slugError && (
              <p id="pf-slug-error" className="text-destructive mt-1 text-xs">
                {slugError}
              </p>
            )}
          </div>
          <div>
            <label className={LABEL} htmlFor="pf-category">
              Category
            </label>
            {categoryOptions ? (
              <select
                id="pf-category"
                className={INPUT}
                value={category}
                disabled={!canEdit}
                onChange={(e) => setCategory(e.target.value)}
              >
                <option value="">No category</option>
                {categoryOptions.map((o) => (
                  <option key={o.value} value={o.value}>
                    {o.label}
                  </option>
                ))}
                {/* Keep a legacy free-text value selectable so opening the
                    modal never silently discards it. */}
                {category && !categoryOptions.some((o) => o.value === category) && (
                  <option value={category}>{category}</option>
                )}
              </select>
            ) : (
              <input
                id="pf-category"
                className={INPUT}
                value={category}
                disabled={!canEdit}
                placeholder="e.g. Product"
                onChange={(e) => setCategory(e.target.value)}
              />
            )}
          </div>
        </div>
        {hasTags && (
          <div>
            <label className={LABEL} htmlFor="pf-tags">
              Tags
            </label>
            <TagInput
              id="pf-tags"
              value={tags}
              onChange={setTags}
              collection={post.postType}
              field="tags"
              disabled={!canEdit}
              maxTags={tagsField?.maxRows}
            />
          </div>
        )}
        <div>
          <label className={LABEL} htmlFor="pf-excerpt">
            Excerpt
          </label>
          <textarea
            id="pf-excerpt"
            className={`${INPUT} min-h-[60px] resize-y`}
            value={excerpt}
            disabled={!canEdit}
            placeholder="A short summary shown in listings and the header."
            onChange={(e) => setExcerpt(e.target.value)}
          />
        </div>
        <div>
          <label className={LABEL} htmlFor="pf-image">
            Featured image
          </label>
          <div className="flex gap-2">
            <input
              id="pf-image"
              className={`${INPUT} flex-1`}
              value={featuredImage}
              disabled={!canEdit}
              placeholder="https://… or pick from the media library"
              onChange={(e) => setFeaturedImage(e.target.value)}
            />
            <button
              type="button"
              disabled={!canEdit}
              onClick={() => setMediaOpen(true)}
              className="bg-accent text-foreground border-border hover:bg-accent/80 shrink-0 rounded-md border px-3 py-1.5 text-xs font-medium disabled:opacity-50"
            >
              Browse
            </button>
          </div>
          {featuredImage && (
            <div className="border-border bg-muted mt-2 overflow-hidden rounded-md border">
              <img src={featuredImage} alt="" className="h-28 w-full object-cover" />
            </div>
          )}
        </div>
        <div>
          <RichTextField
            label="Body"
            value={body}
            onChange={canEdit ? setBody : () => {}}
            helpText="Rendered by the Article Body section when its source is set to the post Body field."
          />
        </div>
        <div>
          <div className="mb-1 flex items-center justify-between">
            <label className={`${LABEL} mb-0`} htmlFor="pf-seo-title">
              SEO title
            </label>
            <SeoCharCount value={seoTitle} min={SEO_TITLE_MIN} max={SEO_TITLE_MAX} />
          </div>
          <input
            id="pf-seo-title"
            className={INPUT}
            value={seoTitle}
            disabled={!canEdit}
            placeholder={title || 'Defaults to the post title'}
            onChange={(e) => setSeoTitle(e.target.value)}
          />
        </div>
        <div>
          <div className="mb-1 flex items-center justify-between">
            <label className={`${LABEL} mb-0`} htmlFor="pf-seo-desc">
              SEO description
            </label>
            <SeoCharCount value={seoDescription} min={SEO_DESC_MIN} max={SEO_DESC_MAX} />
          </div>
          <textarea
            id="pf-seo-desc"
            className={`${INPUT} min-h-[60px] resize-y`}
            value={seoDescription}
            disabled={!canEdit}
            placeholder={excerpt || 'Summarize the post for search results (120–160 characters)'}
            onChange={(e) => setSeoDescription(e.target.value)}
          />
        </div>
      </div>

      <MediaPickerModal
        open={mediaOpen}
        onClose={() => setMediaOpen(false)}
        onSelect={(url) => {
          setFeaturedImage(url)
          setMediaOpen(false)
        }}
        accept="image/*"
      />
    </Modal>
  )
}
