import { useState } from 'react'
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'
import {
  PlusIcon,
  PencilIcon,
  TrashIcon,
  MapPinIcon,
  BuildingOfficeIcon,
  WrenchScrewdriverIcon,
  ArchiveBoxIcon,
  TruckIcon,
} from '@heroicons/react/24/outline'
import clsx from 'clsx'
import { poisApi } from '@/api'
import { MapContainer } from '@/components/mapa'
import POILayer from '@/components/mapa/POILayer'
import Card from '@/components/ui/Card'
import Button from '@/components/ui/Button'
import Modal from '@/components/ui/Modal'
import Input from '@/components/ui/Input'
import Select from '@/components/ui/Select'
import Table from '@/components/ui/Table'
import { useToast } from '@/components/ui/Toast'
import { POI } from '@/types'

interface POIForm {
  nombre: string
  tipo: POI['tipo']
  direccion: string
  lat: number | ''
  lng: number | ''
  telefono?: string
  notas?: string
}

const defaultForm: POIForm = {
  nombre: '',
  tipo: 'cliente',
  direccion: '',
  lat: '',
  lng: '',
}

const tipoIcons: Record<POI['tipo'], React.ReactNode> = {
  cliente: <BuildingOfficeIcon className="w-5 h-5" />,
  taller: <WrenchScrewdriverIcon className="w-5 h-5" />,
  gasolinera: <TruckIcon className="w-5 h-5" />,
  almacen: <ArchiveBoxIcon className="w-5 h-5" />,
  otro: <MapPinIcon className="w-5 h-5" />,
}

const tipoColors: Record<POI['tipo'], string> = {
  cliente: 'text-accent-400',
  taller: 'text-warning-400',
  gasolinera: 'text-success-400',
  almacen: 'text-purple-400',
  otro: 'text-slate-400',
}

