'use client'

/**
 * Inline redirect editor pane — design-parity replacement for the old
 * `RedirectEditorDrawer` overlay. Rendered inside an `<InspectorPane>` beside
 * the redirect rules table. Same fields, validation, and create/update save
 * paths as the drawer; only the presentation pattern changed.
 */
import { useState } from 'react'
import { Trash2 } from 'lucide-react'
import { toast } from 'sonner'
import {
  createRedirectRule,
  updateRedirectRule,
  type RedirectRule,
  type RedirectRulePayload,
  type RedirectStatusCode,
} from '../../lib/seo-service.js'
import {
  InspectorPaneBody,
  InspectorPaneFooter,
  InspectorPaneHeader,
  InspectorPaneSection,
} from '../ui/InspectorPane.js'
import { Toggle } from '../ui/Toggle.js'

const STATUS_CODES: { value: RedirectStatusCode; label: string }[] = [
  { value: 301, label: '301 — Permanent' },
  { value: 302, label: '302 — Temporary' },
  { value: 307, label: '307 — Temporary (preserve method)' },
  { value: 308, label: '308 — Permanent (preserve method)' },
  { value: 410, label: '410 — Gone (no destination)' },
]

const inputCls =
  'w-full rounded-[7px] border border-[var(--bdr)] bg-[var(--card)] px-2.5 py-1.5 text-[12.5px] text-[var(--txt)] placeholder:text-[var(--muted)] focus:border-[var(--acc)] focus:outline-none'

const labelCls = 'mb-1 block text-[11.5px] font-medium text-[var(--sub)]'

