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 {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select';
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, X } from 'lucide-react';
import { useState } from 'react';

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

type PriceOverride = {
  country: string;
  amount: string;
  currency: string;
};

type PlanFormRules = {
  limits: {
    maxCourts: number;
    maxBookingsPerDay: number;
    maxActiveUsers: number | '';
    maxSports: number | '';
  };
  features: {
    onlinePayments: boolean;
    publicBookingPage: boolean;
    advancedReports: boolean;
    whatsappReminders: boolean;
    fixedSlots: boolean;
  };
  policies: {
    maxAdvanceBookingDays: number | '';
    minCancellationNoticeHours: number | '';
    allowOverbooking: boolean;
  };
};

function initOverrides(rules: unknown): PriceOverride[] {
  const r = rules as Record<string, unknown> | null | undefined;
  const pricing = r?.pricing as Record<string, unknown> | undefined;
  const overrides = pricing?.overrides as
    | Record<string, { amount: number; currency: string }>
    | undefined;
  if (!overrides) return [];
  return Object.entries(overrides).map(([country, data]) => ({
    country,
    amount: String(data.amount),
    currency: data.currency,
  }));
}

function getDefaultRules(): PlanFormRules {
  return {
    limits: {
      maxCourts: 10,
      maxBookingsPerDay: 100,
      maxActiveUsers: '',
      maxSports: '',
    },
    features: {
      onlinePayments: false,
      publicBookingPage: false,
      advancedReports: false,
      whatsappReminders: false,
      fixedSlots: false,
    },
    policies: {
      maxAdvanceBookingDays: '',
      minCancellationNoticeHours: '',
      allowOverbooking: false,
    },
  };
}

function initRules(plan?: Plan): PlanFormRules {
  if (!plan) return getDefaultRules();
  const r = plan.rules as Record<string, unknown> | null | undefined;
  const limits = r?.limits as Record<string, unknown> | undefined;
  const features = r?.features as Record<string, unknown> | undefined;
  const policies = r?.policies as Record<string, unknown> | undefined;

  return {
    limits: {
      maxCourts: (limits?.maxCourts as number) ?? 10,
      maxBookingsPerDay: (limits?.maxBookingsPerDay as number) ?? 100,
      maxActiveUsers: (limits?.maxActiveUsers as number | undefined) ?? '',
      maxSports: (limits?.maxSports as number | undefined) ?? '',
    },
    features: {
      onlinePayments: (features?.onlinePayments as boolean) ?? false,
      publicBookingPage: (features?.publicBookingPage as boolean) ?? false,
      advancedReports: (features?.advancedReports as boolean) ?? false,
      whatsappReminders: (features?.whatsappReminders as boolean) ?? false,
      fixedSlots: (features?.fixedSlots as boolean) ?? false,
    },
    policies: {
      maxAdvanceBookingDays: (policies?.maxAdvanceBookingDays as number | undefined) ?? '',
      minCancellationNoticeHours:
        (policies?.minCancellationNoticeHours as number | undefined) ?? '',
      allowOverbooking: (policies?.allowOverbooking as boolean) ?? false,
    },
  };
}

function buildRulesData(formRules: PlanFormRules, priceOverrides: PriceOverride[]): unknown {
  const validOverrides = priceOverrides.filter((o) => o.country.trim());
  const { limits, features, policies } = formRules;

  const rules: Record<string, unknown> = {
    version: validOverrides.length > 0 ? 'v2' : 'v1',
    limits: {
      maxCourts: limits.maxCourts,
      maxBookingsPerDay: limits.maxBookingsPerDay,
      ...(limits.maxActiveUsers !== '' && { maxActiveUsers: limits.maxActiveUsers }),
      ...(limits.maxSports !== '' && { maxSports: limits.maxSports }),
    },
    features,
    policies: {
      ...(policies.maxAdvanceBookingDays !== '' && {
        maxAdvanceBookingDays: policies.maxAdvanceBookingDays,
      }),
      ...(policies.minCancellationNoticeHours !== '' && {
        minCancellationNoticeHours: policies.minCancellationNoticeHours,
      }),
      allowOverbooking: policies.allowOverbooking,
    },
  };

  if (validOverrides.length > 0) {
    const overrides: Record<string, { amount: number; currency: string }> = {};
    for (const o of validOverrides) {
      overrides[o.country.trim().toUpperCase()] = {
        amount: Number.parseFloat(o.amount),
        currency: o.currency,
      };
    }
    rules.pricing = { overrides };
  }

  return rules;
}

