import { useState, type ReactNode } from 'react'
import { AlertCircle, Check, Plus, Trash2 } from '../../../lib/icons'
import { Section, Row, SubHeading } from '../_ui'
import Select, { type SelectOption } from '../../../components/ui/Select'
import { useArrInstances, newArrInstance, type ArrInstance } from '../../../stores/arr-instances-store'
import { useArrSystemStatus, useArrProfiles, useArrRootFolders, useSonarrLanguageProfiles } from '../../../hooks/use-arr'
import OverrideRulesEditor from '../../../components/settings/OverrideRulesEditor'

export function ArrSection() {
  const instances = useArrInstances(s => s.instances)
  const upsert = useArrInstances(s => s.upsert)
  const remove = useArrInstances(s => s.remove)

  function ensure(kind: 'sonarr' | 'radarr', tier: 'default' | '4k') {
    const existing = instances.find(x => x.kind === kind && x.tier === tier)
    if (existing) return existing
    const fresh = newArrInstance(kind, tier)
    upsert(fresh)
    return fresh
  }

  const radarr = instances.find(x => x.kind === 'radarr' && x.tier === 'default')
  const radarr4k = instances.find(x => x.kind === 'radarr' && x.tier === '4k')
  const sonarr = instances.find(x => x.kind === 'sonarr' && x.tier === 'default')
  const sonarr4k = instances.find(x => x.kind === 'sonarr' && x.tier === '4k')

  return (
    <Section
      id="sonarr-radarr"
      title="Sonarr & Radarr"
      description="Connect to your *arr stack to request new movies and shows from inside the app"
    >
      <SubHeading label="Movies (Radarr)" />
      <ArrInstanceRow instance={radarr || null} kind="radarr" tier="default" onAdd={() => ensure('radarr', 'default')} onRemove={() => radarr && remove(radarr.id)} />
      <ArrInstanceRow instance={radarr4k || null} kind="radarr" tier="4k" onAdd={() => ensure('radarr', '4k')} onRemove={() => radarr4k && remove(radarr4k.id)} />

      <SubHeading label="Shows (Sonarr)" />
      <ArrInstanceRow instance={sonarr || null} kind="sonarr" tier="default" onAdd={() => ensure('sonarr', 'default')} onRemove={() => sonarr && remove(sonarr.id)} />
      <ArrInstanceRow instance={sonarr4k || null} kind="sonarr" tier="4k" onAdd={() => ensure('sonarr', '4k')} onRemove={() => sonarr4k && remove(sonarr4k.id)} />

      <SubHeading label="Override rules" />
      <div data-settings-row className="py-4">
        <OverrideRulesEditor />
      </div>
    </Section>
  )
}

function ArrInstanceRow({
  instance,
  kind,
  tier,
  onAdd,
  onRemove,
}: {
  instance: ArrInstance | null
  kind: 'sonarr' | 'radarr'
  tier: 'default' | '4k'
  onAdd: () => void
  onRemove: () => void
}) {
  const [expanded, setExpanded] = useState(false)
  const label = `${kind === 'radarr' ? 'Radarr' : 'Sonarr'}${tier === '4k' ? ' (4K)' : ''}`
  const hint = !instance
    ? `Not connected. Click + to set up the ${tier === '4k' ? '4K ' : ''}${kind === 'radarr' ? 'Radarr' : 'Sonarr'} instance.`
    : instance.lastTestVersion
      ? `Connected - v${instance.lastTestVersion}`
      : instance.baseUrl
        ? 'Configured but not yet tested'
        : 'Configured'

  return (
    <>
      <Row label={label} hint={hint}>
        {!instance ? (
          <button
            onClick={onAdd}
            className="inline-flex items-center gap-1.5 h-9 px-3 rounded-full bg-accent/10 ring-1 ring-accent/30 hover:bg-accent/15 hover:text-accent text-[11.5px] text-accent font-medium tracking-tight transition focus-ring"
          >
            <Plus size={11} stroke={2.25} />
            Add
          </button>
        ) : (
          <div className="flex items-center gap-1.5">
            <button
              onClick={() => setExpanded(v => !v)}
              className="h-9 px-3 rounded-full text-[11.5px] text-text-2 hover:text-text-1 hover:bg-elevated transition focus-ring"
            >
              {expanded ? 'Done' : 'Edit'}
            </button>
            <button
              onClick={() => {
                if (confirm(`Remove ${label}?`)) onRemove()
              }}
              className="h-9 w-9 grid place-items-center rounded-full text-text-4 hover:text-red-300 transition focus-ring"
            >
              <Trash2 size={12} stroke={2} />
            </button>
          </div>
        )}
      </Row>
      {instance && expanded && <ArrInstanceEditor instance={instance} />}
    </>
  )
}

