'use client'

import { cloneElement, isValidElement, useEffect, useId, useState, type ReactElement } from 'react'
import { Sparkles, Check } from 'lucide-react'
import { toast } from 'sonner'
import {
  fetchSeoContentRecord,
  updateSeoFields,
  generateSeoField,
  type SeoContentRecord,
  type SeoFieldPayload,
  type LlmsInclude,
} from '../../lib/seo-service.js'
import { Drawer } from './Drawer.js'
import { SeoLoading, SeoErrorState, btnPrimary, btnSecondary, gradeMeta } from './primitives.js'

const META_TITLE_MAX = 60
const META_DESC_MAX = 160

type AiField =
  | 'metaTitle'
  | 'metaDescription'
  | 'ogTitle'
  | 'ogDescription'
  | 'focusKeyword'
  | 'keyTakeaway'

const KEY_TAKEAWAY_MAX = 240
const LLMS_DESC_MAX = 160

function CharCount({ value, max }: { value: string; max: number }) {
  const over = value.length > max
  return (
    <span className={`text-xs ${over ? 'text-destructive' : 'text-muted-foreground'}`}>
      {value.length}/{max}
    </span>
  )
}

function Field({
  label,
  children,
  hint,
}: {
  label: string
  children: React.ReactNode
  hint?: React.ReactNode
}) {
  // Associate the visible label with its control for screen readers. We inject
  // a generated id onto the single child input/textarea (unless it already has
  // one) and point the <label htmlFor> at it.
  const generatedId = useId()
  let control = children
  if (isValidElement(children) && (children.props as { id?: string }).id == null) {
    control = cloneElement(children as ReactElement<{ id?: string }>, { id: generatedId })
  }
  const controlId = isValidElement(control) ? (control.props as { id?: string }).id : undefined

  return (
    <div className="space-y-1.5">
      <div className="flex items-center justify-between">
        <label htmlFor={controlId} className="text-foreground text-sm font-medium">
          {label}
        </label>
        {hint}
      </div>
      {control}
    </div>
  )
}

const inputCls =
  'w-full rounded-md border border-border bg-input-background px-3 py-2 text-base text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring'