const TABS = [
  { id: 'basico', label: 'Básico' },
  { id: 'limites', label: 'Límites' },
  { id: 'features', label: 'Funcionalidades' },
  { id: 'policies', label: 'Políticas' },
  { id: 'pricing', label: 'Precios x país' },
] as const;

function Toggle({
  checked,
  onChange,
  label,
}: {
  checked: boolean;
  onChange: (v: boolean) => void;
  label: string;
}) {
  return (
    <button
      type="button"
      role="switch"
      aria-checked={checked}
      onClick={() => onChange(!checked)}
      className={`relative inline-flex h-6 w-10 shrink-0 items-center rounded-full transition-colors ${
        checked ? 'bg-primary' : 'bg-input'
      }`}
    >
      <span
        className={`inline-block size-4 rounded-full bg-white shadow-sm transition-transform ${
          checked ? 'translate-x-5' : 'translate-x-1'
        }`}
      />
      <span className="sr-only">{label}</span>
    </button>
  );
}

function PlanFormDialog({
  mode,
  plan,
  onClose,
}: {
  mode: 'create' | 'edit';
  plan?: Plan;
  onClose: () => void;
}) {
  const queryClient = useQueryClient();
  const [activeTab, setActiveTab] = useState('basico');
  const [code, setCode] = useState(plan?.code ?? '');
  const [name, setName] = useState(plan?.name ?? '');
  const [price, setPrice] = useState(String(plan?.price ?? ''));
  const [formRules, setFormRules] = useState<PlanFormRules>(() => initRules(plan));
  const [priceOverrides, setPriceOverrides] = useState<PriceOverride[]>(() =>
    mode === 'edit' && plan ? initOverrides(plan.rules) : []
  );

  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; rules?: unknown }) =>
      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;

  function updateRule<S extends keyof PlanFormRules>(
    section: S,
    field: keyof PlanFormRules[S],
    value: PlanFormRules[S][keyof PlanFormRules[S]]
  ) {
    setFormRules((prev) => ({
      ...prev,
      [section]: { ...prev[section], [field]: value },
    }));
  }

  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault();
    const rules = buildRulesData(formRules, priceOverrides);

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

  const addOverride = () => {
    setPriceOverrides((prev) => [...prev, { country: '', amount: '', currency: 'ARS' }]);
  };

  const removeOverride = (index: number) => {
    setPriceOverrides((prev) => prev.filter((_, i) => i !== index));
  };

  const updateOverride = (index: number, field: keyof PriceOverride, value: string) => {
    setPriceOverrides((prev) => prev.map((o, i) => (i === index ? { ...o, [field]: value } : o)));
  };

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

        <form onSubmit={handleSubmit} className="space-y-5">
          <div className="-mx-6 flex gap-0 border-b border-border/60 px-6">
            {TABS.map((tab) => (
              <button
                key={tab.id}
                type="button"
                onClick={() => setActiveTab(tab.id)}
                className={`-mb-px border-b-2 px-3 pb-2 pt-1 text-sm font-medium transition-colors ${
                  activeTab === tab.id
                    ? 'border-primary text-primary'
                    : 'border-transparent text-muted-foreground hover:text-foreground'
                }`}
              >
                {tab.label}
              </button>
            ))}
          </div>

          {activeTab === 'basico' && (
            <div 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="grid grid-cols-2 gap-4">
                <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 USD
                    <span className="text-xs text-muted-foreground">(fallback global)</span>
                  </Label>
                  <Input
                    id="price"
                    type="number"
                    step="0.01"
                    min="0"
                    value={price}
                    onChange={(e) => setPrice(e.target.value)}
                    placeholder="29.99"
                    required
                  />
                </div>
              </div>
            </div>
          )}

          {activeTab === 'limites' && (
            <div className="space-y-4">
              <div className="grid grid-cols-2 gap-4">
                <div className="space-y-2">
                  <Label htmlFor="maxCourts">Máx. canchas</Label>
                  <Input
                    id="maxCourts"
                    type="number"
                    min="1"
                    value={formRules.limits.maxCourts}
                    onChange={(e) => updateRule('limits', 'maxCourts', Number(e.target.value))}
                    required
                  />
                </div>
                <div className="space-y-2">
                  <Label htmlFor="maxBookingsPerDay">Máx. turnos/día</Label>
                  <Input
                    id="maxBookingsPerDay"
                    type="number"
                    min="1"
                    value={formRules.limits.maxBookingsPerDay}
                    onChange={(e) =>
                      updateRule('limits', 'maxBookingsPerDay', Number(e.target.value))
                    }
                    required
                  />
                </div>
                <div className="space-y-2">
                  <Label htmlFor="maxActiveUsers">
                    Máx. usuarios activos
                    <span className="text-xs text-muted-foreground">(opcional)</span>
                  </Label>
                  <Input
                    id="maxActiveUsers"
                    type="number"
                    min="1"
                    value={formRules.limits.maxActiveUsers}
                    onChange={(e) =>
                      updateRule(
                        'limits',
                        'maxActiveUsers',
                        e.target.value === '' ? '' : Number(e.target.value)
                      )
                    }
                    placeholder="Ilimitado"
                  />
                </div>
                <div className="space-y-2">
                  <Label htmlFor="maxSports">
                    Máx. deportes
                    <span className="text-xs text-muted-foreground">(opcional)</span>
                  </Label>
                  <Input
                    id="maxSports"
                    type="number"
                    min="1"
                    value={formRules.limits.maxSports}
                    onChange={(e) =>
                      updateRule(
                        'limits',
                        'maxSports',
                        e.target.value === '' ? '' : Number(e.target.value)
                      )
                    }
                    placeholder="Ilimitado"
                  />
                </div>
              </div>
            </div>
          )}

          {activeTab === 'features' && (
            <div className="space-y-4">
              {(
                [
                  ['onlinePayments', 'Pagos online'],
                  ['publicBookingPage', 'Página de reservas pública'],
                  ['advancedReports', 'Reportes avanzados'],
                  ['whatsappReminders', 'Recordatorios por WhatsApp'],
                  ['fixedSlots', 'Turnos fijos'],
                ] as const
              ).map(([key, label]) => (
                <div key={key} className="flex items-center justify-between">
                  <Label className="cursor-pointer">{label}</Label>
                  <Toggle
                    checked={formRules.features[key]}
                    onChange={(v) => updateRule('features', key, v)}
                    label={label}
                  />
                </div>
              ))}
            </div>
          )}

          {activeTab === 'policies' && (
            <div className="space-y-4">
              <div className="grid grid-cols-2 gap-4">
                <div className="space-y-2">
                  <Label htmlFor="maxAdvanceBookingDays">
                    Anticipación máx. (días)
                    <span className="text-xs text-muted-foreground">(opcional)</span>
                  </Label>
                  <Input
                    id="maxAdvanceBookingDays"
                    type="number"
                    min="1"
                    value={formRules.policies.maxAdvanceBookingDays}
                    onChange={(e) =>
                      updateRule(
                        'policies',
                        'maxAdvanceBookingDays',
                        e.target.value === '' ? '' : Number(e.target.value)
                      )
                    }
                    placeholder="Sin límite"
                  />
                </div>
                <div className="space-y-2">
                  <Label htmlFor="minCancellationNoticeHours">
                    Cancelación mín. (horas)
                    <span className="text-xs text-muted-foreground">(opcional)</span>
                  </Label>
                  <Input
                    id="minCancellationNoticeHours"
                    type="number"
                    min="0"
                    value={formRules.policies.minCancellationNoticeHours}
                    onChange={(e) =>
                      updateRule(
                        'policies',
                        'minCancellationNoticeHours',
                        e.target.value === '' ? '' : Number(e.target.value)
                      )
                    }
                    placeholder="Sin restricción"
                  />
                </div>
              </div>
              <div className="flex items-center justify-between">
                <Label className="cursor-pointer" htmlFor="allowOverbooking">
                  Permitir sobreventa
                </Label>
                <Toggle
                  checked={formRules.policies.allowOverbooking}
                  onChange={(v) => updateRule('policies', 'allowOverbooking', v)}
                  label="Permitir sobreventa"
                />
              </div>
            </div>
          )}

          {activeTab === 'pricing' && (
            <div className="space-y-3">
              <div className="flex items-center justify-between">
                <Label>Precios por país</Label>
                <Button
                  type="button"
                  variant="outline"
                  size="sm"
                  className="rounded-xl"
                  onClick={addOverride}
                >
                  <Plus className="mr-1 size-3" />
                  Agregar
                </Button>
              </div>

              {priceOverrides.length === 0 && (
                <p className="text-sm text-muted-foreground">
                  Sin precios personalizados. Se usa el precio global USD.
                </p>
              )}

              {priceOverrides.map((override, index) => (
                <div key={index} className="flex items-end gap-2">
                  <div className="flex-1 space-y-1">
                    <Label className="text-xs">País</Label>
                    <Input
                      value={override.country}
                      onChange={(e) => updateOverride(index, 'country', e.target.value)}
                      placeholder="AR"
                      maxLength={2}
                      className="uppercase"
                    />
                  </div>
                  <div className="flex-1 space-y-1">
                    <Label className="text-xs">Monto</Label>
                    <Input
                      type="number"
                      step="0.01"
                      min="0"
                      value={override.amount}
                      onChange={(e) => updateOverride(index, 'amount', e.target.value)}
                      placeholder="14999"
                    />
                  </div>
                  <div className="w-24 space-y-1">
                    <Label className="text-xs">Moneda</Label>
                    <Select
                      value={override.currency}
                      onValueChange={(v) => updateOverride(index, 'currency', v)}
                    >
                      <SelectTrigger>
                        <SelectValue />
                      </SelectTrigger>
                      <SelectContent>
                        <SelectItem value="USD">USD</SelectItem>
                        <SelectItem value="ARS">ARS</SelectItem>
                      </SelectContent>
                    </Select>
                  </div>
                  <Button
                    type="button"
                    variant="ghost"
                    size="icon"
                    className="size-9 shrink-0 rounded-lg text-destructive hover:bg-destructive/10"
                    onClick={() => removeOverride(index)}
                  >
                    <X className="size-3.5" />
                  </Button>
                </div>
              ))}
            </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) => {
                const rules = plan.rules as Record<string, unknown> | null;
                const pricing = rules?.pricing as Record<string, unknown> | undefined;
                const overrides = pricing?.overrides as Record<string, unknown> | undefined;
                const overrideCountries = overrides ? Object.keys(overrides) : [];

                return (
                  <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">
                      <div className="flex flex-col items-end gap-1">
                        <span className="font-medium">${Number(plan.price).toFixed(2)} USD</span>
                        {overrideCountries.length > 0 && (
                          <div className="flex flex-wrap gap-1">
                            {overrideCountries.map((country) => (
                              <Badge key={country} variant="secondary" className="text-xs">
                                {country}
                              </Badge>
                            ))}
                          </div>
                        )}
                      </div>
                    </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>
  );
}