export default function POIs() {
  const queryClient = useQueryClient()
  const toast = useToast()
  const [isModalOpen, setIsModalOpen] = useState(false)
  const [form, setForm] = useState<POIForm>(defaultForm)
  const [editingPOI, setEditingPOI] = useState<POI | null>(null)
  const [viewMode, setViewMode] = useState<'map' | 'table'>('map')
  const [filterTipo, setFilterTipo] = useState<string>('')

  const { data: pois, isLoading } = useQuery({
    queryKey: ['pois'],
    queryFn: () => poisApi.list(),
  })

  const createMutation = useMutation({
    mutationFn: poisApi.create,
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['pois'] })
      toast.success('Punto de interes creado')
      handleCloseModal()
    },
    onError: () => {
      toast.error('Error al crear punto de interes')
    },
  })

  const updateMutation = useMutation({
    mutationFn: ({ id, data }: { id: string; data: Partial<POI> }) =>
      poisApi.update(id, data),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['pois'] })
      toast.success('Punto de interes actualizado')
      handleCloseModal()
    },
    onError: () => {
      toast.error('Error al actualizar')
    },
  })

  const deleteMutation = useMutation({
    mutationFn: poisApi.delete,
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['pois'] })
      toast.success('Punto de interes eliminado')
    },
    onError: () => {
      toast.error('Error al eliminar')
    },
  })

  const handleCloseModal = () => {
    setIsModalOpen(false)
    setForm(defaultForm)
    setEditingPOI(null)
  }

  const handleNewPOI = () => {
    setForm(defaultForm)
    setEditingPOI(null)
    setIsModalOpen(true)
  }

  const handleEditPOI = (poi: POI) => {
    setForm({
      nombre: poi.nombre,
      tipo: poi.tipo,
      direccion: poi.direccion,
      lat: poi.lat,
      lng: poi.lng,
      telefono: poi.telefono,
      notas: poi.notas,
    })
    setEditingPOI(poi)
    setIsModalOpen(true)
  }

  const handleDeletePOI = (id: string) => {
    if (confirm('¿Estas seguro de eliminar este punto de interes?')) {
      deleteMutation.mutate(id)
    }
  }

  const handleMapClick = (lat: number, lng: number) => {
    if (isModalOpen) {
      setForm({ ...form, lat, lng })
    }
  }

  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault()

    if (!form.nombre || !form.direccion) {
      toast.error('Completa los campos requeridos')
      return
    }

    if (form.lat === '' || form.lng === '') {
      toast.error('Selecciona una ubicacion en el mapa')
      return
    }

    const poiData = {
      nombre: form.nombre,
      tipo: form.tipo,
      direccion: form.direccion,
      lat: form.lat as number,
      lng: form.lng as number,
      telefono: form.telefono,
      notas: form.notas,
    }

    if (editingPOI) {
      updateMutation.mutate({ id: editingPOI.id, data: poiData })
    } else {
      createMutation.mutate(poiData as Omit<POI, 'id' | 'createdAt' | 'updatedAt'>)
    }
  }

  const poisList = pois || []
  const filteredPOIs = filterTipo
    ? poisList.filter((p) => p.tipo === filterTipo)
    : poisList

  const columns = [
    {
      key: 'nombre',
      header: 'Nombre',
      render: (poi: POI) => (
        <div className="flex items-center gap-3">
          <span className={tipoColors[poi.tipo]}>{tipoIcons[poi.tipo]}</span>
          <div>
            <p className="text-white font-medium">{poi.nombre}</p>
            <p className="text-xs text-slate-500 capitalize">{poi.tipo}</p>
          </div>
        </div>
      ),
    },
    {
      key: 'direccion',
      header: 'Direccion',
      render: (poi: POI) => <span className="text-slate-300">{poi.direccion}</span>,
    },
    {
      key: 'telefono',
      header: 'Telefono',
      render: (poi: POI) => (
        <span className="text-slate-300">{poi.telefono || '-'}</span>
      ),
    },
    {
      key: 'coordenadas',
      header: 'Coordenadas',
      render: (poi: POI) => (
        <span className="text-slate-400 text-xs font-mono">
          {poi.lat.toFixed(5)}, {poi.lng.toFixed(5)}
        </span>
      ),
    },
    {
      key: 'acciones',
      header: '',
      sortable: false,
      render: (poi: POI) => (
        <div className="flex items-center gap-2 justify-end">
          <Button
            size="xs"
            variant="ghost"
            leftIcon={<PencilIcon className="w-4 h-4" />}
            onClick={() => handleEditPOI(poi)}
          >
            Editar
          </Button>
          <Button
            size="xs"
            variant="ghost"
            leftIcon={<TrashIcon className="w-4 h-4" />}
            onClick={() => handleDeletePOI(poi.id)}
          >
            Eliminar
          </Button>
        </div>
      ),
    },
  ]

  // Stats by type
  const stats = {
    cliente: poisList.filter((p) => p.tipo === 'cliente').length,
    taller: poisList.filter((p) => p.tipo === 'taller').length,
    gasolinera: poisList.filter((p) => p.tipo === 'gasolinera').length,
    almacen: poisList.filter((p) => p.tipo === 'almacen').length,
    otro: poisList.filter((p) => p.tipo === 'otro').length,
  }

  return (
    <div className="space-y-6">
      {/* Header */}
      <div className="flex items-center justify-between">
        <div>
          <h1 className="text-2xl font-bold text-white">Puntos de Interes</h1>
          <p className="text-slate-500 mt-1">
            Gestiona ubicaciones importantes para tu flota
          </p>
        </div>
        <div className="flex items-center gap-3">
          <div className="flex rounded-lg overflow-hidden border border-slate-700">
            <button
              onClick={() => setViewMode('map')}
              className={clsx(
                'px-3 py-1.5 text-sm',
                viewMode === 'map'
                  ? 'bg-accent-500 text-white'
                  : 'bg-slate-800 text-slate-400 hover:text-white'
              )}
            >
              Mapa
            </button>
            <button
              onClick={() => setViewMode('table')}
              className={clsx(
                'px-3 py-1.5 text-sm',
                viewMode === 'table'
                  ? 'bg-accent-500 text-white'
                  : 'bg-slate-800 text-slate-400 hover:text-white'
              )}
            >
              Tabla
            </button>
          </div>
          <Button leftIcon={<PlusIcon className="w-5 h-5" />} onClick={handleNewPOI}>
            Nuevo POI
          </Button>
        </div>
      </div>

      {/* Stats */}
      <div className="grid grid-cols-2 sm:grid-cols-5 gap-4">
        {Object.entries(stats).map(([tipo, count]) => (
          <Card
            key={tipo}
            padding="md"
            className={clsx(
              'cursor-pointer transition-all',
              filterTipo === tipo && 'ring-2 ring-accent-500'
            )}
            onClick={() => setFilterTipo(filterTipo === tipo ? '' : tipo)}
          >
            <div className="flex items-center gap-3">
              <span className={tipoColors[tipo as POI['tipo']]}>
                {tipoIcons[tipo as POI['tipo']]}
              </span>
              <div>
                <p className="text-2xl font-bold text-white">{count}</p>
                <p className="text-xs text-slate-500 capitalize">{tipo}</p>
              </div>
            </div>
          </Card>
        ))}
      </div>

      {/* Content */}
      {viewMode === 'map' ? (
        <div className="h-[500px] rounded-xl overflow-hidden">
          <MapContainer showControls>
            <POILayer pois={filteredPOIs} onPOIClick={handleEditPOI} />
          </MapContainer>
        </div>
      ) : (
        <Card padding="none">
          <Table
            data={filteredPOIs}
            columns={columns}
            keyExtractor={(p) => p.id}
            isLoading={isLoading}
            pagination
            pageSize={15}
            emptyMessage="No hay puntos de interes"
          />
        </Card>
      )}

      {/* Create/Edit Modal */}
      <Modal
        isOpen={isModalOpen}
        onClose={handleCloseModal}
        title={editingPOI ? 'Editar punto de interes' : 'Nuevo punto de interes'}
        size="lg"
      >
        <form onSubmit={handleSubmit} className="space-y-4">
          <div className="grid grid-cols-2 gap-4">
            <Input
              label="Nombre *"
              value={form.nombre}
              onChange={(e) => setForm({ ...form, nombre: e.target.value })}
              placeholder="Ej: Cliente ABC"
            />
            <Select
              label="Tipo"
              value={form.tipo}
              onChange={(e) => setForm({ ...form, tipo: e.target.value as POI['tipo'] })}
              options={[
                { value: 'cliente', label: 'Cliente' },
                { value: 'taller', label: 'Taller' },
                { value: 'gasolinera', label: 'Gasolinera' },
                { value: 'almacen', label: 'Almacen' },
                { value: 'otro', label: 'Otro' },
              ]}
            />
          </div>

          <Input
            label="Direccion *"
            value={form.direccion}
            onChange={(e) => setForm({ ...form, direccion: e.target.value })}
            placeholder="Ej: Av. Principal 123, Ciudad"
          />

          <Input
            label="Telefono"
            value={form.telefono || ''}
            onChange={(e) => setForm({ ...form, telefono: e.target.value })}
            placeholder="Ej: +52 555 123 4567"
          />

          <div>
            <label className="block text-sm font-medium text-slate-400 mb-2">
              Notas
            </label>
            <textarea
              value={form.notas || ''}
              onChange={(e) => setForm({ ...form, notas: e.target.value })}
              rows={3}
              className={clsx(
                'w-full px-4 py-2 bg-slate-800/50 border border-slate-700/50 rounded-lg',
                'text-white placeholder:text-slate-500',
                'focus:outline-none focus:ring-2 focus:ring-accent-500'
              )}
              placeholder="Notas adicionales..."
            />
          </div>

          <div>
            <label className="block text-sm font-medium text-slate-400 mb-2">
              Ubicacion
            </label>
            <div className="grid grid-cols-2 gap-4 mb-2">
              <Input
                label="Latitud"
                type="number"
                step="any"
                value={form.lat}
                onChange={(e) =>
                  setForm({ ...form, lat: e.target.value ? parseFloat(e.target.value) : '' })
                }
                placeholder="19.4326"
              />
              <Input
                label="Longitud"
                type="number"
                step="any"
                value={form.lng}
                onChange={(e) =>
                  setForm({ ...form, lng: e.target.value ? parseFloat(e.target.value) : '' })
                }
                placeholder="-99.1332"
              />
            </div>
            <p className="text-xs text-slate-500">
              Ingresa las coordenadas manualmente o usa el geocodificador
            </p>
          </div>

          <div className="flex justify-end gap-3 pt-4">
            <Button type="button" variant="ghost" onClick={handleCloseModal}>
              Cancelar
            </Button>
            <Button
              type="submit"
              isLoading={createMutation.isPending || updateMutation.isPending}
            >
              {editingPOI ? 'Guardar cambios' : 'Crear POI'}
            </Button>
          </div>
        </form>
      </Modal>
    </div>
  )
}
