import { useMemo, useState } from 'react'
import type { ColumnDef } from '@tanstack/react-table'
import { toast } from 'sonner'
import { Badge } from '@/components/ui/badge'
import { Button } from '@/components/ui/button'
import { DataTable } from '@/components/ui/data-table'
import { Switch } from '@/components/ui/switch'
import { Label } from '@/components/ui/label'
import { formatCivilDate } from '@/lib/formatters'
import type { ChargeableCharConfig } from '../types'
import { CATEGORY_LABELS } from '../categories'
import { useProductTypes } from '../../product-types/hooks/useProductTypes'
import { useReactivateChargeableCharConfig } from '../hooks/useReactivateChargeableCharConfig'
import { ReactivationNotAllowedError } from '../api/reactivateChargeableCharConfig'
import { ProductTypeSelect } from './ProductTypeSelect'
import { DeleteChargeableCharConfigDialog } from './DeleteChargeableCharConfigDialog'

interface ChargeableCharsTableProps {
  configs: ChargeableCharConfig[]
  total: number
  page: number
  pageSize: number
  onPageChange: (page: number) => void
  productTypeId: number | undefined
  activeOnly: boolean
  onProductTypeChange: (productTypeId: number | undefined) => void
  onActiveOnlyChange: (value: boolean) => void
  onSchedulePrice: (config: ChargeableCharConfig) => void
  onDeactivate: (config: ChargeableCharConfig) => void
}

function resolveReactivationError(err: unknown): string {
  if (err instanceof ReactivationNotAllowedError) {
    switch (err.reason) {
      case 'ALREADY_ACTIVE':
        return 'El registro ya está activo.'
      case 'VIGENTE_EXISTS':
        return 'Ya existe un registro activo para este tipo de producto y símbolo. Modificá ese registro en su lugar.'
      case 'POSTERIOR_ROWS_EXIST':
        return 'Existen cambios posteriores al cierre de este registro. Para modificar el precio, usá "Programar cambio de precio".'
    }
  }
  return 'No se pudo reactivar el símbolo. Intentá de nuevo.'
}

