import { useState, useEffect, useCallback, useRef } from 'react'
import { ExternalLink, Star, Search } from 'lucide-react'
import { Button } from '@/components/ui/Button'
import { PageHeader } from '@/components/admin'
import { adminApi } from '@/api/admin'
import type { GalleryFlowItem, GalleryScriptItem } from '@/api/admin'
import { toast } from '@/lib/toast'
import { cn } from '@/lib/utils'

// ---------------------------------------------------------------------------
// Toggle switch component
// ---------------------------------------------------------------------------

function ToggleSwitch({
  checked,
  onChange,
  disabled,
}: {
  checked: boolean
  onChange: (value: boolean) => void
  disabled?: boolean
}) {
  return (
    <button
      type="button"
      role="switch"
      aria-checked={checked}
      disabled={disabled}
      onClick={() => onChange(!checked)}
      className={cn(
        'relative inline-flex h-5 w-9 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors duration-200',
        'focus:outline-none focus:ring-2 focus:ring-primary/40 focus:ring-offset-2 focus:ring-offset-background',
        checked ? 'bg-primary' : 'bg-[rgba(255,255,255,0.1)]',
        disabled && 'cursor-not-allowed opacity-50',
      )}
    >
      <span
        className={cn(
          'pointer-events-none inline-block h-4 w-4 transform rounded-full bg-white shadow-lg ring-0 transition duration-200',
          checked ? 'translate-x-4' : 'translate-x-0',
        )}
      />
    </button>
  )
}

// ---------------------------------------------------------------------------
// Sort order input
// ---------------------------------------------------------------------------

function SortOrderInput({
  value,
  onSave,
  disabled,
}: {
  value: number
  onSave: (v: number) => void
  disabled?: boolean
}) {
  const [local, setLocal] = useState(String(value))
  const ref = useRef<HTMLInputElement>(null)

  // Sync if external value changes
  useEffect(() => {
    setLocal(String(value))
  }, [value])

  const commit = () => {
    const parsed = parseInt(local, 10)
    if (!isNaN(parsed) && parsed !== value) {
      onSave(parsed)
    } else {
      setLocal(String(value)) // revert invalid input
    }
  }

  return (
    <input
      ref={ref}
      type="number"
      value={local}
      disabled={disabled}
      onChange={e => setLocal(e.target.value)}
      onBlur={commit}
      onKeyDown={e => {
        if (e.key === 'Enter') {
          commit()
          ref.current?.blur()
        }
      }}
      className={cn(
        'w-20 rounded-[8px] border border-border bg-card px-2 py-1 text-sm text-foreground',
        'focus:border-[rgba(96,165,250,0.3)] focus:outline-none',
        disabled && 'cursor-not-allowed opacity-50',
      )}
    />
  )
}

// ---------------------------------------------------------------------------
// Filter bar
// ---------------------------------------------------------------------------

type FilterMode = 'all' | 'featured' | 'unfeatured'

function FilterBar({
  search,
  onSearchChange,
  filter,
  onFilterChange,
}: {
  search: string
  onSearchChange: (v: string) => void
  filter: FilterMode
  onFilterChange: (v: FilterMode) => void
}) {
  return (
    <div className="flex flex-wrap items-center gap-3">
      <div className="relative flex-1 min-w-[180px] max-w-xs">
        <Search className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground pointer-events-none" />
        <input
          type="text"
          placeholder="Search by name…"
          value={search}
          onChange={e => onSearchChange(e.target.value)}
          className={cn(
            'w-full rounded-lg border border-border bg-card pl-9 pr-3 py-2 text-sm text-foreground placeholder:text-muted-foreground',
            'focus:border-[rgba(96,165,250,0.3)] focus:outline-none',
          )}
        />
      </div>
      <div className="flex rounded-lg border border-border overflow-hidden text-sm">
        {(['all', 'featured', 'unfeatured'] as FilterMode[]).map(mode => (
          <button
            key={mode}
            onClick={() => onFilterChange(mode)}
            className={cn(
              'px-3 py-1.5 capitalize transition-colors',
              filter === mode
                ? 'bg-primary text-white font-semibold'
                : 'text-muted-foreground hover:text-foreground bg-card',
            )}
          >
            {mode}
          </button>
        ))}
      </div>
    </div>
  )
}

