'use client'

import {
  Plus,
  Search,
  Trash2,
  SlidersHorizontal,
  Pencil,
  ArrowUpDown,
  ArrowUp,
  ArrowDown,
  Loader2,
  AlertTriangle,
  GripVertical,
  FolderInput,
} from 'lucide-react'
import { useState, useMemo, useCallback } 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'
import { FolderTree, type FolderSelection } from '../components/FolderTree.js'

type PageSortKey = 'title' | 'author' | 'template' | 'status' | 'date'

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

const COLOR_PALETTE = [
  { bg: 'bg-blue-100', text: 'text-blue-700' },
  { bg: 'bg-green-100', text: 'text-green-700' },
  { bg: 'bg-purple-100', text: 'text-purple-700' },
  { bg: 'bg-orange-100', text: 'text-orange-700' },
  { bg: 'bg-pink-100', text: 'text-pink-700' },
  { bg: 'bg-teal-100', text: 'text-teal-700' },
  { bg: 'bg-indigo-100', text: 'text-indigo-700' },
  { bg: 'bg-rose-100', text: 'text-rose-700' },
]

function hashString(s: string): number {
  let hash = 0
  for (let i = 0; i < s.length; i++) {
    hash = ((hash << 5) - hash + s.charCodeAt(i)) | 0
  }
  return Math.abs(hash)
}

const folderColorCache: Record<string, (typeof COLOR_PALETTE)[0]> = {}

function getFolderColor(name: string) {
  if (!folderColorCache[name]) {
    folderColorCache[name] = COLOR_PALETTE[hashString(name) % COLOR_PALETTE.length]!
  }
  return folderColorCache[name]!
}

function computeSeoScore(data: Record<string, unknown> | null | undefined): number {
  if (!data) return 0
  let score = 0
  if (data.metaTitle || data.seoTitle) score += 25
  if (data.metaDescription || data.seoDescription) score += 25
  if (data.canonical) score += 25
  if (data.schemaType) score += 25
  return score
}

function textValue(value: unknown): string {
  return String(value ?? '')
}

function SeoScoreBadge({ score }: { score: number }) {
  const color = score >= 80 ? 'bg-green-500' : score >= 60 ? 'bg-amber-500' : 'bg-red-500'
  return (
    <div className="flex items-center gap-1.5">
      <span className={`h-2.5 w-2.5 rounded-full ${color}`} />
      <span className="text-xs text-gray-600">{score}</span>
    </div>
  )
}

function FolderBadge({ name }: { name: string }) {
  const colors = getFolderColor(name)
  return (
    <span
      className={`inline-flex rounded px-2 py-0.5 text-xs font-medium ${colors.bg} ${colors.text}`}
    >
      {name}
    </span>
  )
}

function buildApiUrl(folderSel: FolderSelection): string {
  const base = '/collections/pages?pageSize=100'
  if (folderSel.type === 'smart') {
    if (folderSel.smart === 'recent') return `${base}&sort=updatedAt&order=desc&pageSize=20`
    if (folderSel.smart === 'uncategorized') return `${base}&folderId=none`
    return base
  }
  return `${base}&folderId=${folderSel.folderId}`
}

