import { useMemo, useState } from 'react'
import { motion, AnimatePresence } from 'framer-motion'
import { Plus, Trash2, ChevronUp, ChevronDown } from '../../lib/icons'
import { useOverrideRules, type OverrideRule } from '../../stores/override-rules-store'
import { useArrInstances } from '../../stores/arr-instances-store'
import { useArrProfiles, useArrRootFolders } from '../../hooks/use-arr'
import Select, { type SelectOption } from '../ui/Select'

const COMMON_GENRES = [
  'Action', 'Adventure', 'Animation', 'Anime', 'Comedy', 'Crime',
  'Documentary', 'Drama', 'Family', 'Fantasy', 'History', 'Horror',
  'Music', 'Mystery', 'Romance', 'Science Fiction', 'Thriller', 'War', 'Western',
]

const COMMON_LANGS = ['en', 'ja', 'ko', 'fr', 'es', 'it', 'de', 'zh', 'ru', 'pt', 'tr', 'ar']

/**
 * UI for the override-rules store. Lists existing rules with reorder /
 * delete affordances; expanding a row shows the editor inline. The
 * "Add rule" button creates a permissive default the user can refine.
 */
export default function OverrideRulesEditor() {
  const rules = useOverrideRules(s => s.rules)
  const add = useOverrideRules(s => s.add)
  const update = useOverrideRules(s => s.update)
  const remove = useOverrideRules(s => s.remove)
  const reorder = useOverrideRules(s => s.reorder)
  const [editing, setEditing] = useState<string | null>(null)

  function newRule() {
    const created = add({
      name: 'Untitled rule',
      kind: 'any',
      genres: [],
      languages: [],
      keywordIds: [],
      enabled: true,
    })
    setEditing(created.id)
  }

  return (
    <div className="space-y-3">
      <div className="flex items-center justify-between">
        <p className="text-[12.5px] text-text-3 leading-relaxed max-w-md">
          Rules evaluate top-to-bottom; the first match wins. Use them to route Anime to a different Sonarr instance, or 4K-only requests to a different root folder.
        </p>
        <button
          onClick={newRule}
          className="inline-flex items-center gap-1.5 h-8 px-3 rounded-full bg-accent text-void text-[12px] font-semibold tracking-tight hover:bg-accent-hover transition focus-ring shrink-0"
        >
          <Plus size={11} stroke={2.25} />
          Add rule
        </button>
      </div>

      {rules.length === 0 ? (
        <p className="text-[12px] text-text-4 italic py-4">No rules yet - requests will use each instance's defaults.</p>
      ) : (
        <ol className="space-y-2">
          {rules.map((rule, i) => (
            <RuleCard
              key={rule.id}
              rule={rule}
              expanded={editing === rule.id}
              isFirst={i === 0}
              isLast={i === rules.length - 1}
              onToggle={() => setEditing(editing === rule.id ? null : rule.id)}
              onChange={patch => update(rule.id, patch)}
              onRemove={() => {
                if (confirm(`Delete rule "${rule.name}"?`)) remove(rule.id)
              }}
              onMove={dir => reorder(rule.id, dir)}
            />
          ))}
        </ol>
      )}
    </div>
  )
}