function normalizePath(p: string): string {
  const t = p.trim()
  if (!t) return ''
  if (/^https?:\/\//i.test(t)) return t
  return t.startsWith('/') ? t : `/${t}`
}

function PaneToggleRow({
  label,
  hint,
  checked,
  onCheckedChange,
  variant,
}: {
  label: string
  hint?: string
  checked: boolean
  onCheckedChange: (checked: boolean) => void
  variant?: 'enabled'
}) {
  return (
    <div className="flex items-center justify-between gap-3 py-1.5">
      <div className="min-w-0">
        <div className="text-[12.5px] font-medium text-[var(--txt)]">{label}</div>
        {hint && <div className="text-[11px] text-[var(--muted)]">{hint}</div>}
      </div>
      <Toggle
        checked={checked}
        onCheckedChange={onCheckedChange}
        variant={variant}
        aria-label={label}
      />
    </div>
  )
}

export interface RedirectEditorPaneProps {
  /** null = create mode */
  rule: RedirectRule | null
  onClose: () => void
  /** Called after a successful save so the list can refetch / close the pane. */
  onSaved?: () => void
  /** Ask the parent to confirm-and-delete this rule (edit mode only). */
  onDelete?: (rule: RedirectRule) => void
}

export function RedirectEditorPane({ rule, onClose, onSaved, onDelete }: RedirectEditorPaneProps) {
  // The parent keys this pane by rule id, so initializing from props is safe.
  const [form, setForm] = useState<RedirectRulePayload>(() =>
    rule
      ? {
          type: rule.type,
          fromPath: rule.fromPath,
          toPath: rule.toPath,
          enabled: rule.enabled,
          preserveQuery: rule.preserveQuery,
          notes: rule.notes ?? '',
        }
      : {
          type: 301,
          fromPath: '',
          toPath: '',
          enabled: true,
          preserveQuery: false,
          notes: '',
        },
  )
  const [saving, setSaving] = useState(false)
  const [clientError, setClientError] = useState<string | null>(null)

  const isGone = form.type === 410
  const update = (patch: Partial<RedirectRulePayload>) => setForm((f) => ({ ...f, ...patch }))

  async function handleSave() {
    const fromPath = normalizePath(form.fromPath)
    const toPath = isGone ? '' : normalizePath(form.toPath)
    if (!fromPath) {
      setClientError('Source path is required.')
      return
    }
    if (!isGone && !toPath) {
      setClientError('Destination is required for redirect status codes.')
      return
    }
    if (!isGone && fromPath === toPath) {
      setClientError('Source and destination cannot be identical (would create a loop).')
      return
    }
    setClientError(null)
    setSaving(true)
    const payload: RedirectRulePayload = { ...form, fromPath, toPath }
    const res = rule
      ? await updateRedirectRule(rule.id, payload)
      : await createRedirectRule(payload)
    setSaving(false)
    if (res.error) {
      toast.error(res.error)
      return
    }
    toast.success(rule ? 'Redirect updated.' : 'Redirect created.')
    onSaved?.()
  }

  return (
    <>
      <InspectorPaneHeader onClose={onClose} closeLabel="Close redirect editor">
        <div className="truncate text-[13.5px] font-semibold text-[var(--txt)]">
          {rule ? 'Edit redirect' : 'New redirect'}
        </div>
        {rule && (
          <div className="mt-0.5 truncate font-mono text-[11.5px] text-[var(--muted)]">
            {rule.fromPath}
          </div>
        )}
      </InspectorPaneHeader>

      <InspectorPaneBody>
        {clientError && (
          <div className="px-4 pt-3.5">
            <p
              className="rounded-[7px] bg-[var(--err-l)] px-3 py-2 text-[12px] text-[var(--err)]"
              role="alert"
            >
              {clientError}
            </p>
          </div>
        )}

        <InspectorPaneSection title="Rule">
          <div className="mb-3">
            <label className={labelCls} htmlFor="redir-type">
              Status code
            </label>
            <select
              id="redir-type"
              className={inputCls}
              value={form.type}
              onChange={(e) => update({ type: Number(e.target.value) as RedirectStatusCode })}
            >
              {STATUS_CODES.map((s) => (
                <option key={s.value} value={s.value}>
                  {s.label}
                </option>
              ))}
            </select>
          </div>

          <div className="mb-3">
            <label className={labelCls} htmlFor="redir-from">
              Source path
            </label>
            <input
              id="redir-from"
              className={inputCls}
              value={form.fromPath}
              onChange={(e) => update({ fromPath: e.target.value })}
              placeholder="/old-path"
            />
          </div>

          {!isGone && (
            <div className="mb-3 last:mb-0">
              <label className={labelCls} htmlFor="redir-to">
                Destination
              </label>
              <input
                id="redir-to"
                className={inputCls}
                value={form.toPath}
                onChange={(e) => update({ toPath: e.target.value })}
                placeholder="/new-path or https://example.com/page"
              />
            </div>
          )}
        </InspectorPaneSection>

        <InspectorPaneSection title="Options">
          <PaneToggleRow
            label="Enabled"
            checked={!!form.enabled}
            onCheckedChange={(v) => update({ enabled: v })}
            variant="enabled"
          />
          {!isGone && (
            <PaneToggleRow
              label="Preserve query string"
              hint="Append the original query params to the destination."
              checked={!!form.preserveQuery}
              onCheckedChange={(v) => update({ preserveQuery: v })}
            />
          )}
          <div className="mt-2">
            <label className={labelCls} htmlFor="redir-notes">
              Notes <span className="font-normal text-[var(--muted)]">(optional)</span>
            </label>
            <input
              id="redir-notes"
              className={inputCls}
              value={form.notes ?? ''}
              onChange={(e) => update({ notes: e.target.value })}
              placeholder="Why this redirect exists"
            />
          </div>
        </InspectorPaneSection>
      </InspectorPaneBody>

      <InspectorPaneFooter>
        <div className="flex items-center gap-2">
          {rule && onDelete && (
            <button
              type="button"
              onClick={() => onDelete(rule)}
              disabled={saving}
              aria-label={`Delete redirect ${rule.fromPath}`}
              className="flex h-9 w-9 shrink-0 items-center justify-center rounded-[7px] border border-[var(--bdr)] text-[var(--err)] transition-colors duration-[var(--motion-fast)] hover:bg-[var(--err-l)] focus-visible:ring-2 focus-visible:ring-[var(--ring)] focus-visible:outline-none disabled:opacity-50"
            >
              <Trash2 size={16} aria-hidden />
            </button>
          )}
          <button
            type="button"
            onClick={() => void handleSave()}
            disabled={saving}
            className="bg-primary text-primary-foreground min-w-0 flex-1 rounded-[7px] px-3 py-2 text-[13px] font-semibold transition-colors duration-[var(--motion-fast)] hover:opacity-90 focus-visible:ring-2 focus-visible:ring-[var(--ring)] focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50"
          >
            {saving ? 'Saving…' : rule ? 'Save changes' : 'Create redirect'}
          </button>
        </div>
      </InspectorPaneFooter>
    </>
  )
}
