'use client'

import * as Dialog from '@radix-ui/react-dialog'
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="flex items-center gap-1 text-xs font-medium text-gray-700 transition-colors hover:text-gray-900"
      >
        {label}
        {active ? (
          sortConfig!.direction === 'asc' ? (
            <ArrowUp className="h-3 w-3" />
          ) : (
            <ArrowDown className="h-3 w-3" />
          )
        ) : (
          <ArrowUpDown className="h-3 w-3 text-gray-400" />
        )}
      </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="h-6 w-6 animate-spin text-blue-600" />
      </div>
    )
  }

  return (
    <div className="p-3 pr-6 sm:p-4 sm:pr-8">
      {error && (
        <div className="mb-4 flex items-center gap-3 rounded-lg border border-red-200 bg-red-50 p-3">
          <AlertTriangle className="h-5 w-5 shrink-0 text-red-600" />
          <span className="flex-1 text-sm text-red-800">{error}</span>
          <button
            onClick={refetch}
            className="rounded-lg border border-red-300 px-3 py-1 text-sm text-red-700 transition-colors hover:bg-red-100"
          >
            Retry
          </button>
        </div>
      )}

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

      <div className="mb-4 rounded-lg border border-gray-200 bg-white">
        <div className="flex flex-col gap-3 p-3 sm:flex-row">
          <div className="relative flex-1">
            <Search className="absolute top-1/2 left-3 h-4 w-4 -translate-y-1/2 text-gray-400" />
            <input
              type="text"
              placeholder="Search by source or destination URL..."
              value={searchQuery}
              onChange={(e) => setSearchQuery(e.target.value)}
              className="w-full rounded-lg border border-gray-300 py-2 pr-3 pl-9 text-sm focus:ring-2 focus:ring-blue-500 focus:outline-none"
            />
          </div>
          <select
            value={filterType}
            onChange={(e) => setFilterType(e.target.value)}
            className="rounded-lg border border-gray-300 px-3 py-2 text-sm focus:ring-2 focus:ring-blue-500 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="mb-4 flex h-12 w-12 items-center justify-center rounded-full bg-gray-100">
            <ArrowRightLeft className="h-6 w-6 text-gray-400" />
          </div>
          <h3 className="mb-1 text-sm font-medium text-gray-900">No redirects yet</h3>
          <p className="text-sm text-gray-500">Add your first redirect to get started.</p>
        </div>
      ) : (
        <div className="rounded-lg border border-gray-200 bg-white">
          <div className="overflow-x-auto">
            <table className="w-full">
              <thead className="border-b border-gray-200 bg-gray-50">
                <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="px-4 py-2 text-left text-xs font-medium text-gray-700">Actions</th>
                </tr>
              </thead>
              <tbody className="divide-y divide-gray-200">
                {filteredAndSorted.map((redirect) => (
                  <tr key={redirect.id} className="transition-colors hover:bg-gray-50">
                    <td className="px-4 py-3">
                      <code className="rounded bg-gray-100 px-2 py-1 text-xs text-gray-900">
                        {redirect.from}
                      </code>
                    </td>
                    <td className="px-4 py-3">
                      <code className="rounded bg-gray-100 px-2 py-1 text-xs text-gray-900">
                        {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-blue-100 text-blue-800'
                            : 'bg-purple-100 text-purple-800'
                        }`}
                      >
                        {redirect.type}
                      </span>
                    </td>
                    <td className="px-4 py-3 text-sm text-gray-600">
                      {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-green-100 text-green-800'
                            : 'bg-gray-100 text-gray-800'
                        }`}
                      >
                        {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="rounded p-1.5 transition-colors hover:bg-gray-100"
                          aria-label="Edit redirect"
                        >
                          <Pencil className="h-4 w-4 text-gray-600" />
                        </button>
                        <button
                          type="button"
                          onClick={() => handleDelete(redirect.id)}
                          className="rounded p-1.5 transition-colors hover:bg-gray-100"
                          aria-label="Delete redirect"
                        >
                          <Trash2 className="h-4 w-4 text-red-600" />
                        </button>
                      </div>
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        </div>
      )}

      <Dialog.Root open={showAddDialog} onOpenChange={setShowAddDialog}>
        <Dialog.Portal>
          <Dialog.Overlay className="fixed inset-0 z-50 bg-black/50" />
          <Dialog.Content className="fixed top-1/2 left-1/2 z-50 w-full max-w-md -translate-x-1/2 -translate-y-1/2 rounded-lg bg-white p-6 shadow-lg">
            <Dialog.Title className="mb-4 text-lg font-semibold text-gray-900">
              Add Redirect
            </Dialog.Title>
            <form onSubmit={handleSubmit} className="space-y-4">
              <div>
                <label className="mb-1 block text-sm font-medium text-gray-700">Source URL</label>
                <input
                  type="text"
                  value={newRedirect.source}
                  onChange={(e) => setNewRedirect({ ...newRedirect, source: e.target.value })}
                  placeholder="/old-page"
                  className="w-full rounded-lg border border-gray-300 px-3 py-2 text-sm focus:ring-2 focus:ring-blue-500 focus:outline-none"
                  required
                />
              </div>
              <div>
                <label className="mb-1 block text-sm font-medium text-gray-700">
                  Destination URL
                </label>
                <input
                  type="text"
                  value={newRedirect.destination}
                  onChange={(e) => setNewRedirect({ ...newRedirect, destination: e.target.value })}
                  placeholder="/new-page"
                  className="w-full rounded-lg border border-gray-300 px-3 py-2 text-sm focus:ring-2 focus:ring-blue-500 focus:outline-none"
                  required
                />
              </div>
              <div>
                <label className="mb-1 block text-sm font-medium text-gray-700">
                  Redirect Type
                </label>
                <select
                  value={newRedirect.type}
                  onChange={(e) =>
                    setNewRedirect({ ...newRedirect, type: e.target.value as '301' | '302' })
                  }
                  className="w-full rounded-lg border border-gray-300 px-3 py-2 text-sm focus:ring-2 focus:ring-blue-500 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="rounded-lg border border-gray-300 px-4 py-2 text-sm transition-colors hover:bg-gray-50"
                  >
                    Cancel
                  </button>
                </Dialog.Close>
                <button
                  type="submit"
                  className="rounded-lg bg-blue-600 px-4 py-2 text-sm text-white transition-colors hover:bg-blue-700"
                >
                  Add Redirect
                </button>
              </div>
            </form>
          </Dialog.Content>
        </Dialog.Portal>
      </Dialog.Root>
    </div>
  )
}