export function SeoEditorDrawer({
  open,
  onOpenChange,
  entityType,
  entityId,
  onSaved,
}: {
  open: boolean
  onOpenChange: (open: boolean) => void
  entityType: string | null
  entityId: string | null
  onSaved?: () => void
}) {
  const [record, setRecord] = useState<SeoContentRecord | null>(null)
  const [loading, setLoading] = useState(false)
  const [error, setError] = useState<string | null>(null)
  const [saving, setSaving] = useState(false)
  const [aiBusy, setAiBusy] = useState<AiField | null>(null)
  const [form, setForm] = useState<SeoFieldPayload>({})

  useEffect(() => {
    if (!open || !entityType || !entityId) return
    let alive = true
    setLoading(true)
    setError(null)
    fetchSeoContentRecord(entityType, entityId)
      .then((rec) => {
        if (!alive) return
        if (!rec) {
          setError('Could not load this record.')
          return
        }
        setRecord(rec)
        setForm({
          metaTitle: rec.metaTitle ?? '',
          metaDescription: rec.metaDescription ?? '',
          canonicalUrl: rec.canonicalUrl ?? '',
          focusKeyword: rec.focusKeyword ?? '',
          keyTakeaway: rec.keyTakeaway ?? '',
          ogTitle: rec.ogTitle ?? '',
          ogDescription: rec.ogDescription ?? '',
          noindex: rec.noindex,
          nofollow: rec.nofollow,
          llmsInclude: rec.llmsInclude ?? 'AUTO',
          llmsDescription: rec.llmsDescription ?? '',
          llmsSection: rec.llmsSection ?? '',
          llmsOptional: rec.llmsOptional ?? false,
        })
      })
      .catch((e) => alive && setError(e instanceof Error ? e.message : 'Failed to load'))
      .finally(() => alive && setLoading(false))
    return () => {
      alive = false
    }
  }, [open, entityType, entityId])

  const update = (patch: Partial<SeoFieldPayload>) => setForm((f) => ({ ...f, ...patch }))

  async function handleAiGenerate(field: AiField) {
    if (!entityType || !entityId) return
    setAiBusy(field)
    try {
      const result = await generateSeoField(field, { entityType, entityId })
      if (result.unavailable) {
        toast.error('AI is not configured. Add an AI provider to enable suggestions.')
        return
      }
      if (result.text) {
        update({ [field]: result.text } as Partial<SeoFieldPayload>)
        toast.success('AI suggestion applied — review before saving.')
      } else {
        toast.error('No suggestion was returned.')
      }
    } catch {
      toast.error('AI request failed.')
    } finally {
      setAiBusy(null)
    }
  }

  async function handleSave() {
    if (!entityType || !entityId) return
    setSaving(true)
    const res = await updateSeoFields(entityType, entityId, form)
    setSaving(false)
    if (res.error) {
      toast.error(res.error)
      return
    }
    toast.success('SEO fields saved.')
    onOpenChange(false)
    onSaved?.()
  }

  const title = form.metaTitle || record?.title || 'Untitled'
  const desc = form.metaDescription || 'No meta description set. Search engines may generate one.'
  const url = record?.url ?? ''

  function aiButton(field: AiField) {
    return (
      <button
        type="button"
        onClick={() => handleAiGenerate(field)}
        disabled={aiBusy !== null}
        className="text-primary hover:bg-accent focus-visible:ring-ring inline-flex items-center gap-1 rounded-md px-2 py-0.5 text-xs font-medium focus-visible:ring-2 focus-visible:outline-none disabled:opacity-60"
      >
        <Sparkles
          className={`h-3.5 w-3.5 ${aiBusy === field ? 'animate-pulse' : ''}`}
          aria-hidden
        />
        {aiBusy === field ? 'Generating…' : 'AI Generate'}
      </button>
    )
  }

  return (
    <Drawer
      open={open}
      onOpenChange={onOpenChange}
      title="Edit SEO"
      description={record?.title}
      footer={
        <>
          <button className={btnSecondary} onClick={() => onOpenChange(false)} disabled={saving}>
            Cancel
          </button>
          <button className={btnPrimary} onClick={handleSave} disabled={saving || loading}>
            {saving ? 'Saving…' : 'Save changes'}
          </button>
        </>
      }
    >
      {loading ? (
        <SeoLoading />
      ) : error ? (
        <SeoErrorState message={error} />
      ) : record ? (
        <div className="space-y-6">
          {/* SERP preview */}
          <div className="border-border rounded-lg border p-4">
            <p className="text-muted-foreground mb-2 text-xs font-medium tracking-wide uppercase">
              Google preview
            </p>
            <p className="text-success truncate text-sm">{url}</p>
            <p className="text-primary text-lg leading-snug">{title}</p>
            <p className="text-muted-foreground line-clamp-2 text-sm">{desc}</p>
          </div>

          <Field
            label="Meta title"
            hint={
              <span className="flex items-center gap-2">
                <CharCount value={form.metaTitle ?? ''} max={META_TITLE_MAX} />
                {aiButton('metaTitle')}
              </span>
            }
          >
            <input
              className={inputCls}
              value={form.metaTitle ?? ''}
              onChange={(e) => update({ metaTitle: e.target.value })}
              placeholder="Page title for search results"
            />
          </Field>

          <Field
            label="Meta description"
            hint={
              <span className="flex items-center gap-2">
                <CharCount value={form.metaDescription ?? ''} max={META_DESC_MAX} />
                {aiButton('metaDescription')}
              </span>
            }
          >
            <textarea
              className={`${inputCls} min-h-20 resize-y`}
              value={form.metaDescription ?? ''}
              onChange={(e) => update({ metaDescription: e.target.value })}
              placeholder="Short summary shown under the title in search results"
            />
          </Field>

          <Field label="Focus keyword" hint={aiButton('focusKeyword')}>
            <input
              className={inputCls}
              value={form.focusKeyword ?? ''}
              onChange={(e) => update({ focusKeyword: e.target.value })}
              placeholder="Primary keyword this page targets"
            />
          </Field>

          <Field
            label="Key takeaway"
            hint={
              <span className="flex items-center gap-2">
                <CharCount value={form.keyTakeaway ?? ''} max={KEY_TAKEAWAY_MAX} />
                {aiButton('keyTakeaway')}
              </span>
            }
          >
            <textarea
              className={`${inputCls} min-h-16 resize-y`}
              value={form.keyTakeaway ?? ''}
              onChange={(e) => update({ keyTakeaway: e.target.value })}
              placeholder="One or two sentences AI answer engines can quote — what is this page about?"
            />
          </Field>

          <Field label="Canonical URL">
            <input
              className={inputCls}
              value={form.canonicalUrl ?? ''}
              onChange={(e) => update({ canonicalUrl: e.target.value })}
              placeholder={url || 'https://example.com/page'}
            />
          </Field>

          {/* Social preview */}
          <div className="space-y-4">
            <p className="text-foreground text-sm font-medium">Social sharing</p>
            <Field label="Open Graph title" hint={aiButton('ogTitle')}>
              <input
                className={inputCls}
                value={form.ogTitle ?? ''}
                onChange={(e) => update({ ogTitle: e.target.value })}
                placeholder={form.metaTitle || 'Title when shared on social media'}
              />
            </Field>
            <Field label="Open Graph description" hint={aiButton('ogDescription')}>
              <textarea
                className={`${inputCls} min-h-16 resize-y`}
                value={form.ogDescription ?? ''}
                onChange={(e) => update({ ogDescription: e.target.value })}
                placeholder={form.metaDescription || 'Description when shared on social media'}
              />
            </Field>
            <div className="border-border overflow-hidden rounded-lg border">
              {record.ogImage ? (
                // eslint-disable-next-line @next/next/no-img-element
                <img
                  src={record.ogImage}
                  alt={`Social preview for ${record.title}`}
                  className="bg-muted aspect-[1200/630] w-full object-cover"
                />
              ) : (
                <div className="bg-muted text-muted-foreground flex aspect-[1200/630] w-full items-center justify-center text-sm">
                  No OG image set
                </div>
              )}
              <div className="p-3">
                <p className="text-muted-foreground truncate text-xs uppercase">
                  {url.replace(/^https?:\/\//, '').split('/')[0]}
                </p>
                <p className="text-foreground truncate text-sm font-medium">
                  {form.ogTitle || title}
                </p>
                <p className="text-muted-foreground line-clamp-1 text-sm">
                  {form.ogDescription || desc}
                </p>
              </div>
            </div>
          </div>

          {/* Indexing toggles */}
          <div className="border-border space-y-3 rounded-lg border p-4">
            <label className="flex items-center justify-between gap-3">
              <span className="min-w-0">
                <span className="text-foreground block text-sm font-medium">No-index</span>
                <span className="text-muted-foreground block text-sm">
                  Hide this page from search engines.
                </span>
              </span>
              <input
                type="checkbox"
                role="switch"
                aria-checked={!!form.noindex}
                checked={!!form.noindex}
                onChange={(e) => update({ noindex: e.target.checked })}
                className="accent-primary h-4 w-4"
              />
            </label>
            <label className="flex items-center justify-between gap-3">
              <span className="min-w-0">
                <span className="text-foreground block text-sm font-medium">No-follow</span>
                <span className="text-muted-foreground block text-sm">
                  Tell crawlers not to follow links on this page.
                </span>
              </span>
              <input
                type="checkbox"
                role="switch"
                aria-checked={!!form.nofollow}
                checked={!!form.nofollow}
                onChange={(e) => update({ nofollow: e.target.checked })}
                className="accent-primary h-4 w-4"
              />
            </label>
          </div>

          {/* llms.txt curation */}
          <div className="border-border space-y-4 rounded-lg border p-4">
            <div>
              <p className="text-foreground text-sm font-medium">AI discovery (llms.txt)</p>
              <p className="text-muted-foreground text-sm">
                Controls how this page appears in the curated <code>llms.txt</code> guide that AI
                agents read. It does not affect search ranking.
              </p>
            </div>
            <Field label="Include in llms.txt">
              <select
                className={inputCls}
                value={form.llmsInclude ?? 'AUTO'}
                onChange={(e) => update({ llmsInclude: e.target.value as LlmsInclude })}
              >
                <option value="AUTO">Auto — include when eligible</option>
                <option value="ALWAYS">Always — pin it in</option>
                <option value="NEVER">Never — exclude</option>
              </select>
            </Field>
            <Field
              label="Agent description"
              hint={<CharCount value={form.llmsDescription ?? ''} max={LLMS_DESC_MAX} />}
            >
              <textarea
                className={`${inputCls} min-h-16 resize-y`}
                value={form.llmsDescription ?? ''}
                onChange={(e) => update({ llmsDescription: e.target.value })}
                placeholder={
                  form.keyTakeaway ||
                  form.metaDescription ||
                  'One line for an AI agent — what this page covers and why it matters.'
                }
              />
            </Field>
            <Field label="Section">
              <input
                className={inputCls}
                value={form.llmsSection ?? ''}
                onChange={(e) => update({ llmsSection: e.target.value })}
                placeholder="Defaults to the content type"
              />
            </Field>
            <label className="flex items-center justify-between gap-3">
              <span className="min-w-0">
                <span className="text-foreground block text-sm font-medium">Optional</span>
                <span className="text-muted-foreground block text-sm">
                  Group under “Optional” — agents skip these first when context is tight.
                </span>
              </span>
              <input
                type="checkbox"
                role="switch"
                aria-checked={!!form.llmsOptional}
                checked={!!form.llmsOptional}
                onChange={(e) => update({ llmsOptional: e.target.checked })}
                className="accent-primary h-4 w-4"
              />
            </label>
          </div>

          {/* Score summary */}
          {(() => {
            const meta = gradeMeta(record.seoGrade)
            return (
              <div
                className={`flex items-center gap-2 rounded-lg px-3 py-2 text-sm ${meta.bg} ${meta.text}`}
              >
                <Check className="h-4 w-4" aria-hidden />
                Current SEO score: <span className="font-medium">{record.seoScore}</span> (
                {meta.label})
              </div>
            )
          })()}
        </div>
      ) : null}
    </Drawer>
  )
}