function RuleCard({
  rule,
  expanded,
  isFirst,
  isLast,
  onToggle,
  onChange,
  onRemove,
  onMove,
}: {
  rule: OverrideRule
  expanded: boolean
  isFirst: boolean
  isLast: boolean
  onToggle: () => void
  onChange: (patch: Partial<OverrideRule>) => void
  onRemove: () => void
  onMove: (dir: -1 | 1) => void
}) {
  const instances = useArrInstances(s => s.instances)
  // Pick the instance the rule's tier + kind would route to so we can
  // populate profile / root folder dropdowns from a real source.
  const targetInstance = useMemo(() => {
    if (rule.kind === 'movie') {
      return instances.find(i => i.kind === 'radarr' && i.tier === (rule.tier || 'default')) || null
    }
    if (rule.kind === 'tv') {
      return instances.find(i => i.kind === 'sonarr' && i.tier === (rule.tier || 'default')) || null
    }
    // For 'any', prefer Radarr default (the override fields apply to
    // whichever kind the request is - we just need an instance to list
    // valid choices from).
    return instances.find(i => i.tier === (rule.tier || 'default')) || instances[0] || null
  }, [instances, rule.kind, rule.tier])
  const profiles = useArrProfiles(targetInstance)
  const rootFolders = useArrRootFolders(targetInstance)
  return (
    <li className="rounded-lg bg-elevated/40 ring-1 ring-border overflow-hidden">
      <div className="flex items-center gap-2 px-3 py-2">
        <input
          type="checkbox"
          checked={rule.enabled}
          onChange={e => onChange({ enabled: e.target.checked })}
          className="accent-amber-500"
          aria-label="Rule enabled"
        />
        <button
          onClick={onToggle}
          className="flex-1 text-left min-w-0 focus-ring rounded"
        >
          <p className="text-[13px] font-medium text-text-1 truncate tracking-tight">{rule.name}</p>
          <p className="text-[11px] text-text-3 truncate tabular-nums">
            {summarise(rule)}
          </p>
        </button>
        <button
          onClick={() => onMove(-1)}
          disabled={isFirst}
          className="w-7 h-7 grid place-items-center rounded text-text-4 hover:text-text-1 disabled:opacity-30 transition"
          aria-label="Move up"
        >
          <ChevronUp size={12} stroke={2} />
        </button>
        <button
          onClick={() => onMove(1)}
          disabled={isLast}
          className="w-7 h-7 grid place-items-center rounded text-text-4 hover:text-text-1 disabled:opacity-30 transition"
          aria-label="Move down"
        >
          <ChevronDown size={12} stroke={2} />
        </button>
        <button
          onClick={onRemove}
          className="w-7 h-7 grid place-items-center rounded text-text-4 hover:text-red-300 transition"
          aria-label="Delete rule"
        >
          <Trash2 size={11} stroke={2} />
        </button>
      </div>

      <AnimatePresence>
        {expanded && (
          <motion.div
            initial={{ height: 0, opacity: 0 }}
            animate={{ height: 'auto', opacity: 1 }}
            exit={{ height: 0, opacity: 0 }}
            transition={{ duration: 0.22, ease: [0.16, 1, 0.3, 1] }}
            className="overflow-hidden border-t border-border/50"
          >
            <div className="p-4 space-y-4 text-[13px]">
              <Field label="Name">
                <input
                  type="text"
                  value={rule.name}
                  onChange={e => onChange({ name: e.target.value })}
                  className="w-full h-9 px-3 rounded-md bg-void/40 ring-1 ring-border focus:ring-accent/50 outline-none text-[12.5px] tracking-tight"
                />
              </Field>

              <Field label="Applies to">
                <Segmented
                  value={rule.kind}
                  onChange={v => onChange({ kind: v })}
                  options={[
                    { value: 'any', label: 'Any' },
                    { value: 'movie', label: 'Movies' },
                    { value: 'tv', label: 'Shows' },
                  ]}
                />
              </Field>

              <Field label="Genres" hint="Match if any of these genre names is present (empty = match any)">
                <div className="flex flex-wrap gap-1.5">
                  {COMMON_GENRES.map(g => {
                    const on = rule.genres.includes(g)
                    return (
                      <button
                        key={g}
                        onClick={() =>
                          onChange({
                            genres: on
                              ? rule.genres.filter(x => x !== g)
                              : [...rule.genres, g],
                          })
                        }
                        className={`h-7 px-2.5 rounded-full text-[11px] tracking-tight transition border ${
                          on
                            ? 'bg-accent/15 text-accent border-accent/40'
                            : 'bg-elevated/40 text-text-2 border-border hover:border-border-strong'
                        }`}
                      >
                        {g}
                      </button>
                    )
                  })}
                </div>
              </Field>

              <Field label="Original language" hint="ISO 639-1 codes - empty matches any">
                <div className="flex flex-wrap gap-1.5">
                  {COMMON_LANGS.map(l => {
                    const on = rule.languages.includes(l)
                    return (
                      <button
                        key={l}
                        onClick={() =>
                          onChange({
                            languages: on
                              ? rule.languages.filter(x => x !== l)
                              : [...rule.languages, l],
                          })
                        }
                        className={`h-7 px-2.5 rounded-full text-[11px] uppercase tracking-[0.08em] font-medium transition border ${
                          on
                            ? 'bg-accent/15 text-accent border-accent/40'
                            : 'bg-elevated/40 text-text-2 border-border hover:border-border-strong'
                        }`}
                      >
                        {l}
                      </button>
                    )
                  })}
                </div>
              </Field>

              <Field label="Year range">
                <div className="flex items-center gap-2 max-w-xs">
                  <input
                    type="number"
                    value={rule.yearMin ?? ''}
                    onChange={e => onChange({ yearMin: e.target.value ? Number(e.target.value) : undefined })}
                    placeholder="From"
                    className="flex-1 h-9 px-3 rounded-md bg-void/40 ring-1 ring-border focus:ring-accent/50 outline-none tabular-nums text-[12.5px]"
                  />
                  <span className="text-text-4">→</span>
                  <input
                    type="number"
                    value={rule.yearMax ?? ''}
                    onChange={e => onChange({ yearMax: e.target.value ? Number(e.target.value) : undefined })}
                    placeholder="To"
                    className="flex-1 h-9 px-3 rounded-md bg-void/40 ring-1 ring-border focus:ring-accent/50 outline-none tabular-nums text-[12.5px]"
                  />
                </div>
              </Field>

              <div className="pt-2 border-t border-border/40 space-y-3">
                <p className="text-[10.5px] uppercase tracking-[0.16em] font-semibold text-text-3">
                  When matched, override:
                </p>
                <Field label="Tier">
                  <Segmented
                    value={rule.tier || 'inherit'}
                    onChange={v => onChange({ tier: v === 'inherit' ? undefined : (v as 'default' | '4k') })}
                    options={[
                      { value: 'inherit', label: 'Inherit' },
                      { value: 'default', label: 'Regular' },
                      { value: '4k', label: '4K' },
                    ]}
                  />
                </Field>
                {!targetInstance && (
                  <p className="text-[11px] text-amber-200 bg-amber-500/8 ring-1 ring-amber-400/25 rounded-md px-3 py-2 leading-relaxed">
                    Connect a {rule.kind === 'tv' ? 'Sonarr' : rule.kind === 'movie' ? 'Radarr' : 'Sonarr or Radarr'} instance to pick a profile or folder. Until then this rule will inherit the instance defaults.
                  </p>
                )}
                <Field label="Quality profile">
                  <Select
                    ariaLabel="Quality profile override"
                    width="w-full"
                    value={rule.qualityProfileId != null ? String(rule.qualityProfileId) : ''}
                    onChange={v => onChange({ qualityProfileId: v ? Number(v) : undefined })}
                    placeholder="Inherit from instance"
                    disabled={!targetInstance || !profiles.data}
                    options={[
                      { value: '', label: 'Inherit from instance', muted: true } as SelectOption<string>,
                      ...((profiles.data || []).map<SelectOption<string>>((p: any) => ({
                        value: String(p.id),
                        label: p.name,
                      }))),
                    ]}
                  />
                </Field>
                <Field label="Root folder">
                  <Select
                    ariaLabel="Root folder override"
                    width="w-full"
                    value={rule.rootFolderPath ?? ''}
                    onChange={v => onChange({ rootFolderPath: v || undefined })}
                    placeholder="Inherit from instance"
                    disabled={!targetInstance || !rootFolders.data}
                    options={[
                      { value: '', label: 'Inherit from instance', muted: true } as SelectOption<string>,
                      ...((rootFolders.data || []).map<SelectOption<string>>((r: any) => ({
                        value: r.path,
                        label: <span className="font-mono">{r.path}</span>,
                      }))),
                    ]}
                  />
                </Field>
              </div>
            </div>
          </motion.div>
        )}
      </AnimatePresence>
    </li>
  )
}