function ArrInstanceEditor({ instance }: { instance: ArrInstance }) {
  const upsert = useArrInstances(s => s.upsert)
  const [draft, setDraft] = useState<ArrInstance>(instance)
  const [testing, setTesting] = useState(false)
  const [testResult, setTestResult] = useState<'ok' | 'fail' | null>(null)

  const status = useArrSystemStatus(testResult === 'ok' ? draft : null)
  const profiles = useArrProfiles(testResult === 'ok' ? draft : null)
  const rootFolders = useArrRootFolders(testResult === 'ok' ? draft : null)
  const langProfiles = useSonarrLanguageProfiles(testResult === 'ok' && draft.kind === 'sonarr' ? draft : null)

  function save(patch: Partial<ArrInstance>) {
    const next = { ...draft, ...patch }
    setDraft(next)
    upsert(next)
  }

  async function runTest() {
    if (!draft.baseUrl || !draft.apiKey) {
      setTestResult('fail')
      return
    }
    setTesting(true)
    try {
      const res = await fetch(
        `${draft.baseUrl.replace(/\/+$/, '')}/api/v3/system/status`,
        { headers: { 'X-Api-Key': draft.apiKey } },
      )
      if (!res.ok) {
        setTestResult('fail')
        save({ lastTestError: `HTTP ${res.status}`, lastTestVersion: undefined, lastTestedAt: new Date().toISOString() })
      } else {
        const data = await res.json()
        setTestResult('ok')
        save({
          lastTestVersion: data?.version,
          lastTestError: undefined,
          lastTestedAt: new Date().toISOString(),
        })
      }
    } catch (e) {
      setTestResult('fail')
      save({ lastTestError: String(e), lastTestVersion: undefined, lastTestedAt: new Date().toISOString() })
    } finally {
      setTesting(false)
    }
  }

  return (
    <div className="py-4 space-y-3 border-t border-border/50">
      <ArrField label="Base URL" hint='Including http(s):// and port, no trailing slash. e.g. "http://10.0.0.5:7878"'>
        <input
          type="url"
          value={draft.baseUrl}
          onChange={e => save({ baseUrl: e.target.value.trim() })}
          placeholder="http://localhost:7878"
          className="w-full h-9 px-3 rounded-md bg-elevated/60 ring-1 ring-border focus:ring-accent/50 outline-none text-[12.5px] tracking-tight font-mono"
        />
      </ArrField>
      <ArrField label="API key" hint="Settings - General - Security in Sonarr/Radarr">
        <input
          type="password"
          value={draft.apiKey}
          onChange={e => save({ apiKey: e.target.value.trim() })}
          placeholder="32-character key"
          className="w-full h-9 px-3 rounded-md bg-elevated/60 ring-1 ring-border focus:ring-accent/50 outline-none text-[12.5px] tracking-tight font-mono"
        />
      </ArrField>
      <ArrField label="Friendly name" hint="Optional - shown in the request modal">
        <input
          type="text"
          value={draft.name}
          onChange={e => save({ name: e.target.value })}
          className="w-full h-9 px-3 rounded-md bg-elevated/60 ring-1 ring-border focus:ring-accent/50 outline-none text-[12.5px] tracking-tight"
        />
      </ArrField>

      <div className="flex items-center gap-2 pt-1 flex-wrap">
        <button
          onClick={runTest}
          disabled={testing || !draft.baseUrl || !draft.apiKey}
          className="inline-flex items-center gap-1.5 h-9 px-4 rounded-full bg-accent text-void text-[12px] font-semibold tracking-tight transition disabled:opacity-40 disabled:cursor-not-allowed hover:bg-accent-hover focus-ring"
        >
          {testing ? 'Testing...' : 'Test connection'}
        </button>
        {testResult === 'ok' && (
          <span className="inline-flex items-center gap-1.5 h-8 px-2.5 rounded-full bg-success/12 ring-1 ring-success/30 text-[11.5px] text-success font-medium">
            <Check size={12} stroke={2.5} />
            Connected - v{status.data?.version || draft.lastTestVersion || '?'}
          </span>
        )}
        {testResult === 'fail' && (
          <span className="inline-flex items-center gap-1.5 h-8 px-2.5 rounded-full bg-red-500/10 ring-1 ring-red-500/30 text-[11.5px] text-red-200 font-medium max-w-xs truncate">
            <AlertCircle size={12} />
            {draft.lastTestError || 'Connection failed'}
          </span>
        )}
      </div>

      {testResult === 'ok' && (profiles.data || rootFolders.data) && (
        <div className="pt-3 space-y-3 border-t border-border/40">
          <ArrField label="Default quality profile">
            <Select
              ariaLabel="Default quality profile"
              width="w-full"
              value={draft.defaultQualityProfileId != null ? String(draft.defaultQualityProfileId) : ''}
              onChange={v => save({ defaultQualityProfileId: v ? Number(v) : undefined })}
              placeholder="Pick a profile"
              options={(profiles.data || []).map<SelectOption<string>>(p => ({
                value: String(p.id),
                label: p.name,
              }))}
            />
          </ArrField>
          <ArrField label="Default root folder">
            <Select
              ariaLabel="Default root folder"
              width="w-full"
              value={draft.defaultRootFolder ?? ''}
              onChange={v => save({ defaultRootFolder: v || undefined })}
              placeholder="Pick a folder"
              options={(rootFolders.data || []).map<SelectOption<string>>(r => ({
                value: r.path,
                label: <span className="font-mono">{r.path}</span>,
              }))}
            />
          </ArrField>
          {draft.kind === 'sonarr' && langProfiles.data && langProfiles.data.length > 0 && (
            <ArrField label="Default language profile">
              <Select
                ariaLabel="Default language profile"
                width="w-full"
                value={draft.defaultLanguageProfileId != null ? String(draft.defaultLanguageProfileId) : ''}
                onChange={v => save({ defaultLanguageProfileId: v ? Number(v) : undefined })}
                placeholder="Pick a profile"
                options={(langProfiles.data || []).map<SelectOption<string>>(p => ({
                  value: String(p.id),
                  label: p.name,
                }))}
              />
            </ArrField>
          )}
        </div>
      )}
    </div>
  )
}

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