'use client'

import * as Dialog from '@radix-ui/react-dialog'
import { adminPortalContainer } from '../lib/portal-container.js'
import {
  Pencil,
  Plus,
  Trash2,
  Search,
  ArrowUpDown,
  ArrowUp,
  ArrowDown,
  ArrowRightLeft,
  Loader2,
  AlertTriangle,
} from 'lucide-react'
import { useState, useMemo, type FormEvent } from 'react'
import { toast } from 'sonner'
import { sortByRelevance, type SortConfig, toggleSort } from '../lib/search.js'
import { useApiData } from '../lib/useApiData.js'
import { cmsApi } from '../lib/api.js'

type RedirectSortKey = 'from' | 'to' | 'type' | 'hits' | 'active'

export interface RedirectsProps {
  onNavigate?: (path: string) => void
}

export function Redirects({ onNavigate }: RedirectsProps) {
  const { data, loading, error, refetch } = useApiData<any[]>('/redirects')
  const [showAddDialog, setShowAddDialog] = useState(false)
  const [newRedirect, setNewRedirect] = useState({
    source: '',
    destination: '',
    type: '301' as '301' | '302',
  })
  const [searchQuery, setSearchQuery] = useState('')
  const [filterType, setFilterType] = useState('all')
  const [sortConfig, setSortConfig] = useState<SortConfig<RedirectSortKey> | null>(null)

  const redirects = data ?? []

  const filteredAndSorted = useMemo(() => {
    let results = redirects.filter((r) => {
      const matchesSearch =
        (r.from ?? '').toLowerCase().includes(searchQuery.toLowerCase()) ||
        (r.to ?? '').toLowerCase().includes(searchQuery.toLowerCase())
      const matchesType = filterType === 'all' || r.type === filterType
      return matchesSearch && matchesType
    })

    if (searchQuery.trim()) {
      results = sortByRelevance(results, searchQuery, (r) => [r.from, r.to])
    } else if (sortConfig) {
      results = [...results].sort((a, b) => {
        let cmp: number
        if (sortConfig.key === 'hits') {
          cmp = a.hits - b.hits
        } else if (sortConfig.key === 'active') {
          cmp = Number(a.active) - Number(b.active)
        } else {
          cmp = String(a[sortConfig.key]).localeCompare(String(b[sortConfig.key]))
        }
        return sortConfig.direction === 'asc' ? cmp : -cmp
      })
    }
    return results
  }, [redirects, searchQuery, filterType, sortConfig])

  const handleSubmit = async (e: FormEvent) => {
    e.preventDefault()
    const res = await cmsApi('/redirects', {
      method: 'POST',
      body: JSON.stringify({
        from: newRedirect.source,
        to: newRedirect.destination,
        type: newRedirect.type,
      }),
    })
    if (res.error) {
      toast.error(res.error)
    } else {
      toast.success('Redirect added')
      refetch()
    }
    setShowAddDialog(false)
  }

  const handleDelete = async (id: number) => {
    const res = await cmsApi(`/redirects/${id}`, { method: 'DELETE' })
    if (res.error) {
      toast.error(res.error)
    } else {
      toast.success('Redirect deleted')
      refetch()
    }
  }

  function SortHeader({ label, sortKey }: { label: string; sortKey: RedirectSortKey }) {
    const active = sortConfig?.key === sortKey
    return (
      <button
        type="button"
        onClick={() => setSortConfig(toggleSort(sortConfig, sortKey))}
        className="text-foreground hover:text-foreground flex items-center gap-1 text-xs font-medium transition-colors"
      >
        {label}
        {active ? (
          sortConfig!.direction === 'asc' ? (
            <ArrowUp className="h-3 w-3" />
          ) : (
            <ArrowDown className="h-3 w-3" />
          )
        ) : (
          <ArrowUpDown className="text-muted-foreground h-3 w-3" />
        )}
      </button>
    )
  }

  if (loading) {
    return (
      <div className="flex h-64 items-center justify-center p-3 pr-6 sm:p-4 sm:pr-8">
        <Loader2 className="text-primary h-6 w-6 animate-spin" />
      </div>
    )
  }

  return (
    <div className="p-3 pr-6 sm:p-4 sm:pr-8">
      {error && (
        <div className="border-destructive/30 bg-destructive/10 mb-4 flex items-center gap-3 rounded-lg border p-3">
          <AlertTriangle className="text-destructive h-5 w-5 shrink-0" />
          <span className="text-destructive flex-1 text-sm">{error}</span>
          <button
            onClick={refetch}
            className="border-destructive/40 text-destructive hover:bg-destructive/15 rounded-lg border px-3 py-1 text-sm transition-colors"
          >
            Retry
          </button>
        </div>
      )}

      <div className="mb-4 flex items-center justify-between">
        <div>
          <h1 className="text-foreground mb-1 text-xl font-medium sm:text-2xl">Redirects</h1>
          <p className="text-muted-foreground text-sm">
            {filteredAndSorted.length} total redirects
          </p>
        </div>
        <button
          type="button"
          onClick={() => setShowAddDialog(true)}
          className="bg-primary text-primary-foreground hover:bg-primary/90 flex items-center gap-2 rounded-lg px-4 py-2 text-sm transition-colors"
        >
          <Plus className="h-4 w-4" />
          Add Redirect
        </button>
      </div>

      <div className="border-border bg-card mb-4 rounded-lg border">
        <div className="flex flex-col gap-3 p-3 sm:flex-row">
          <div className="relative flex-1">
            <Search className="text-muted-foreground absolute top-1/2 left-3 h-4 w-4 -translate-y-1/2" />
            <input
              type="text"
              placeholder="Search by source or destination URL..."
              value={searchQuery}
              onChange={(e) => setSearchQuery(e.target.value)}
              className="border-input focus:ring-ring w-full rounded-lg border py-2 pr-3 pl-9 text-sm focus:ring-2 focus:outline-none"
            />
          </div>
          <select
            value={filterType}
            onChange={(e) => setFilterType(e.target.value)}
            className="border-input focus:ring-ring rounded-lg border px-3 py-2 text-sm focus:ring-2 focus:outline-none"
          >
            <option value="all">All Types</option>
            <option value="301">301 (Permanent)</option>
            <option value="302">302 (Temporary)</option>
          </select>
        </div>
      </div>

      {filteredAndSorted.length === 0 && !loading ? (
        <div className="flex flex-col items-center justify-center py-16 text-center">
          <div className="bg-muted mb-4 flex h-12 w-12 items-center justify-center rounded-full">
            <ArrowRightLeft className="text-muted-foreground h-6 w-6" />
          </div>
          <h3 className="text-foreground mb-1 text-sm font-medium">No redirects yet</h3>
          <p className="text-muted-foreground text-sm">Add your first redirect to get started.</p>
        </div>
      ) : (
        <div className="border-border bg-card rounded-lg border">
          <div className="overflow-x-auto">
            <table className="w-full">
              <thead className="border-border bg-muted border-b">
                <tr>
                  <th className="px-4 py-2 text-left">
                    <SortHeader label="Source URL" sortKey="from" />
                  </th>
                  <th className="px-4 py-2 text-left">
                    <SortHeader label="Destination URL" sortKey="to" />
                  </th>
                  <th className="px-4 py-2 text-left">
                    <SortHeader label="Type" sortKey="type" />
                  </th>
                  <th className="px-4 py-2 text-left">
                    <SortHeader label="Hits" sortKey="hits" />
                  </th>
                  <th className="px-4 py-2 text-left">
                    <SortHeader label="Status" sortKey="active" />
                  </th>
                  <th className="text-foreground px-4 py-2 text-left text-xs font-medium">
                    Actions
                  </th>
                </tr>
              </thead>
              <tbody className="divide-border divide-y">
                {filteredAndSorted.map((redirect) => (
                  <tr key={redirect.id} className="hover:bg-muted transition-colors">
                    <td className="px-4 py-3">
                      <code className="bg-muted text-foreground rounded px-2 py-1 text-xs">
                        {redirect.from}
                      </code>
                    </td>
                    <td className="px-4 py-3">
                      <code className="bg-muted text-foreground rounded px-2 py-1 text-xs">
                        {redirect.to}
                      </code>
                    </td>
                    <td className="px-4 py-3">
                      <span
                        className={`inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium ${
                          redirect.type === '301'
                            ? 'bg-primary/15 text-primary'
                            : 'bg-accent text-accent-foreground'
                        }`}
                      >
                        {redirect.type}
                      </span>
                    </td>
                    <td className="text-muted-foreground px-4 py-3 text-sm">
                      {redirect.hits.toLocaleString()}
                    </td>
                    <td className="px-4 py-3">
                      <span
                        className={`inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium ${
                          redirect.active
                            ? 'bg-success/15 text-success'
                            : 'bg-muted text-foreground'
                        }`}
                      >
                        {redirect.active ? 'Active' : 'Inactive'}
                      </span>
                    </td>
                    <td className="px-4 py-3">
                      <div className="flex items-center gap-2">
                        <button
                          type="button"
                          onClick={() => onNavigate?.(`/redirects/${redirect.id}/edit`)}
                          className="hover:bg-muted rounded p-1.5 transition-colors"
                          aria-label="Edit redirect"
                        >
                          <Pencil className="text-muted-foreground h-4 w-4" />
                        </button>
                        <button
                          type="button"
                          onClick={() => handleDelete(redirect.id)}
                          className="hover:bg-muted rounded p-1.5 transition-colors"
                          aria-label="Delete redirect"
                        >
                          <Trash2 className="text-destructive h-4 w-4" />
                        </button>
                      </div>
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        </div>
      )}

      <Dialog.Root open={showAddDialog} onOpenChange={setShowAddDialog}>
        <Dialog.Portal container={adminPortalContainer()}>
          <Dialog.Overlay className="fixed inset-0 z-50 bg-black/50" />
          <Dialog.Content className="bg-card fixed top-1/2 left-1/2 z-50 w-full max-w-md -translate-x-1/2 -translate-y-1/2 rounded-lg p-6 shadow-lg">
            <Dialog.Title className="text-foreground mb-4 text-lg font-medium">
              Add Redirect
            </Dialog.Title>
            <form onSubmit={handleSubmit} className="space-y-4">
              <div>
                <label className="text-foreground mb-1 block text-sm font-medium">Source URL</label>
                <input
                  type="text"
                  value={newRedirect.source}
                  onChange={(e) => setNewRedirect({ ...newRedirect, source: e.target.value })}
                  placeholder="/old-page"
                  className="border-input focus:ring-ring w-full rounded-lg border px-3 py-2 text-sm focus:ring-2 focus:outline-none"
                  required
                />
              </div>
              <div>
                <label className="text-foreground mb-1 block text-sm font-medium">
                  Destination URL
                </label>
                <input
                  type="text"
                  value={newRedirect.destination}
                  onChange={(e) => setNewRedirect({ ...newRedirect, destination: e.target.value })}
                  placeholder="/new-page"
                  className="border-input focus:ring-ring w-full rounded-lg border px-3 py-2 text-sm focus:ring-2 focus:outline-none"
                  required
                />
              </div>
              <div>
                <label className="text-foreground mb-1 block text-sm font-medium">
                  Redirect Type
                </label>
                <select
                  value={newRedirect.type}
                  onChange={(e) =>
                    setNewRedirect({ ...newRedirect, type: e.target.value as '301' | '302' })
                  }
                  className="border-input focus:ring-ring w-full rounded-lg border px-3 py-2 text-sm focus:ring-2 focus:outline-none"
                >
                  <option value="301">301 (Permanent)</option>
                  <option value="302">302 (Temporary)</option>
                </select>
              </div>
              <div className="flex items-center justify-end gap-3 pt-4">
                <Dialog.Close asChild>
                  <button
                    type="button"
                    className="border-input hover:bg-muted rounded-lg border px-4 py-2 text-sm transition-colors"
                  >
                    Cancel
                  </button>
                </Dialog.Close>
                <button
                  type="submit"
                  className="bg-primary text-primary-foreground hover:bg-primary/90 rounded-lg px-4 py-2 text-sm transition-colors"
                >
                  Add Redirect
                </button>
              </div>
            </form>
          </Dialog.Content>
        </Dialog.Portal>
      </Dialog.Root>
    </div>
  )
}