export function ChargeableCharsTable({
  configs,
  total,
  page,
  pageSize,
  onPageChange,
  productTypeId,
  activeOnly,
  onProductTypeChange,
  onActiveOnlyChange,
  onSchedulePrice,
  onDeactivate,
}: ChargeableCharsTableProps) {
  const { data: ptData } = useProductTypes({ activo: true, pageSize: 200 })
  const productTypes = ptData?.items ?? []

  const reactivateMutation = useReactivateChargeableCharConfig()

  const [deleteTarget, setDeleteTarget] = useState<ChargeableCharConfig | null>(null)

  const totalPages = Math.max(1, Math.ceil(total / pageSize))
  const hasPrev = page > 1
  const hasNext = page < totalPages

  function handleReactivate(config: ChargeableCharConfig) {
    reactivateMutation.mutate(config.id, {
      onError: (err) => {
        toast.error(resolveReactivationError(err))
      },
    })
  }

  const columns = useMemo<ColumnDef<ChargeableCharConfig>[]>(
    () => [
      {
        accessorKey: 'productTypeId',
        header: 'Tipo de Producto',
        cell: ({ row }) => {
          const ptId = row.original.productTypeId
          if (ptId === null) return <span className="text-muted-foreground">Global</span>
          const pt = productTypes.find((p) => p.id === ptId)
          return <span>{pt?.nombre ?? `Tipo ${ptId}`}</span>
        },
      },
      {
        accessorKey: 'symbol',
        header: 'Símbolo',
        cell: ({ row }) => (
          <span className="font-mono text-lg">{row.original.symbol}</span>
        ),
      },
      {
        accessorKey: 'category',
        header: 'Categoría',
        cell: ({ row }) => (
          <Badge variant="secondary">
            {CATEGORY_LABELS[row.original.category] ?? row.original.category}
          </Badge>
        ),
      },
      {
        accessorKey: 'pricePerUnit',
        header: 'Precio/unidad',
        cell: ({ row }) => (
          <span>
            {new Intl.NumberFormat('es-AR', {
              minimumFractionDigits: 4,
              maximumFractionDigits: 4,
            }).format(row.original.pricePerUnit)}
          </span>
        ),
      },
      {
        accessorKey: 'validFrom',
        header: 'Desde',
        cell: ({ row }) => <span>{formatCivilDate(row.original.validFrom)}</span>,
      },
      {
        accessorKey: 'validTo',
        header: 'Hasta',
        cell: ({ row }) => (
          <span>
            {row.original.validTo ? formatCivilDate(row.original.validTo) : '—'}
          </span>
        ),
      },
      {
        accessorKey: 'isActive',
        header: 'Estado',
        cell: ({ row }) =>
          row.original.isActive ? (
            <Badge variant="secondary" className="bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200">
              Vigente
            </Badge>
          ) : (
            <Badge variant="secondary" className="bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-200">
              Cerrada
            </Badge>
          ),
      },
      {
        id: 'acciones',
        header: 'Acciones',
        cell: ({ row }) => {
          const config = row.original
          return (
            <div className="flex gap-1" onClick={(e) => e.stopPropagation()}>
              {config.isActive ? (
                <>
                  <Button
                    variant="outline"
                    size="sm"
                    onClick={() => onSchedulePrice(config)}
                    aria-label="Programar cambio de precio"
                  >
                    Programar precio
                  </Button>
                  <Button
                    variant="ghost"
                    size="sm"
                    onClick={() => onDeactivate(config)}
                    className="text-destructive hover:text-destructive"
                    aria-label="Desactivar"
                  >
                    Desactivar
                  </Button>
                </>
              ) : (
                <Button
                  variant="ghost"
                  size="sm"
                  onClick={() => handleReactivate(config)}
                  disabled={reactivateMutation.isPending && reactivateMutation.variables === config.id}
                  aria-label="Reactivar"
                >
                  Reactivar
                </Button>
              )}
              <Button
                variant="ghost"
                size="sm"
                onClick={() => setDeleteTarget(config)}
                className="text-destructive hover:text-destructive"
                aria-label="Eliminar"
              >
                Eliminar
              </Button>
            </div>
          )
        },
      },
    ],
    [productTypes, onSchedulePrice, onDeactivate, reactivateMutation],
  )

  return (
    <div className="space-y-4">
      {/* Filters */}
      <div className="flex flex-wrap gap-3 items-center">
        <ProductTypeSelect
          value={productTypeId}
          onValueChange={(v) => onProductTypeChange(v === null ? undefined : v)}
          showAllOption={true}
          allOptionLabel="Todos los tipos"
          globalOptionLabel="Global"
          placeholder="Todos los tipos"
          aria-label="Tipo de producto"
        />

        <div className="flex items-center gap-2">
          <Switch
            id="activeOnly"
            checked={activeOnly}
            onCheckedChange={onActiveOnlyChange}
            aria-label="Solo activos"
          />
          <Label htmlFor="activeOnly" className="text-sm">Solo activos</Label>
        </div>
      </div>

      <DataTable
        columns={columns}
        data={configs}
        getRowId={(row) => String(row.id)}
        emptyMessage="Todavía no hay caracteres tasables configurados."
      />

      {/* Pagination */}
      <div className="flex items-center justify-between pt-2">
        <span className="text-sm text-muted-foreground">
          {total} resultado{total !== 1 ? 's' : ''}
        </span>
        <div className="flex gap-2">
          <Button
            variant="outline"
            size="sm"
            disabled={!hasPrev}
            onClick={() => onPageChange(page - 1)}
            aria-label="Anterior"
          >
            Anterior
          </Button>
          <span className="flex items-center px-2 text-sm text-muted-foreground">
            {page} / {totalPages}
          </span>
          <Button
            variant="outline"
            size="sm"
            disabled={!hasNext}
            onClick={() => onPageChange(page + 1)}
            aria-label="Siguiente"
          >
            Siguiente
          </Button>
        </div>
      </div>

      {/* Delete confirmation dialog */}
      {deleteTarget && (
        <DeleteChargeableCharConfigDialog
          open={!!deleteTarget}
          onOpenChange={(open) => { if (!open) setDeleteTarget(null) }}
          configId={deleteTarget.id}
          symbol={deleteTarget.symbol}
        />
      )}
    </div>
  )
}
