import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogHeader,
  DialogTitle,
} from '@/components/ui/dialog';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { AdminLayout } from '@/features/admin/admin-layout';
import { ApiClientError, apiClient } from '@/lib/api-client';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { useLocation } from '@tanstack/react-router';
import { BarChart3, Pencil, Plus, RefreshCw, Trash2 } from 'lucide-react';
import { useState } from 'react';

type Plan = {
  code: string;
  name: string;
  price: number;
  rules: unknown;
  lastUpdatedAt: string;
  complexCount: number;
};

function PlanFormDialog({
  mode,
  plan,
  onClose,
}: {
  mode: 'create' | 'edit';
  plan?: Plan;
  onClose: () => void;
}) {
  const queryClient = useQueryClient();
  const [code, setCode] = useState(plan?.code ?? '');
  const [name, setName] = useState(plan?.name ?? '');
  const [price, setPrice] = useState(String(plan?.price ?? ''));

  const createMutation = useMutation({
    mutationFn: (data: { code: string; name: string; price: number; rules: object }) =>
      apiClient.admin.createPlan(data),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['admin-plans'] });
      onClose();
    },
  });

  const updateMutation = useMutation({
    mutationFn: (data: { name?: string; price?: number }) =>
      apiClient.admin.updatePlan(plan!.code, data),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['admin-plans'] });
      onClose();
    },
  });

  const isPending = createMutation.isPending || updateMutation.isPending;
  const error = createMutation.error ?? updateMutation.error;

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

    if (mode === 'create') {
      createMutation.mutate({
        code,
        name,
        price: Number.parseFloat(price),
        rules: {},
      });
    } else {
      updateMutation.mutate({
        name,
        price: Number.parseFloat(price),
      });
    }
  };

  return (
    <Dialog open onOpenChange={(open) => !open && onClose()}>
      <DialogContent className="rounded-2xl sm:max-w-md">
        <DialogHeader>
          <DialogTitle>{mode === 'create' ? 'Crear plan' : 'Editar plan'}</DialogTitle>
          <DialogDescription>
            {mode === 'create'
              ? 'Agregá un nuevo plan de suscripción.'
              : 'Actualizá los datos del plan.'}
          </DialogDescription>
        </DialogHeader>

        <form onSubmit={handleSubmit} className="space-y-4">
          {mode === 'create' && (
            <div className="space-y-2">
              <Label htmlFor="code">Código</Label>
              <Input
                id="code"
                value={code}
                onChange={(e) => setCode(e.target.value)}
                placeholder="pro"
                maxLength={10}
                required
              />
            </div>
          )}

          <div className="space-y-2">
            <Label htmlFor="name">Nombre</Label>
            <Input
              id="name"
              value={name}
              onChange={(e) => setName(e.target.value)}
              placeholder="Pro"
              maxLength={30}
              required
            />
          </div>

          <div className="space-y-2">
            <Label htmlFor="price">Precio</Label>
            <Input
              id="price"
              type="number"
              step="0.01"
              min="0"
              value={price}
              onChange={(e) => setPrice(e.target.value)}
              placeholder="29.99"
              required
            />
          </div>

          {error && (
            <p className="text-sm text-destructive">
              {error instanceof ApiClientError
                ? String(error.details ?? error.message)
                : error.message}
            </p>
          )}

          <div className="flex justify-end gap-3">
            <Button type="button" variant="outline" className="rounded-xl" onClick={onClose}>
              Cancelar
            </Button>
            <Button type="submit" className="rounded-xl" disabled={isPending}>
              {isPending ? 'Guardando...' : mode === 'create' ? 'Crear' : 'Guardar'}
            </Button>
          </div>
        </form>
      </DialogContent>
    </Dialog>
  );
}

function DeleteConfirmDialog({
  plan,
  onClose,
}: {
  plan: Plan;
  onClose: () => void;
}) {
  const queryClient = useQueryClient();
  const deleteMutation = useMutation({
    mutationFn: () => apiClient.admin.deletePlan(plan.code),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['admin-plans'] });
      onClose();
    },
  });

  return (
    <Dialog open onOpenChange={(open) => !open && onClose()}>
      <DialogContent className="rounded-2xl sm:max-w-md">
        <DialogHeader>
          <DialogTitle>Eliminar plan</DialogTitle>
          <DialogDescription>
            ¿Estás seguro de eliminar el plan <strong>{plan.name}</strong>?
            {plan.complexCount > 0 && (
              <span className="mt-2 block text-destructive">
                No se puede eliminar porque tiene {plan.complexCount} complejo
                {plan.complexCount > 1 ? 's' : ''} asignado{plan.complexCount > 1 ? 's' : ''}.
              </span>
            )}
          </DialogDescription>
        </DialogHeader>

        {deleteMutation.error && (
          <p className="text-sm text-destructive">
            {deleteMutation.error instanceof ApiClientError
              ? String(deleteMutation.error.details ?? deleteMutation.error.message)
              : deleteMutation.error.message}
          </p>
        )}

        <div className="flex justify-end gap-3">
          <Button type="button" variant="outline" className="rounded-xl" onClick={onClose}>
            Cancelar
          </Button>
          <Button
            type="button"
            variant="destructive"
            className="rounded-xl"
            onClick={() => deleteMutation.mutate()}
            disabled={deleteMutation.isPending || plan.complexCount > 0}
          >
            {deleteMutation.isPending ? 'Eliminando...' : 'Eliminar'}
          </Button>
        </div>
      </DialogContent>
    </Dialog>
  );
}

