import { useState, useCallback, useRef } from 'react'
import { useQuery } from '@tanstack/react-query'
import { Link } from 'react-router-dom'
import {
  Search, SlidersHorizontal, CookingPot, Clock, Users, Sparkles
} from 'lucide-react'
import { mealPlannerApi } from '../api'
import type { Recipe } from '../types'
import { Button } from '../components/ui/Button'
import { Input } from '../components/ui/Input'
import { Badge } from '../components/ui/Badge'
import { Card, CardBody } from '../components/ui/Card'
import { Skeleton, SkeletonText } from '../components/ui/Skeleton'
import { EmptyState } from '../components/ui/EmptyState'
import { Select } from '../components/ui/Select'
import { useFocusSearchOnShortcut } from '../hooks/useFocusSearch'

const CUISINE_OPTIONS = [
  { value: '', label: 'All cuisines' },
  { value: 'american', label: 'American' },
  { value: 'chinese', label: 'Chinese' },
  { value: 'french', label: 'French' },
  { value: 'greek', label: 'Greek' },
  { value: 'indian', label: 'Indian' },
  { value: 'italian', label: 'Italian' },
  { value: 'japanese', label: 'Japanese' },
  { value: 'korean', label: 'Korean' },
  { value: 'mediterranean', label: 'Mediterranean' },
  { value: 'mexican', label: 'Mexican' },
  { value: 'thai', label: 'Thai' },
]

const PROTEIN_OPTIONS = [
  { value: '', label: 'All proteins' },
  { value: 'beef', label: 'Beef' },
  { value: 'chicken', label: 'Chicken' },
  { value: 'lamb', label: 'Lamb' },
  { value: 'pork', label: 'Pork' },
  { value: 'shrimp', label: 'Shrimp' },
  { value: 'salmon', label: 'Salmon' },
  { value: 'tofu', label: 'Tofu' },
  { value: 'vegetarian', label: 'Vegetarian' },
]

export default function RecipesPage() {
  const [q, setQ] = useState('')
  const searchInputRef = useRef<HTMLInputElement>(null)
  useFocusSearchOnShortcut(searchInputRef)
  const [debouncedQ, setDebouncedQ] = useState('')
  const [showFilters, setShowFilters] = useState(false)

  // Pending (form) vs applied (query) state so users can stage changes
  // and commit them with Apply, with Reset clearing pending back to applied.
  const [applied, setApplied] = useState({
    cuisine: '', protein: '', dietary: '', ingredient: '',
    maxTime: '', spiceMax: '', calorieMax: '',
  })
  const [pending, setPending] = useState(applied)

  const setPendingField = (key: keyof typeof pending, value: string) =>
    setPending(p => ({ ...p, [key]: value }))

  const activeCount = Object.values(applied).filter(v => v && v.length > 0).length

  const applyFilters = () => setApplied(pending)
  const resetFilters = () => {
    const empty = {
      cuisine: '', protein: '', dietary: '', ingredient: '',
      maxTime: '', spiceMax: '', calorieMax: '',
    }
    setPending(empty)
    setApplied(empty)
  }

  // Debounce search
  const handleSearch = useCallback((value: string) => {
    setQ(value)
    const id = setTimeout(() => setDebouncedQ(value), 300)
    return () => clearTimeout(id)
  }, [])

  const params: any = { limit: 120 }
  if (debouncedQ) params.q = debouncedQ
  if (applied.cuisine) params.cuisine = applied.cuisine
  if (applied.protein) params.protein = applied.protein
  if (applied.dietary) params.dietary = applied.dietary
  if (applied.ingredient) params.ingredient = applied.ingredient
  if (applied.maxTime) params.max_time = parseInt(applied.maxTime, 10)
  if (applied.spiceMax) params.spice_max = parseInt(applied.spiceMax, 10)
  if (applied.calorieMax) params.calorie_max = parseInt(applied.calorieMax, 10)

  const { data, isLoading } = useQuery<Recipe[]>({
    queryKey: ['recipes', params],
    queryFn: () => mealPlannerApi.recipes.list(params).then(r => r.data),
  })

  if (isLoading && !data) {
    return <RecipesSkeleton />
  }

  const recipes = data || []

  return (
    <div className="space-y-6">
      {/* Header */}
      <div className="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4">
        <div className="flex items-center gap-3">
          <div className="w-10 h-10 rounded-xl bg-primary-50 flex items-center justify-center">
            <CookingPot className="w-5 h-5 text-primary-600" />
          </div>
          <div>
            <h1 className="text-2xl font-bold text-surface-900">Recipes</h1>
            <p className="text-sm text-surface-500">{recipes.length} recipes</p>
          </div>
        </div>
        <div className="flex gap-2">
          <Link
            to="/recipes/recommended"
            className="inline-flex items-center gap-2 rounded-lg bg-warning-50 text-warning-700 text-sm font-medium px-4 py-2 hover:bg-warning-100 transition-colors"
          >
            <Sparkles className="w-4 h-4" />
            Recommended
          </Link>
          <Button
            variant={showFilters ? 'primary' : 'secondary'}
            size="sm"
            icon={<SlidersHorizontal className="w-4 h-4" />}
            onClick={() => setShowFilters(!showFilters)}
            aria-expanded={showFilters}
          >
            Filters
            {activeCount > 0 && (
              <span
                className="ml-1.5 inline-flex items-center justify-center min-w-[1.25rem] h-5 px-1.5 text-[10px] font-bold rounded-full bg-primary-600 text-white"
                aria-label={`${activeCount} filters active`}
              >
                {activeCount}
              </span>
            )}
          </Button>
        </div>
      </div>

      {/* Search */}
      <div className="relative">
        <Search className="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-surface-400" />
        <Input
          ref={searchInputRef}
          value={q}
          onChange={(e) => handleSearch(e.target.value)}
          placeholder="Search recipes..."
          className="pl-10"
        />
      </div>

      {/* Filters */}
      {showFilters && (
        <div role="region" aria-label="Filters">
        <Card className="overflow-hidden">
          <CardBody>
            <div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4">
              <Select
                label="Cuisine"
                options={CUISINE_OPTIONS}
                value={pending.cuisine}
                onChange={(e) => setPendingField('cuisine', e.target.value)}
              />
              <Select
                label="Protein"
                options={PROTEIN_OPTIONS}
                value={pending.protein}
                onChange={(e) => setPendingField('protein', e.target.value)}
              />
              <Input
                label="Dietary tag"
                value={pending.dietary}
                onChange={(e) => setPendingField('dietary', e.target.value)}
                placeholder="e.g., gluten-free"
              />
              <Input
                label="Contains ingredient"
                value={pending.ingredient}
                onChange={(e) => setPendingField('ingredient', e.target.value)}
                placeholder="e.g., chicken"
              />
              <Input
                label="Max time (min)"
                type="number"
                value={pending.maxTime}
                onChange={(e) => setPendingField('maxTime', e.target.value)}
                placeholder="e.g., 45"
              />
              <Input
                label="Max spice (1-5)"
                type="number"
                value={pending.spiceMax}
                onChange={(e) => setPendingField('spiceMax', e.target.value)}
                placeholder="e.g., 2"
              />
              <Input
                label="Max calories"
                type="number"
                value={pending.calorieMax}
                onChange={(e) => setPendingField('calorieMax', e.target.value)}
                placeholder="e.g., 600"
              />
            </div>
            <div className="flex items-center justify-end gap-2 mt-4 pt-4 border-t border-surface-200">
              <Button variant="ghost" size="sm" onClick={resetFilters}>
                Reset
              </Button>
              <Button size="sm" onClick={applyFilters}>
                Apply filters
              </Button>
            </div>
          </CardBody>
        </Card>
        </div>
      )}

      {/* Grid */}
      {recipes.length === 0 ? (
        <EmptyState
          icon={CookingPot}
          title="No recipes found"
          description="Try adjusting filters or search terms."
        />
      ) : (
        <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4">
          {recipes.map(recipe => (
            <RecipeCard key={recipe.id} recipe={recipe} />
          ))}
        </div>
      )}
    </div>
  )
}

