import { useState, useEffect } from 'react'
import { useQuery } from '@tanstack/react-query'
import { useSearchParams } from 'react-router-dom'
import { Printer, ShoppingCart, Package, Tag, Receipt, RotateCcw, ChevronLeft, ChevronRight } from 'lucide-react'
import { mealPlannerApi } from '../api'
import type { ShoppingList } from '../types'
import { Button } from '../components/ui/Button'
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 { isoMonday, parseIsoDate, shiftIsoDate, formatIsoDate } from '../lib/utils'

const AISLE_LABEL: Record<string, string> = {
  produce: 'Produce',
  meat: 'Meat & Seafood',
  seafood: 'Meat & Seafood',
  meat_seafood: 'Meat & Seafood',
  chicken: 'Meat & Seafood',
  beef: 'Meat & Seafood',
  pork: 'Meat & Seafood',
  dairy: 'Dairy & Eggs',
  eggs: 'Dairy & Eggs',
  cheese: 'Dairy & Eggs',
  milk: 'Dairy & Eggs',
  yogurt: 'Dairy & Eggs',
  pantry: 'Pantry',
  canned: 'Pantry',
  canned_goods: 'Pantry',
  dry: 'Pantry',
  snacks: 'Pantry',
  frozen: 'Frozen',
  bakery: 'Bakery',
  bread: 'Bakery',
  beverages: 'Beverages',
  drinks: 'Beverages',
  spices: 'Spices',
  seasoning: 'Spices',
  other: 'Other',
}

function aisleDisplay(key: string): string {
  return AISLE_LABEL[key.toLowerCase()] ?? key
}

function ShoppingListSkeleton() {
  return (
    <div className="space-y-6 animate-fade-in">
      <div className="flex justify-between items-center">
        <Skeleton className="h-8 w-64" />
        <Skeleton className="h-9 w-28" />
      </div>
      <div className="grid grid-cols-1 md:grid-cols-3 gap-4">
        <SkeletonCard />
        <SkeletonCard />
        <SkeletonCard />
      </div>
      <Card>
        <CardBody>
          <SkeletonText lines={6} />
        </CardBody>
      </Card>
    </div>
  )
}

function SkeletonCard() {
  return (
    <Card>
      <CardBody>
        <Skeleton className="h-10 w-24 mb-2" />
        <Skeleton className="h-4 w-32" />
      </CardBody>
    </Card>
  )
}

function storageKey(week: string) {
  return `shopping-list-checked-${week}`
}

