import { useMemo, useState } from 'react'
import { Alert } from '@/components/ui/Alert'
import { Button } from '@/components/ui/Button'
import { fieldControlClass } from '@/components/ui/field'
import { toast } from '@/components/ui/toast'
import { CategoryChips } from '@/components/plants/CategoryChips'
import { PlantCard } from '@/components/plants/PlantCard'
import { PlantFormModal } from '@/components/plants/PlantFormModal'
import { DeletePlantModal } from '@/components/plants/DeletePlantModal'
import { SeedLotModal } from '@/components/plants/SeedLotModal'
import { DeleteSeedLotModal } from '@/components/plants/DeleteSeedLotModal'
import { PlantPicker } from '@/editor/PlantPicker'
import { filterPlants, usePlants, type CategoryFilter, type Plant } from '@/lib/plants'
import { lotsByPlant, useSeedLots, type SeedLot } from '@/lib/seedLots'
import type { UnitPref } from '@/lib/units'
import { usePageTitle } from '@/lib/usePageTitle'

// Which modal is open, if any. edit/duplicate/delete carry the target plant.
type Dialog =
  | { kind: 'create' }
  | { kind: 'edit'; plant: Plant }
  | { kind: 'duplicate'; plant: Plant }
  | { kind: 'delete'; plant: Plant }
  | { kind: 'picker' }
  | { kind: 'addLot'; plant: Plant }
  | { kind: 'editLot'; plant: Plant; lot: SeedLot }
  | { kind: 'deleteLot'; lot: SeedLot }
  | null

// There's no per-user unit preference server-side (only per-garden), so the
// catalog page keeps its own, persisted locally.
const UNIT_KEY = 'pansy:unit-pref'
function loadUnit(): UnitPref {
  try {
    return localStorage.getItem(UNIT_KEY) === 'imperial' ? 'imperial' : 'metric'
  } catch {
    return 'metric'
  }
}

export function PlantsPage() {
  usePageTitle('Plants')
  const plants = usePlants()
  const seedLots = useSeedLots()
  const lots = useMemo(() => lotsByPlant(seedLots.data), [seedLots.data])
  const [unit, setUnit] = useState<UnitPref>(() => loadUnit())
  const [query, setQuery] = useState('')
  const [category, setCategory] = useState<CategoryFilter>('all')
  const [dialog, setDialog] = useState<Dialog>(null)
  const close = () => setDialog(null)

  function toggleUnit() {
    setUnit((u) => {
      const next: UnitPref = u === 'metric' ? 'imperial' : 'metric'
      try {
        localStorage.setItem(UNIT_KEY, next)
      } catch {
        // Preference is a nicety; ignore storage failures.
      }
      return next
    })
  }

  const all = useMemo(() => plants.data ?? [], [plants.data])
  const filtered = useMemo(() => filterPlants(all, query, category), [all, query, category])

  return (
    <section>
      <div className="flex flex-wrap items-center justify-between gap-3">
        <h1 className="text-2xl font-semibold tracking-tight">Plants</h1>
        <div className="flex items-center gap-2">
          <Button variant="ghost" onClick={() => setDialog({ kind: 'picker' })}>
            Try the picker
          </Button>
          <Button
            variant="ghost"
            onClick={toggleUnit}
            title="Toggle spacing units"
            aria-label={`Spacing units: ${unit === 'metric' ? 'metric' : 'imperial'}`}
          >
            {unit === 'metric' ? 'cm' : 'in'}
          </Button>
          <Button onClick={() => setDialog({ kind: 'create' })}>New plant</Button>
        </div>
      </div>

      <div className="mt-4 flex flex-col gap-3">
        <input
          type="search"
          value={query}
          onChange={(e) => setQuery(e.target.value)}
          placeholder="Search plants by name…"
          aria-label="Search plants"
          className={fieldControlClass}
        />
        <div className="pb-1">
          <CategoryChips value={category} onChange={setCategory} />
        </div>
      </div>

      <div className="mt-5">
        {plants.isPending && <p className="text-sm text-muted">Loading the catalog…</p>}
        {plants.isError && <Alert>Could not load the plant catalog. Please refresh.</Alert>}

        {plants.isSuccess && filtered.length === 0 && (
          <div className="rounded-xl border border-dashed border-border p-10 text-center">
            <p className="text-fg">No plants match.</p>
            <p className="mt-1 text-sm text-muted">Try a different search or category, or add a custom plant.</p>
          </div>
        )}

        {filtered.length > 0 && (
          <div className="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3">
            {filtered.map((p) => (
              <PlantCard
                key={p.id}
                plant={p}
                unit={unit}
                lots={lots.get(p.id) ?? []}
                onEdit={() => setDialog({ kind: 'edit', plant: p })}
                onDelete={() => setDialog({ kind: 'delete', plant: p })}
                onDuplicate={() => setDialog({ kind: 'duplicate', plant: p })}
                onAddLot={() => setDialog({ kind: 'addLot', plant: p })}
                onEditLot={(lot) => setDialog({ kind: 'editLot', plant: p, lot })}
                onDeleteLot={(lot) => setDialog({ kind: 'deleteLot', lot })}
              />
            ))}
          </div>
        )}
      </div>

      {dialog?.kind === 'create' && <PlantFormModal unit={unit} onClose={close} />}
      {dialog?.kind === 'edit' && <PlantFormModal plant={dialog.plant} unit={unit} onClose={close} />}
      {dialog?.kind === 'duplicate' && <PlantFormModal template={dialog.plant} unit={unit} onClose={close} />}
      {dialog?.kind === 'delete' && <DeletePlantModal plant={dialog.plant} onClose={close} />}
      {dialog?.kind === 'addLot' && <SeedLotModal plant={dialog.plant} onClose={close} />}
      {dialog?.kind === 'editLot' && <SeedLotModal plant={dialog.plant} lot={dialog.lot} onClose={close} />}
      {dialog?.kind === 'deleteLot' && <DeleteSeedLotModal lot={dialog.lot} onClose={close} />}
      {dialog?.kind === 'picker' && (
        <PlantPicker
          unit={unit}
          onClose={close}
          onSelect={(p) => {
            toast.info(`Picked ${p.name}`)
            close()
          }}
        />
      )}
    </section>
  )
}