export function PlansPage() {
  const location = useLocation();
  const queryClient = useQueryClient();
  const [createOpen, setCreateOpen] = useState(false);
  const [editingPlan, setEditingPlan] = useState<Plan | null>(null);
  const [deletingPlan, setDeletingPlan] = useState<Plan | null>(null);

  const { data, isLoading } = useQuery({
    queryKey: ['admin-plans'],
    queryFn: () => apiClient.admin.listPlans(),
  });

  return (
    <AdminLayout currentPath={location.pathname}>
      <div className="mb-6 flex items-center justify-between">
        <div>
          <h1 className="text-2xl font-bold tracking-tight">Planes</h1>
          <p className="mt-1 text-sm text-muted-foreground">
            {data?.length ?? 0} planes de suscripción.
          </p>
        </div>

        <div className="flex gap-2">
          <Button
            variant="outline"
            size="icon"
            className="rounded-xl"
            onClick={() => queryClient.invalidateQueries({ queryKey: ['admin-plans'] })}
          >
            <RefreshCw className="size-4" />
          </Button>
          <Button className="rounded-xl" onClick={() => setCreateOpen(true)}>
            <Plus className="mr-2 size-4" />
            Nuevo plan
          </Button>
        </div>
      </div>

      {createOpen && <PlanFormDialog mode="create" onClose={() => setCreateOpen(false)} />}

      {editingPlan && (
        <PlanFormDialog mode="edit" plan={editingPlan} onClose={() => setEditingPlan(null)} />
      )}

      {deletingPlan && (
        <DeleteConfirmDialog plan={deletingPlan} onClose={() => setDeletingPlan(null)} />
      )}

      {isLoading ? (
        <div className="flex items-center justify-center py-20">
          <p className="text-sm text-muted-foreground">Cargando planes...</p>
        </div>
      ) : data?.length === 0 ? (
        <div className="flex flex-col items-center justify-center py-20">
          <BarChart3 className="mb-3 size-10 text-muted-foreground/50" />
          <p className="text-sm text-muted-foreground">No hay planes creados.</p>
        </div>
      ) : (
        <div className="overflow-hidden rounded-2xl border border-border/60">
          <table className="w-full">
            <thead>
              <tr className="border-b border-border/60 bg-muted/50">
                <th className="px-5 py-3 text-left text-xs font-semibold uppercase tracking-wider text-muted-foreground">
                  Código
                </th>
                <th className="px-5 py-3 text-left text-xs font-semibold uppercase tracking-wider text-muted-foreground">
                  Nombre
                </th>
                <th className="px-5 py-3 text-right text-xs font-semibold uppercase tracking-wider text-muted-foreground">
                  Precio
                </th>
                <th className="hidden px-5 py-3 text-center text-xs font-semibold uppercase tracking-wider text-muted-foreground sm:table-cell">
                  Complejos
                </th>
                <th className="px-5 py-3 text-right text-xs font-semibold uppercase tracking-wider text-muted-foreground">
                  Acciones
                </th>
              </tr>
            </thead>
            <tbody className="divide-y divide-border/40">
              {data?.map((plan) => (
                <tr key={plan.code} className="transition-colors hover:bg-accent/30">
                  <td className="px-5 py-4">
                    <Badge variant="secondary" className="font-mono text-xs">
                      {plan.code}
                    </Badge>
                  </td>
                  <td className="px-5 py-4 font-medium">{plan.name}</td>
                  <td className="px-5 py-4 text-right font-medium">
                    ${Number(plan.price).toFixed(2)}
                  </td>
                  <td className="hidden px-5 py-4 text-center text-sm text-muted-foreground sm:table-cell">
                    {plan.complexCount}
                  </td>
                  <td className="px-5 py-4 text-right">
                    <div className="flex justify-end gap-1">
                      <Button
                        variant="ghost"
                        size="icon"
                        className="size-8 rounded-lg"
                        onClick={() => setEditingPlan(plan)}
                      >
                        <Pencil className="size-3.5" />
                      </Button>
                      <Button
                        variant="ghost"
                        size="icon"
                        className="size-8 rounded-lg text-destructive hover:bg-destructive/10 hover:text-destructive"
                        onClick={() => setDeletingPlan(plan)}
                      >
                        <Trash2 className="size-3.5" />
                      </Button>
                    </div>
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      )}
    </AdminLayout>
  );
}