export function Pages({ onNavigate }: PagesProps) {
  const [folderSel, setFolderSel] = useState<FolderSelection>({ type: 'smart', smart: 'all' })
  const [sidebarOpen, setSidebarOpen] = useState(true)

  const apiUrl = useMemo(() => buildApiUrl(folderSel), [folderSel])
  const { data, loading, error, refetch } = useApiData<{ docs: any[]; total: number }>(apiUrl)

  const allData = useApiData<{ docs: any[]; total: number }>('/collections/pages?pageSize=1')
  const uncatData = useApiData<{ docs: any[]; total: number }>(
    '/collections/pages?pageSize=1&folderId=none',
  )

  const [searchQuery, setSearchQuery] = useState('')
  const [filterStatus, setFilterStatus] = useState<string>('all')
  const [filterTemplate, setFilterTemplate] = useState<string>('all')
  const [selectedPages, setSelectedPages] = useState<number[]>([])
  const [sortConfig, setSortConfig] = useState<SortConfig<PageSortKey> | null>(null)

  const pages = data?.docs ?? []
  const totalCount = data?.total ?? pages.length

  const filteredAndSorted = useMemo(() => {
    let results = pages.filter((page: any) => {
      const matchesSearch =
        textValue(page.title).toLowerCase().includes(searchQuery.toLowerCase()) ||
        textValue(page.author).toLowerCase().includes(searchQuery.toLowerCase())
      const matchesStatus =
        filterStatus === 'all' ||
        textValue(page.status).toLowerCase() === filterStatus.toLowerCase()
      const matchesTemplate =
        filterTemplate === 'all' ||
        textValue(page.template).toLowerCase() === filterTemplate.toLowerCase()
      return matchesSearch && matchesStatus && matchesTemplate
    })

    if (searchQuery.trim()) {
      results = sortByRelevance(results, searchQuery, (p: any) => [
        p.title,
        p.author ?? '',
        p.template ?? '',
      ])
    } else if (sortConfig) {
      results = [...results].sort((a: any, b: any) => {
        const aVal = a[sortConfig.key] ?? ''
        const bVal = b[sortConfig.key] ?? ''
        const cmp = String(aVal).localeCompare(String(bVal))
        return sortConfig.direction === 'asc' ? cmp : -cmp
      })
    }
    return results
  }, [pages, searchQuery, filterStatus, filterTemplate, sortConfig])

  const handleSelectAll = (checked: boolean) => {
    setSelectedPages(checked ? filteredAndSorted.map((p: any) => p.id) : [])
  }

  const handleSelectPage = (id: number) => {
    setSelectedPages((prev) =>
      prev.includes(id) ? prev.filter((pid) => pid !== id) : [...prev, id],
    )
  }

  const handleBulkDelete = async () => {
    for (const id of selectedPages) {
      await cmsApi(`/collections/pages/${id}`, { method: 'DELETE' })
    }
    toast.success(`${selectedPages.length} pages deleted`)
    setSelectedPages([])
    refetch()
  }

  const handleBulkPublish = async () => {
    for (const id of selectedPages) {
      await cmsApi(`/collections/pages/${id}`, {
        method: 'PUT',
        body: JSON.stringify({ status: 'PUBLISHED' }),
      })
    }
    toast.success(`${selectedPages.length} pages published`)
    setSelectedPages([])
    refetch()
  }

  const handleBulkUnpublish = async () => {
    for (const id of selectedPages) {
      await cmsApi(`/collections/pages/${id}`, {
        method: 'PUT',
        body: JSON.stringify({ status: 'DRAFT' }),
      })
    }
    toast.success(`${selectedPages.length} pages unpublished`)
    setSelectedPages([])
    refetch()
  }

  const handleDelete = async (id: number) => {
    await cmsApi(`/collections/pages/${id}`, { method: 'DELETE' })
    toast.success('Page deleted')
    setSelectedPages((prev) => prev.filter((pid) => pid !== id))
    refetch()
  }

  const handleDropItem = useCallback(
    async (itemId: string, folderId: string | null) => {
      const res = await cmsApi(`/documents/${itemId}/folder`, {
        method: 'PUT',
        body: JSON.stringify({ folderId }),
      })
      if (res.error) {
        toast.error(res.error)
      } else {
        toast.success(folderId ? 'Moved to folder' : 'Removed from folder')
        refetch()
      }
    },
    [refetch],
  )

  const handleDragStart = (e: React.DragEvent, id: string) => {
    e.dataTransfer.setData('text/actuate-item-id', id)
    e.dataTransfer.effectAllowed = 'move'
  }

  function SortHeader({ label, sortKey }: { label: string; sortKey: PageSortKey }) {
    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="flex h-full flex-col 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 flex-col justify-between gap-3 sm:flex-row sm:items-center">
        <div className="flex items-center gap-3">
          <button
            type="button"
            onClick={() => setSidebarOpen((prev) => !prev)}
            className="rounded-lg p-1.5 transition-colors hover:bg-gray-100"
            title={sidebarOpen ? 'Hide folders' : 'Show folders'}
          >
            <FolderInput className="h-5 w-5 text-gray-600" />
          </button>
          <div>
            <h1 className="text-xl font-semibold text-gray-900 sm:text-2xl">Pages</h1>
            <p className="text-sm text-gray-500">
              {totalCount} page{totalCount !== 1 ? 's' : ''}
            </p>
          </div>
        </div>
        <button
          onClick={() => onNavigate?.('/pages/new')}
          className="flex items-center justify-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" />
          <span className="hidden sm:inline">New Page</span>
          <span className="sm:hidden">New</span>
        </button>
      </div>

      <div className="flex min-h-0 flex-1 gap-4 overflow-hidden">
        {sidebarOpen && (
          <div className="flex w-56 shrink-0 flex-col overflow-hidden rounded-lg border border-gray-200 bg-white">
            <FolderTree
              scope="pages"
              selected={folderSel}
              onSelect={(sel) => {
                setFolderSel(sel)
                setSelectedPages([])
              }}
              totalCount={allData.data?.total}
              uncategorizedCount={uncatData.data?.total}
              onDropItem={handleDropItem}
            />
          </div>
        )}

        <div className="flex min-w-0 flex-1 flex-col">
          <div className="mb-4 rounded-lg border border-gray-200 bg-white">
            <div className="flex flex-col gap-3 p-3">
              <div className="relative">
                <Search className="absolute top-1/2 left-3 h-4 w-4 -translate-y-1/2 text-gray-400" />
                <input
                  type="text"
                  placeholder="Search pages..."
                  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>
              <div className="flex flex-col gap-2 sm:flex-row">
                <select
                  value={filterStatus}
                  onChange={(e) => setFilterStatus(e.target.value)}
                  className="flex-1 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 Status</option>
                  <option value="published">Published</option>
                  <option value="draft">Draft</option>
                </select>
                <select
                  value={filterTemplate}
                  onChange={(e) => setFilterTemplate(e.target.value)}
                  className="flex-1 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 Templates</option>
                  <option value="landing">Landing</option>
                  <option value="standard">Standard</option>
                  <option value="marketing">Marketing</option>
                  <option value="blog">Blog</option>
                </select>
                <button
                  type="button"
                  className="flex items-center justify-center gap-2 rounded-lg border border-gray-300 px-3 py-2 text-sm transition-colors hover:bg-gray-50"
                >
                  <SlidersHorizontal className="h-4 w-4" />
                  <span className="hidden sm:inline">More Filters</span>
                </button>
              </div>
            </div>
          </div>

          {selectedPages.length > 0 && (
            <div className="mb-4 rounded-lg border border-blue-200 bg-blue-50 p-3">
              <div className="flex flex-col justify-between gap-2 sm:flex-row sm:items-center">
                <span className="text-sm text-blue-900">
                  {selectedPages.length} page{selectedPages.length !== 1 ? 's' : ''} selected
                </span>
                <div className="flex items-center gap-2">
                  <button
                    type="button"
                    onClick={handleBulkPublish}
                    className="flex-1 rounded-lg bg-green-600 px-3 py-1.5 text-sm text-white transition-colors hover:bg-green-700 sm:flex-none"
                  >
                    Publish
                  </button>
                  <button
                    type="button"
                    onClick={handleBulkUnpublish}
                    className="flex-1 rounded-lg bg-yellow-600 px-3 py-1.5 text-sm text-white transition-colors hover:bg-yellow-700 sm:flex-none"
                  >
                    Unpublish
                  </button>
                  <button
                    type="button"
                    onClick={handleBulkDelete}
                    className="flex-1 rounded-lg bg-red-600 px-3 py-1.5 text-sm text-white transition-colors hover:bg-red-700 sm:flex-none"
                  >
                    Delete
                  </button>
                  <button
                    type="button"
                    onClick={() => setSelectedPages([])}
                    className="flex-1 rounded-lg border border-gray-300 bg-white px-3 py-1.5 text-sm transition-colors hover:bg-gray-50 sm:flex-none"
                  >
                    Cancel
                  </button>
                </div>
              </div>
            </div>
          )}

          {filteredAndSorted.length === 0 && !error ? (
            <div className="flex flex-1 flex-col items-center justify-center rounded-lg border border-gray-200 bg-white p-8 text-center">
              <p className="mb-2 text-sm text-gray-500">
                {folderSel.type === 'smart' && folderSel.smart === 'uncategorized'
                  ? 'No uncategorized pages'
                  : folderSel.type === 'folder'
                    ? 'No pages in this folder'
                    : 'No pages yet'}
              </p>
              <button
                onClick={() => onNavigate?.('/pages/new')}
                className="rounded-lg bg-blue-600 px-4 py-2 text-sm text-white transition-colors hover:bg-blue-700"
              >
                Create your first page
              </button>
            </div>
          ) : (
            <>
              <div className="hidden flex-1 overflow-hidden rounded-lg border border-gray-200 bg-white md:block">
                <div className="h-full overflow-x-auto">
                  <table className="w-full">
                    <thead className="sticky top-0 border-b border-gray-200 bg-gray-50">
                      <tr>
                        <th className="w-8 px-3 py-2 text-left">
                          <input
                            type="checkbox"
                            checked={
                              selectedPages.length === filteredAndSorted.length &&
                              filteredAndSorted.length > 0
                            }
                            onChange={(e) => handleSelectAll(e.target.checked)}
                            className="rounded border-gray-300"
                          />
                        </th>
                        <th className="w-6 px-1 py-2"></th>
                        <th className="px-3 py-2 text-left">
                          <SortHeader label="Title" sortKey="title" />
                        </th>
                        <th className="px-3 py-2 text-left text-xs font-medium text-gray-700">
                          Folder
                        </th>
                        <th className="px-3 py-2 text-left">
                          <SortHeader label="Author" sortKey="author" />
                        </th>
                        <th className="px-3 py-2 text-left text-xs font-medium text-gray-700">
                          SEO
                        </th>
                        <th className="px-3 py-2 text-left">
                          <SortHeader label="Status" sortKey="status" />
                        </th>
                        <th className="px-3 py-2 text-left">
                          <SortHeader label="Date" sortKey="date" />
                        </th>
                        <th className="px-3 py-2 text-left text-xs font-medium text-gray-700">
                          Actions
                        </th>
                      </tr>
                    </thead>
                    <tbody className="divide-y divide-gray-200">
                      {filteredAndSorted.map((page: any) => {
                        const seoScore = computeSeoScore(page.data)
                        const folderName = page.folder?.name ?? page.folderName
                        return (
                          <tr
                            key={page.id}
                            className="transition-colors hover:bg-gray-50"
                            draggable
                            onDragStart={(e) => handleDragStart(e, page.id)}
                          >
                            <td className="px-3 py-2">
                              <input
                                type="checkbox"
                                checked={selectedPages.includes(page.id)}
                                onChange={() => handleSelectPage(page.id)}
                                className="rounded border-gray-300"
                              />
                            </td>
                            <td className="cursor-grab px-1 py-2">
                              <GripVertical className="h-4 w-4 text-gray-300" />
                            </td>
                            <td className="px-3 py-2">
                              <button
                                type="button"
                                onClick={() => onNavigate?.(`/pages/${page.id}`)}
                                className="text-left text-sm font-medium text-gray-900 hover:text-blue-600"
                              >
                                {page.title}
                              </button>
                            </td>
                            <td className="px-3 py-2">
                              {folderName ? (
                                <FolderBadge name={folderName} />
                              ) : (
                                <span className="text-xs text-gray-400">—</span>
                              )}
                            </td>
                            <td className="px-3 py-2 text-sm text-gray-600">{page.author}</td>
                            <td className="px-3 py-2">
                              <SeoScoreBadge score={seoScore} />
                            </td>
                            <td className="px-3 py-2">
                              <span
                                className={`inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium ${page.status === 'Published' || page.status === 'PUBLISHED' ? 'bg-green-100 text-green-800' : 'bg-gray-100 text-gray-800'}`}
                              >
                                {page.status}
                              </span>
                            </td>
                            <td className="px-3 py-2 text-sm text-gray-600">{page.date}</td>
                            <td className="px-3 py-2">
                              <div className="flex items-center gap-2">
                                <button
                                  type="button"
                                  onClick={() => onNavigate?.(`/pages/${page.id}`)}
                                  className="rounded p-1.5 transition-colors hover:bg-gray-100"
                                  title="Edit"
                                >
                                  <Pencil className="h-4 w-4 text-gray-600" />
                                </button>
                                <button
                                  type="button"
                                  onClick={() => handleDelete(page.id)}
                                  className="rounded p-1.5 transition-colors hover:bg-gray-100"
                                  title="Delete"
                                >
                                  <Trash2 className="h-4 w-4 text-red-600" />
                                </button>
                              </div>
                            </td>
                          </tr>
                        )
                      })}
                    </tbody>
                  </table>
                </div>
              </div>

              <div className="flex-1 overflow-auto rounded-lg border border-gray-200 bg-white md:hidden">
                <div className="divide-y divide-gray-200">
                  {filteredAndSorted.map((page: any) => {
                    const seoScore = computeSeoScore(page.data)
                    const folderName = page.folder?.name ?? page.folderName
                    return (
                      <div
                        key={page.id}
                        className="p-3"
                        draggable
                        onDragStart={(e) => handleDragStart(e, page.id)}
                      >
                        <div className="flex items-start gap-3">
                          <input
                            type="checkbox"
                            checked={selectedPages.includes(page.id)}
                            onChange={() => handleSelectPage(page.id)}
                            className="mt-1 rounded border-gray-300"
                          />
                          <div className="min-w-0 flex-1">
                            <button
                              type="button"
                              onClick={() => onNavigate?.(`/pages/${page.id}`)}
                              className="mb-1 block text-left text-sm font-medium text-gray-900 hover:text-blue-600"
                            >
                              {page.title}
                            </button>
                            <div className="mb-2 flex flex-wrap items-center gap-2 text-xs text-gray-600">
                              {folderName && <FolderBadge name={folderName} />}
                              <span>{page.author}</span>
                              <span>&middot;</span>
                              <span>{page.date}</span>
                              <SeoScoreBadge score={seoScore} />
                              <span
                                className={`rounded-full px-2 py-0.5 text-xs font-medium ${page.status === 'Published' || page.status === 'PUBLISHED' ? 'bg-green-100 text-green-800' : 'bg-gray-100 text-gray-800'}`}
                              >
                                {page.status}
                              </span>
                            </div>
                          </div>
                          <button
                            type="button"
                            onClick={() => handleDelete(page.id)}
                            className="rounded p-1.5 transition-colors hover:bg-gray-100"
                          >
                            <Trash2 className="h-4 w-4 text-red-600" />
                          </button>
                        </div>
                      </div>
                    )
                  })}
                </div>
              </div>
            </>
          )}
        </div>
      </div>
    </div>
  )
}