export default function ShoppingListPage() {
  const [searchParams, setSearchParams] = useSearchParams()
  const weekParam = searchParams.get('week')
  const parsedWeek = weekParam ? parseIsoDate(weekParam) : null
  const weekStart = weekParam && parsedWeek ? weekParam : isoMonday()
  const isCurrentWeek = weekStart === isoMonday()
  const navigateWeek = (next: string) => {
    setSearchParams(next === isoMonday() ? {} : { week: next }, { replace: true })
  }
  const { data: shoppingList, isLoading } = useQuery<ShoppingList>({
    queryKey: ['shoppingList', weekStart],
    queryFn: () => mealPlannerApi.shoppingList.get(weekStart).then(r => r.data),
  })

  const week = shoppingList?.week_start_date || ''
  const [checked, setChecked] = useState<Set<string>>(new Set())

  useEffect(() => {
    if (!week) return
    try {
      const raw = localStorage.getItem(storageKey(week))
      if (raw) {
        const parsed = JSON.parse(raw) as string[]
        setChecked(new Set(parsed))
      } else {
        setChecked(new Set())
      }
    } catch {
      setChecked(new Set())
    }
  }, [week])

  useEffect(() => {
    if (!week) return
    localStorage.setItem(storageKey(week), JSON.stringify(Array.from(checked)))
  }, [checked, week])

  const toggle = (id: string) => {
    setChecked(prev => {
      const next = new Set(prev)
      if (next.has(id)) next.delete(id)
      else next.add(id)
      return next
    })
  }

  const clearAll = () => setChecked(new Set())

  const progress =
    shoppingList && shoppingList.items.length > 0
      ? Math.round(
          (Array.from(checked).filter(id =>
            shoppingList.items.some(i => i.ingredient_id === id)
          ).length /
            shoppingList.items.length) *
            100
        )
      : 0

  if (isLoading) {
    return <ShoppingListSkeleton />
  }

  if (!shoppingList || shoppingList.items.length === 0) {
    return (
      <div className="space-y-6">
        <div className="flex items-center gap-3">
          <div className="w-10 h-10 rounded-xl bg-primary-50 flex items-center justify-center">
            <ShoppingCart className="w-5 h-5 text-primary-600" />
          </div>
          <div>
            <h1 className="text-2xl font-bold text-surface-900">Shopping List</h1>
            <p className="text-sm text-surface-500">Week of {formatIsoDate(weekStart)}</p>
          </div>
        </div>
        <div className="inline-flex items-center rounded-lg border border-surface-200 bg-white">
          <button
            onClick={() => navigateWeek(shiftIsoDate(weekStart, -7))}
            aria-label="Previous week"
            className="p-2 text-surface-600 hover:bg-surface-100 rounded-l-lg focus:outline-none focus:ring-2 focus:ring-primary-400"
          >
            <ChevronLeft className="w-4 h-4" />
          </button>
          <button
            onClick={() => navigateWeek(isoMonday())}
            aria-label="Jump to current week"
            title="Jump to current week"
            className={`px-3 py-2 text-sm font-medium border-x border-surface-200 focus:outline-none focus:ring-2 focus:ring-primary-400 ${isCurrentWeek ? 'text-primary-700 bg-primary-50' : 'text-surface-600 hover:bg-surface-100'}`}
          >
            {isCurrentWeek ? 'This week' : 'Current'}
          </button>
          <button
            onClick={() => navigateWeek(shiftIsoDate(weekStart, 7))}
            aria-label="Next week"
            className="p-2 text-surface-600 hover:bg-surface-100 rounded-r-lg focus:outline-none focus:ring-2 focus:ring-primary-400"
          >
            <ChevronRight className="w-4 h-4" />
          </button>
        </div>
        <EmptyState
          icon={Receipt}
          title={isCurrentWeek ? 'No shopping list yet' : 'No plan for that week'}
          description={isCurrentWeek
            ? 'Generate a meal plan first to see your aisle-organized shopping list with sale tracking.'
            : 'There is no meal plan for this week. Go to the Dashboard and generate one, or pick a different week.'}
        />
      </div>
    )
  }

  return (
    <div className="space-y-6">
      {/* Header */}
      <div className="flex flex-col sm:flex-row sm:justify-between sm:items-center 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">
            <ShoppingCart className="w-5 h-5 text-primary-600" />
          </div>
          <div>
            <h1 className="text-2xl font-bold text-surface-900">
              Shopping List
            </h1>
            <p className="text-sm text-surface-500">
              Week of {formatIsoDate(shoppingList.week_start_date)}
            </p>
          </div>
        </div>
        <div className="flex items-center gap-2 flex-wrap">
          <div className="inline-flex items-center rounded-lg border border-surface-200 bg-white">
            <button
              onClick={() => navigateWeek(shiftIsoDate(weekStart, -7))}
              aria-label="Previous week"
              className="p-2 text-surface-600 hover:bg-surface-100 rounded-l-lg focus:outline-none focus:ring-2 focus:ring-primary-400"
            >
              <ChevronLeft className="w-4 h-4" />
            </button>
            <button
              onClick={() => navigateWeek(isoMonday())}
              aria-label="Jump to current week"
              title="Jump to current week"
              className={`px-3 py-2 text-sm font-medium border-x border-surface-200 focus:outline-none focus:ring-2 focus:ring-primary-400 ${isCurrentWeek ? 'text-primary-700 bg-primary-50' : 'text-surface-600 hover:bg-surface-100'}`}
            >
              {isCurrentWeek ? 'This week' : 'Current'}
            </button>
            <button
              onClick={() => navigateWeek(shiftIsoDate(weekStart, 7))}
              aria-label="Next week"
              className="p-2 text-surface-600 hover:bg-surface-100 rounded-r-lg focus:outline-none focus:ring-2 focus:ring-primary-400"
            >
              <ChevronRight className="w-4 h-4" />
            </button>
          </div>
          {progress > 0 && (
            <span className="text-sm text-surface-500">{progress}% complete</span>
          )}
          {checked.size > 0 && (
            <Button
              variant="ghost"
              size="sm"
              icon={<RotateCcw className="w-4 h-4" />}
              onClick={clearAll}
            >
              Reset
            </Button>
          )}
          <Button variant="secondary" icon={<Printer className="w-4 h-4" />} onClick={() => window.print()}>
            Print List
          </Button>
        </div>
      </div>

      {/* Summary Stats */}
      <div className="grid grid-cols-3 gap-2 sm:gap-4">
        <Card className="bg-gradient-to-br from-primary-50 to-primary-100/50 border-primary-200">
          <CardBody className="p-3 sm:p-6">
            <div className="flex items-center gap-2 sm:gap-3">
              <div className="w-8 h-8 sm:w-10 sm:h-10 rounded-xl bg-primary-100 flex items-center justify-center flex-shrink-0">
                <Receipt className="w-4 h-4 sm:w-5 sm:h-5 text-primary-600" />
              </div>
              <div className="min-w-0">
                <div className="text-base sm:text-2xl font-bold text-surface-900 truncate">
                  ${shoppingList.total_estimated_cost.toFixed(2)}
                </div>
                <div className="text-[10px] sm:text-sm text-surface-500 truncate">Estimated</div>
              </div>
            </div>
          </CardBody>
        </Card>

        <Card>
          <CardBody className="p-3 sm:p-6">
            <div className="flex items-center gap-2 sm:gap-3">
              <div className="w-8 h-8 sm:w-10 sm:h-10 rounded-xl bg-surface-100 flex items-center justify-center flex-shrink-0">
                <Package className="w-4 h-4 sm:w-5 sm:h-5 text-surface-600" />
              </div>
              <div className="min-w-0">
                <div className="text-base sm:text-2xl font-bold text-surface-900 truncate">{shoppingList.items.length}</div>
                <div className="text-[10px] sm:text-sm text-surface-500 truncate">Items</div>
              </div>
            </div>
          </CardBody>
        </Card>

        <Card className="bg-gradient-to-br from-success-50 to-success-100/50 border-success-200">
          <CardBody className="p-3 sm:p-6">
            <div className="flex items-center gap-2 sm:gap-3">
              <div className="w-8 h-8 sm:w-10 sm:h-10 rounded-xl bg-success-100 flex items-center justify-center flex-shrink-0">
                <Tag className="w-4 h-4 sm:w-5 sm:h-5 text-success-600" />
              </div>
              <div className="min-w-0">
                <div className="text-base sm:text-2xl font-bold text-success-700 truncate">{shoppingList.sale_items_count}</div>
                <div className="text-[10px] sm:text-sm text-surface-500 truncate">On Sale</div>
              </div>
            </div>
          </CardBody>
        </Card>
      </div>

      {/* Aisle Groups */}
      <div className="space-y-4">
        {Object.entries(shoppingList.by_aisle).map(([aisle, items]) => (
          <Card key={aisle} className="overflow-hidden">
            <div className="px-5 py-3 border-b border-surface-200 bg-surface-50 flex items-center justify-between">
              <h3 className="text-sm font-semibold text-surface-900">{aisleDisplay(aisle)}</h3>
              <Badge variant="neutral">{items.length} items</Badge>
            </div>
            <ul className="divide-y divide-surface-200">
              {items.map((item, idx) => {
                const isChecked = item.ingredient_id ? checked.has(item.ingredient_id) : false
                return (
                  <li
                    key={idx}
                    className={`px-5 py-3.5 flex items-center justify-between hover:bg-surface-50 transition-colors ${isChecked ? 'opacity-60' : ''}`}
                  >
                    <div className="flex items-center gap-3">
                      <input
                        type="checkbox"
                        className="w-5 h-5 rounded border-2 border-surface-300 text-primary-600 focus:ring-primary-500 cursor-pointer flex-shrink-0"
                        checked={isChecked}
                        onChange={() => item.ingredient_id && toggle(item.ingredient_id)}
                      />
                      <div>
                        <span className={`text-sm font-medium text-surface-900 ${isChecked ? 'line-through text-surface-400' : ''}`}>
                          {item.name}
                        </span>
                        <div className="flex gap-1.5 mt-0.5">
                          {item.in_pantry && <Badge variant="success">In Pantry</Badge>}
                          {item.is_on_sale && <Badge variant="danger">SALE</Badge>}
                        </div>
                      </div>
                    </div>
                    <div className="text-right flex items-center gap-3">
                      {item.quantity && (
                        <span className={`text-sm text-surface-500 ${isChecked ? 'line-through' : ''}`}>
                          {item.quantity} {item.unit || ''}
                        </span>
                      )}
                      {item.sale_price ? (
                        <div className="flex flex-col items-end">
                          <span className={`text-sm font-semibold text-danger-600 ${isChecked ? 'line-through' : ''}`}>${item.sale_price.toFixed(2)}</span>
                          {item.estimated_price && item.estimated_price > item.sale_price && (
                            <span className="text-xs text-surface-400 line-through">
                              ${item.estimated_price.toFixed(2)}
                            </span>
                          )}
                        </div>
                      ) : item.estimated_price ? (
                        <span className={`text-sm font-medium text-surface-700 ${isChecked ? 'line-through' : ''}`}>
                          ${item.estimated_price.toFixed(2)}
                        </span>
                      ) : null}
                    </div>
                  </li>
                )
              })}
            </ul>
          </Card>
        ))}
      </div>
    </div>
  )
}