// ---------------------------------------------------------------------------
// Flows table
// ---------------------------------------------------------------------------

function FlowsTable({
  flows,
  onToggleFeatured,
  onSortOrder,
  toggling,
}: {
  flows: GalleryFlowItem[]
  onToggleFeatured: (id: string, value: boolean) => void
  onSortOrder: (id: string, value: number) => void
  toggling: Set<string>
}) {
  if (flows.length === 0) {
    return (
      <p className="py-8 text-center text-sm text-muted-foreground">No flows match the current filter.</p>
    )
  }

  return (
    <div className="overflow-x-auto">
      <table className="w-full text-sm">
        <thead>
          <tr className="border-b border-border text-left">
            <th className="pb-3 pr-4 font-sans text-xs text-[0.625rem] uppercase tracking-[0.1em] text-muted-foreground">Name</th>
            <th className="pb-3 pr-4 font-sans text-xs text-[0.625rem] uppercase tracking-[0.1em] text-muted-foreground">Type</th>
            <th className="pb-3 pr-4 font-sans text-xs text-[0.625rem] uppercase tracking-[0.1em] text-muted-foreground">Featured</th>
            <th className="pb-3 font-sans text-xs text-[0.625rem] uppercase tracking-[0.1em] text-muted-foreground">Sort Order</th>
          </tr>
        </thead>
        <tbody className="divide-y divide-border">
          {flows.map(flow => (
            <tr key={flow.id} className="group hover:bg-[rgba(255,255,255,0.02)] transition-colors">
              <td className="py-3 pr-4 text-foreground font-medium">{flow.name}</td>
              <td className="py-3 pr-4">
                <span className="font-sans text-xs text-[0.625rem] uppercase tracking-[0.1em] rounded-full px-2 py-0.5 border border-border text-muted-foreground">
                  {flow.tree_type}
                </span>
              </td>
              <td className="py-3 pr-4">
                <div className="flex items-center gap-2">
                  <ToggleSwitch
                    checked={flow.is_gallery_featured}
                    onChange={v => onToggleFeatured(flow.id, v)}
                    disabled={toggling.has(flow.id)}
                  />
                  {flow.is_gallery_featured && (
                    <Star className="h-3 w-3 text-amber-400 fill-amber-400" />
                  )}
                </div>
              </td>
              <td className="py-3">
                <SortOrderInput
                  value={flow.gallery_sort_order}
                  onSave={v => onSortOrder(flow.id, v)}
                  disabled={toggling.has(flow.id)}
                />
              </td>
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  )
}

// ---------------------------------------------------------------------------
// Scripts table
// ---------------------------------------------------------------------------

function ScriptsTable({
  scripts,
  onToggleFeatured,
  onSortOrder,
  toggling,
}: {
  scripts: GalleryScriptItem[]
  onToggleFeatured: (id: string, value: boolean) => void
  onSortOrder: (id: string, value: number) => void
  toggling: Set<string>
}) {
  if (scripts.length === 0) {
    return (
      <p className="py-8 text-center text-sm text-muted-foreground">No scripts match the current filter.</p>
    )
  }

  return (
    <div className="overflow-x-auto">
      <table className="w-full text-sm">
        <thead>
          <tr className="border-b border-border text-left">
            <th className="pb-3 pr-4 font-sans text-xs text-[0.625rem] uppercase tracking-[0.1em] text-muted-foreground">Name</th>
            <th className="pb-3 pr-4 font-sans text-xs text-[0.625rem] uppercase tracking-[0.1em] text-muted-foreground">Status</th>
            <th className="pb-3 pr-4 font-sans text-xs text-[0.625rem] uppercase tracking-[0.1em] text-muted-foreground">Featured</th>
            <th className="pb-3 font-sans text-xs text-[0.625rem] uppercase tracking-[0.1em] text-muted-foreground">Sort Order</th>
          </tr>
        </thead>
        <tbody className="divide-y divide-border">
          {scripts.map(script => (
            <tr key={script.id} className="group hover:bg-[rgba(255,255,255,0.02)] transition-colors">
              <td className="py-3 pr-4 text-foreground font-medium">{script.name}</td>
              <td className="py-3 pr-4">
                <span
                  className={cn(
                    'font-sans text-xs text-[0.625rem] uppercase tracking-[0.1em] rounded-full px-2 py-0.5 border',
                    script.is_active
                      ? 'border-emerald-400/30 text-emerald-400 bg-emerald-400/10'
                      : 'border-border text-muted-foreground',
                  )}
                >
                  {script.is_active ? 'Active' : 'Inactive'}
                </span>
              </td>
              <td className="py-3 pr-4">
                <div className="flex items-center gap-2">
                  <ToggleSwitch
                    checked={script.is_gallery_featured}
                    onChange={v => onToggleFeatured(script.id, v)}
                    disabled={toggling.has(script.id)}
                  />
                  {script.is_gallery_featured && (
                    <Star className="h-3 w-3 text-amber-400 fill-amber-400" />
                  )}
                </div>
              </td>
              <td className="py-3">
                <SortOrderInput
                  value={script.gallery_sort_order}
                  onSave={v => onSortOrder(script.id, v)}
                  disabled={toggling.has(script.id)}
                />
              </td>
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  )
}

// ---------------------------------------------------------------------------
// Main page
// ---------------------------------------------------------------------------

export default function GalleryManagementPage() {
  const [flows, setFlows] = useState<GalleryFlowItem[]>([])
  const [scripts, setScripts] = useState<GalleryScriptItem[]>([])
  const [loading, setLoading] = useState(true)

  // Per-table filter state
  const [flowSearch, setFlowSearch] = useState('')
  const [flowFilter, setFlowFilter] = useState<FilterMode>('all')
  const [scriptSearch, setScriptSearch] = useState('')
  const [scriptFilter, setScriptFilter] = useState<FilterMode>('all')

  // Track in-flight requests per item
  const [toggling, setToggling] = useState<Set<string>>(new Set())

  const fetchData = useCallback(async () => {
    setLoading(true)
    try {
      const data = await adminApi.getGalleryAllItems()
      setFlows(data.flows)
      setScripts(data.scripts)
    } catch {
      toast.error('Failed to load gallery items')
    } finally {
      setLoading(false)
    }
  }, [])

  useEffect(() => { fetchData() }, [fetchData])

  // Flow actions
  const handleToggleFlow = async (id: string, value: boolean) => {
    setToggling(prev => new Set(prev).add(id))
    try {
      const updated = await adminApi.toggleFlowFeatured(id, value)
      setFlows(prev => prev.map(f => f.id === id ? { ...f, ...updated } : f))
      toast.success(value ? 'Flow added to gallery' : 'Flow removed from gallery')
    } catch {
      toast.error('Failed to update flow')
    } finally {
      setToggling(prev => { const s = new Set(prev); s.delete(id); return s })
    }
  }

  const handleFlowSortOrder = async (id: string, value: number) => {
    setToggling(prev => new Set(prev).add(id))
    try {
      const updated = await adminApi.updateFlowSortOrder(id, value)
      setFlows(prev => prev.map(f => f.id === id ? { ...f, ...updated } : f))
    } catch {
      toast.error('Failed to update sort order')
    } finally {
      setToggling(prev => { const s = new Set(prev); s.delete(id); return s })
    }
  }

  // Script actions
  const handleToggleScript = async (id: string, value: boolean) => {
    setToggling(prev => new Set(prev).add(id))
    try {
      const updated = await adminApi.toggleScriptFeatured(id, value)
      setScripts(prev => prev.map(s => s.id === id ? { ...s, ...updated } : s))
      toast.success(value ? 'Script added to gallery' : 'Script removed from gallery')
    } catch {
      toast.error('Failed to update script')
    } finally {
      setToggling(prev => { const s = new Set(prev); s.delete(id); return s })
    }
  }

  const handleScriptSortOrder = async (id: string, value: number) => {
    setToggling(prev => new Set(prev).add(id))
    try {
      const updated = await adminApi.updateScriptSortOrder(id, value)
      setScripts(prev => prev.map(s => s.id === id ? { ...s, ...updated } : s))
    } catch {
      toast.error('Failed to update sort order')
    } finally {
      setToggling(prev => { const s = new Set(prev); s.delete(id); return s })
    }
  }

  // Filtering
  const filteredFlows = flows.filter(f => {
    const matchesSearch = f.name.toLowerCase().includes(flowSearch.toLowerCase())
    const matchesFilter =
      flowFilter === 'all' ||
      (flowFilter === 'featured' && f.is_gallery_featured) ||
      (flowFilter === 'unfeatured' && !f.is_gallery_featured)
    return matchesSearch && matchesFilter
  })

  const filteredScripts = scripts.filter(s => {
    const matchesSearch = s.name.toLowerCase().includes(scriptSearch.toLowerCase())
    const matchesFilter =
      scriptFilter === 'all' ||
      (scriptFilter === 'featured' && s.is_gallery_featured) ||
      (scriptFilter === 'unfeatured' && !s.is_gallery_featured)
    return matchesSearch && matchesFilter
  })

  const featuredFlowCount = flows.filter(f => f.is_gallery_featured).length
  const featuredScriptCount = scripts.filter(s => s.is_gallery_featured).length

  return (
    <div className="space-y-8">
      <PageHeader
        title="Gallery Management"
        description="Control which flows and scripts appear in the public template gallery."
        action={
          <Button
            variant="secondary"
            size="sm"
            onClick={() => window.open('/templates', '_blank')}
          >
            <ExternalLink className="h-4 w-4 mr-1.5" />
            Preview Gallery
          </Button>
        }
      />

      {loading ? (
        <div className="flex items-center justify-center py-16 text-muted-foreground text-sm">
          Loading gallery items…
        </div>
      ) : (
        <div className="space-y-8">
          {/* Summary stats */}
          <div className="flex gap-4 flex-wrap">
            <div className="card-flat rounded-[12px] px-4 py-3 flex items-center gap-3">
              <Star className="h-4 w-4 text-amber-400 fill-amber-400" />
              <span className="text-sm text-muted-foreground">
                <span className="text-foreground font-semibold">{featuredFlowCount}</span> featured flow{featuredFlowCount !== 1 ? 's' : ''}
              </span>
            </div>
            <div className="card-flat rounded-[12px] px-4 py-3 flex items-center gap-3">
              <Star className="h-4 w-4 text-amber-400 fill-amber-400" />
              <span className="text-sm text-muted-foreground">
                <span className="text-foreground font-semibold">{featuredScriptCount}</span> featured script{featuredScriptCount !== 1 ? 's' : ''}
              </span>
            </div>
          </div>

          {/* Featured Flows section */}
          <section>
            <div className="mb-4 flex items-center justify-between gap-4 flex-wrap">
              <div>
                <h2 className="text-base font-semibold text-foreground">Featured Flows</h2>
                <p className="text-xs text-muted-foreground mt-0.5">
                  Toggle flows to show in the gallery. Lower sort order = shown first.
                </p>
              </div>
            </div>

            <div className="card-flat rounded-lg p-5 space-y-4">
              <FilterBar
                search={flowSearch}
                onSearchChange={setFlowSearch}
                filter={flowFilter}
                onFilterChange={setFlowFilter}
              />
              <FlowsTable
                flows={filteredFlows}
                onToggleFeatured={handleToggleFlow}
                onSortOrder={handleFlowSortOrder}
                toggling={toggling}
              />
            </div>
          </section>

          {/* Featured Scripts section */}
          <section>
            <div className="mb-4 flex items-center justify-between gap-4 flex-wrap">
              <div>
                <h2 className="text-base font-semibold text-foreground">Featured Scripts</h2>
                <p className="text-xs text-muted-foreground mt-0.5">
                  Toggle scripts to show in the gallery. Lower sort order = shown first.
                </p>
              </div>
            </div>

            <div className="card-flat rounded-lg p-5 space-y-4">
              <FilterBar
                search={scriptSearch}
                onSearchChange={setScriptSearch}
                filter={scriptFilter}
                onFilterChange={setScriptFilter}
              />
              <ScriptsTable
                scripts={filteredScripts}
                onToggleFeatured={handleToggleScript}
                onSortOrder={handleScriptSortOrder}
                toggling={toggling}
              />
            </div>
          </section>
        </div>
      )}
    </div>
  )
}