function Field({ label, hint, children }: { label: string; hint?: string; children: React.ReactNode }) {
  return (
    <div>
      <label className="block text-[10.5px] uppercase tracking-[0.16em] font-semibold text-text-3 mb-1.5">
        {label}
      </label>
      {children}
      {hint && <p className="text-[11px] text-text-4 mt-1.5 leading-relaxed">{hint}</p>}
    </div>
  )
}

function Segmented<T extends string>({
  value,
  onChange,
  options,
}: {
  value: T
  onChange: (v: T) => void
  options: { value: T; label: string }[]
}) {
  return (
    <div className="inline-flex bg-elevated/40 ring-1 ring-border rounded-md p-0.5">
      {options.map(o => (
        <button
          key={o.value}
          onClick={() => onChange(o.value)}
          className={`h-8 px-3 rounded text-[11.5px] font-medium tracking-tight transition focus-ring ${
            value === o.value ? 'bg-accent text-void' : 'text-text-3 hover:text-text-1'
          }`}
        >
          {o.label}
        </button>
      ))}
    </div>
  )
}

function summarise(rule: OverrideRule): string {
  const parts: string[] = []
  if (rule.kind !== 'any') parts.push(rule.kind === 'movie' ? 'Movies' : 'Shows')
  if (rule.genres.length > 0) parts.push(rule.genres.slice(0, 3).join(', '))
  if (rule.languages.length > 0) parts.push(rule.languages.join(' / ').toUpperCase())
  if (rule.yearMin != null || rule.yearMax != null) parts.push(`${rule.yearMin ?? '...'}-${rule.yearMax ?? '...'}`)
  if (rule.tier) parts.push(`→ ${rule.tier === '4k' ? '4K tier' : 'Regular tier'}`)
  if (rule.qualityProfileId) parts.push(`profile ${rule.qualityProfileId}`)
  return parts.length > 0 ? parts.join(' · ') : 'Matches everything'
}