function RecipeCard({ recipe }: { recipe: Recipe }) {
  const totalTime = recipe.total_time_minutes ??
    (recipe.prep_time_minutes || 0) + (recipe.cook_time_minutes || 0)
  return (
    <Link to={`/recipes/${recipe.id}`} className="group block">
      <Card className="h-full overflow-hidden hover:shadow-md transition-shadow border-surface-200 hover:border-primary-200">
        {recipe.image_url ? (
          <div className="aspect-[4/3] overflow-hidden bg-surface-100">
            <img
              src={recipe.image_url}
              alt={recipe.name}
              className="w-full h-full object-cover group-hover:scale-105 transition-transform duration-300"
            />
          </div>
        ) : (
          <div className="aspect-[4/3] bg-surface-100 flex items-center justify-center">
            <CookingPot className="w-12 h-12 text-surface-300" />
          </div>
        )}
        <CardBody className="space-y-2">
          <h3 className="font-semibold text-surface-900 group-hover:text-primary-700 transition-colors line-clamp-2">
            {recipe.name}
          </h3>
          <p className="text-xs text-surface-500 line-clamp-2">{recipe.description}</p>
          <div className="flex flex-wrap gap-1.5 pt-1">
            {recipe.cuisine_tags?.map(t => (
              <Badge key={t} variant="neutral" className="text-[10px] px-1.5 py-0">{t}</Badge>
            ))}
            {recipe.dietary_tags?.map(t => (
              <Badge key={t} variant="success" className="text-[10px] px-1.5 py-0">{t}</Badge>
            ))}
            {recipe.protein_type && (
              <Badge variant="primary" className="text-[10px] px-1.5 py-0">{recipe.protein_type}</Badge>
            )}
          </div>
          <div className="flex items-center gap-3 text-xs text-surface-500 pt-1">
            {totalTime > 0 && (
              <span className="flex items-center gap-1">
                <Clock className="w-3.5 h-3.5" />
                {totalTime} min
              </span>
            )}
            <span className="flex items-center gap-1">
              <Users className="w-3.5 h-3.5" />
              {recipe.servings}
            </span>
          </div>
        </CardBody>
      </Card>
    </Link>
  )
}

function RecipesSkeleton() {
  return (
    <div className="space-y-6 animate-fade-in">
      <div className="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4">
        <div className="flex items-center gap-3">
          <Skeleton className="h-10 w-10 rounded-xl" />
          <div>
            <Skeleton className="h-8 w-32" />
            <Skeleton className="h-4 w-20 mt-1" />
          </div>
        </div>
        <Skeleton className="h-9 w-24" />
      </div>
      <Skeleton className="h-10 w-full" />
      <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4">
        {Array.from({ length: 8 }).map((_, i) => (
          <Card key={i}>
            <Skeleton className="aspect-[4/3]" />
            <CardBody>
              <Skeleton className="h-5 w-3/4 mb-2" />
              <SkeletonText lines={2} />
              <Skeleton className="h-4 w-24 mt-2" />
            </CardBody>
          </Card>
        ))}
      </div>
    </div>
  )
}
