'use client';

import { useCallback, useEffect, useState } from 'react';
import { api } from '@/lib/api-client';

interface PosStore {
  id: string;
  name: string;
  active: boolean;
}
interface PosTerminal {
  id: string;
  storeId: string;
  name: string;
  bindingCode: string | null;
  boundAt: string | null;
  status: string;
  settings?: {
    touchNavigationEnabled?: boolean;
    quickProductVariantIds?: Array<string | null>;
    lineDiscountsEnabled?: boolean;
  };
}
interface CatalogOption {
  variantId: string;
  name: string;
  sku: string;
}
interface PaymentMethod {
  id: string;
  storeId: string;
  code: string;
  label: string;
  kind: 'cash' | 'card' | 'other';
  active: boolean;
  sortOrder: number;
}
interface PosCashier {
  id: string;
  email: string;
  role: 'pos_cashier';
  active: boolean;
  deactivatedAt: string | null;
  deletedAt: string | null;
  createdAt: string;
  status: 'active' | 'inactive' | 'deleted';
}
interface ReceiptSettings {
  storeId: string;
  name: string;
  address: string;
  taxId: string;
  contactEmail: string;
  contactPhone: string;
  receiptHeader: string;
  receiptFooter: string;
  prefix: string;
  nextNumber: number;
  padding: number;
  returnPolicy: string;
}

const emptyReceipt: ReceiptSettings = {
  storeId: '',
  name: '',
  address: '',
  taxId: '',
  contactEmail: '',
  contactPhone: '',
  receiptHeader: '',
  receiptFooter: '',
  prefix: 'TPV',
  nextNumber: 1,
  padding: 6,
  returnPolicy: 'Se admiten devoluciones durante 15 días con el ticket de compra.',
};

export default function PosAdminPage() {
  const [stores, setStores] = useState<PosStore[]>([]);
  const [terminals, setTerminals] = useState<PosTerminal[]>([]);
  const [catalogOptions, setCatalogOptions] = useState<CatalogOption[]>([]);
  const [storeId, setStoreId] = useState('');
  const [terminalName, setTerminalName] = useState('');
  const [loading, setLoading] = useState(true);
  const [creating, setCreating] = useState(false);
  const [error, setError] = useState('');
  const [newCode, setNewCode] = useState('');
  const [copied, setCopied] = useState('');
  const [configuring, setConfiguring] = useState<PosTerminal | null>(null);
  const [touchEnabled, setTouchEnabled] = useState(true);
  const [discountsEnabled, setDiscountsEnabled] = useState(true);
  const [quickSlots, setQuickSlots] = useState<Array<string | null>>(
    Array.from({ length: 8 }, () => null),
  );
  const [savingTouch, setSavingTouch] = useState(false);
  const [touchMessage, setTouchMessage] = useState('');
  const [paymentMethods, setPaymentMethods] = useState<PaymentMethod[]>([]);
  const [cashiers, setCashiers] = useState<PosCashier[]>([]);
  const [newCashier, setNewCashier] = useState({ email: '', password: '' });
  const [savingCashier, setSavingCashier] = useState(false);
  const [cashierMessage, setCashierMessage] = useState('');
  const [newMethod, setNewMethod] = useState({
    code: '',
    label: '',
    kind: 'other' as PaymentMethod['kind'],
  });
  const [savingMethod, setSavingMethod] = useState(false);
  const [paymentMessage, setPaymentMessage] = useState('');
  const [receipt, setReceipt] = useState<ReceiptSettings>(emptyReceipt);
  const [savingReceipt, setSavingReceipt] = useState(false);
  const [receiptMessage, setReceiptMessage] = useState('');

  const loadStoreConfiguration = useCallback(async (selectedStoreId: string) => {
    if (!selectedStoreId) return;
    try {
      const [methodData, receiptData] = await Promise.all([
        api.get<{ items: PaymentMethod[] }>(
          `/api/pos/admin/payment-methods?storeId=${encodeURIComponent(selectedStoreId)}`,
        ),
        api.get<Partial<ReceiptSettings>>(
          `/api/pos/admin/receipt-settings?storeId=${encodeURIComponent(selectedStoreId)}`,
        ),
      ]);
      setPaymentMethods(methodData.items);
      setReceipt({ ...emptyReceipt, ...receiptData, storeId: selectedStoreId });
    } catch (err) {
      setError(err instanceof Error ? err.message : 'No se pudo cargar la configuración de cobro');
    }
  }, []);

  const load = useCallback(async () => {
    setLoading(true);
    setError('');
    try {
      const [storeData, terminalData, catalogData, userData] = await Promise.all([
        api.get<{ stores: PosStore[] }>('/api/pos/admin/stores'),
        api.get<{ terminals: PosTerminal[] }>('/api/pos/admin/terminals'),
        api.get<{ items: CatalogOption[] }>('/api/pos/admin/catalog-products'),
        api.get<{ items: Array<PosCashier | { role: string }> }>('/api/pos/users'),
      ]);
      setStores(storeData.stores);
      setTerminals(terminalData.terminals);
      setCatalogOptions(catalogData.items);
      setCashiers(userData.items.filter((item): item is PosCashier => item.role === 'pos_cashier'));
      const selected = storeId || storeData.stores.find((store) => store.active)?.id || '';
      setStoreId(selected);
      await loadStoreConfiguration(selected);
    } catch (err) {
      setError(err instanceof Error ? err.message : 'No se pudo cargar la configuración TPV');
    } finally {
      setLoading(false);
    }
  }, [loadStoreConfiguration, storeId]);

  useEffect(() => {
    void load();
  }, []); // eslint-disable-line react-hooks/exhaustive-deps

  const changeStore = (nextStoreId: string) => {
    setStoreId(nextStoreId);
    setReceiptMessage('');
    setPaymentMessage('');
    void loadStoreConfiguration(nextStoreId);
  };

  const createTerminal = async (event: React.FormEvent) => {
    event.preventDefault();
    setCreating(true);
    setError('');
    setNewCode('');
    try {
      const terminal = await api.post<PosTerminal>('/api/pos/admin/terminals', {
        storeId,
        name: terminalName.trim(),
      });
      setTerminalName('');
      setNewCode(terminal.bindingCode ?? '');
      await load();
    } catch (err) {
      setError(err instanceof Error ? err.message : 'No se pudo crear el terminal');
    } finally {
      setCreating(false);
    }
  };

  const openTouchConfig = (terminal: PosTerminal) => {
    setConfiguring(terminal);
    setTouchEnabled(terminal.settings?.touchNavigationEnabled !== false);
    setDiscountsEnabled(terminal.settings?.lineDiscountsEnabled !== false);
    const configured = terminal.settings?.quickProductVariantIds ?? [];
    setQuickSlots(Array.from({ length: 8 }, (_, slot) => configured[slot] ?? null));
    setTouchMessage('');
  };

  const saveTouchConfig = async () => {
    if (!configuring) return;
    setSavingTouch(true);
    setTouchMessage('');
    try {
      await api.patch(`/api/pos/admin/terminals/${configuring.id}/touch-config`, {
        touchNavigationEnabled: touchEnabled,
        lineDiscountsEnabled: discountsEnabled,
        quickProductVariantIds: quickSlots,
      });
      setTouchMessage('Configuración del terminal guardada');
      await load();
    } catch (err) {
      setTouchMessage(err instanceof Error ? err.message : 'No se pudo guardar');
    } finally {
      setSavingTouch(false);
    }
  };

  const createPaymentMethod = async (event: React.FormEvent) => {
    event.preventDefault();
    setSavingMethod(true);
    setPaymentMessage('');
    try {
      await api.post('/api/pos/admin/payment-methods', {
        storeId,
        code: newMethod.code.trim().toLowerCase(),
        label: newMethod.label.trim(),
        kind: newMethod.kind,
        active: true,
        sortOrder: paymentMethods.length,
      });
      setNewMethod({ code: '', label: '', kind: 'other' });
      setPaymentMessage('Forma de pago creada');
      await loadStoreConfiguration(storeId);
    } catch (err) {
      setPaymentMessage(err instanceof Error ? err.message : 'No se pudo crear la forma de pago');
    } finally {
      setSavingMethod(false);
    }
  };

  const togglePaymentMethod = async (method: PaymentMethod) => {
    setPaymentMessage('');
    try {
      await api.patch(`/api/pos/admin/payment-methods/${method.id}`, { active: !method.active });
      setPaymentMessage(method.active ? 'Forma de pago desactivada' : 'Forma de pago activada');
      await loadStoreConfiguration(storeId);
    } catch (err) {
      setPaymentMessage(err instanceof Error ? err.message : 'No se pudo actualizar');
    }
  };

  const createCashier = async (event: React.FormEvent) => {
    event.preventDefault();
    setSavingCashier(true);
    setCashierMessage('');
    try {
      await api.post('/api/pos/users', {
        email: newCashier.email.trim().toLowerCase(),
        password: newCashier.password,
        role: 'pos_cashier',
      });
      setNewCashier({ email: '', password: '' });
      setCashierMessage('Cajero creado');
      await load();
    } catch (err) {
      setCashierMessage(err instanceof Error ? err.message : 'No se pudo crear el cajero');
    } finally {
      setSavingCashier(false);
    }
  };

  const toggleCashier = async (cashier: PosCashier) => {
    const nextActive = !cashier.active;
    const action = nextActive ? 'reactivar' : 'desactivar';
    if (!window.confirm(`¿Quieres ${action} a ${cashier.email}?`)) return;
    setCashierMessage('');
    try {
      await api.patch(`/api/pos/users/${cashier.id}/status`, { active: nextActive });
      setCashierMessage(nextActive ? 'Cajero reactivado' : 'Cajero desactivado');
      await load();
    } catch (err) {
      setCashierMessage(err instanceof Error ? err.message : `No se pudo ${action} el cajero`);
    }
  };

  const deleteCashier = async (cashier: PosCashier) => {
    if (
      !window.confirm(
        `¿Eliminar definitivamente a ${cashier.email}? No podrá reactivarse. Su historial de ventas y caja se conservará.`,
      )
    )
      return;
    setCashierMessage('');
    try {
      await api.delete(`/api/pos/users/${cashier.id}`);
      setCashierMessage('Cajero eliminado; su histórico se conserva');
      await load();
    } catch (err) {
      setCashierMessage(err instanceof Error ? err.message : 'No se pudo eliminar el cajero');
    }
  };

  const saveReceipt = async (event: React.FormEvent) => {
    event.preventDefault();
    setSavingReceipt(true);
    setReceiptMessage('');
    try {
      await api.patch('/api/pos/admin/receipt-settings', receipt);
      setReceiptMessage('Datos y numeración del ticket guardados');
      await loadStoreConfiguration(storeId);
    } catch (err) {
      setReceiptMessage(err instanceof Error ? err.message : 'No se pudo guardar el ticket');
    } finally {
      setSavingReceipt(false);
    }
  };

  const copyCode = async (code: string) => {
    await navigator.clipboard.writeText(code);
    setCopied(code);
    window.setTimeout(() => setCopied(''), 2000);
  };

  return (
    <div className="space-y-6">
      <header>
        <h1 className="text-2xl font-bold text-gray-900">TPV</h1>
        <p className="mt-0.5 text-sm text-gray-500">
          Configura terminales táctiles, formas de pago y contenido fiscal del ticket.
        </p>
      </header>

      <label className="block max-w-md text-sm font-medium text-gray-700">
        Tienda que estás configurando
        <select
          value={storeId}
          onChange={(event) => changeStore(event.target.value)}
          className="mt-1 w-full rounded-xl border border-gray-300 bg-white px-3 py-2.5"
        >
          {stores
            .filter((store) => store.active)
            .map((store) => (
              <option key={store.id} value={store.id}>
                {store.name}
              </option>
            ))}
        </select>
      </label>

      <form onSubmit={createTerminal} className="rounded-xl border border-gray-200 bg-white p-6">
        <h2 className="mb-4 font-bold text-gray-900">Crear y vincular terminal</h2>
        <div className="flex flex-wrap items-end gap-4">
          <label className="min-w-64 flex-1 text-sm font-medium text-gray-700">
            Nombre del terminal
            <input
              value={terminalName}
              onChange={(event) => setTerminalName(event.target.value)}
              required
              maxLength={100}
              placeholder="Caja principal"
              className="mt-1 w-full rounded-xl border border-gray-300 px-3 py-2.5"
            />
          </label>
          <button
            disabled={creating || !storeId || !terminalName.trim()}
            className="rounded-xl bg-[#2D6A4F] px-5 py-2.5 text-sm font-semibold text-white disabled:opacity-50"
          >
            {creating ? 'Creando…' : 'Crear terminal'}
          </button>
        </div>
        {newCode && (
          <p className="mt-4 rounded-lg bg-green-50 p-3 text-sm text-green-800">
            Código: <strong className="font-mono text-lg tracking-widest">{newCode}</strong>
          </p>
        )}
        {error && <p className="mt-4 text-sm text-red-600">{error}</p>}
      </form>

      <section className="overflow-hidden rounded-xl border border-gray-200 bg-white">
        <div className="border-b px-6 py-4">
          <h2 className="font-bold">Terminales</h2>
        </div>
        {loading ? (
          <p className="p-6 text-sm text-gray-500">Cargando…</p>
        ) : (
          <div className="overflow-x-auto">
            <table className="w-full text-sm">
              <thead className="bg-gray-50 text-left text-xs uppercase text-gray-500">
                <tr>
                  <th className="px-4 py-3">Nombre</th>
                  <th className="px-4 py-3">Código</th>
                  <th className="px-4 py-3">Estado</th>
                  <th className="px-4 py-3">Vinculado</th>
                  <th className="px-4 py-3">Configuración</th>
                </tr>
              </thead>
              <tbody className="divide-y">
                {terminals
                  .filter((terminal) => terminal.storeId === storeId)
                  .map((terminal) => (
                    <tr key={terminal.id}>
                      <td className="px-4 py-3 font-medium">{terminal.name}</td>
                      <td className="px-4 py-3">
                        <button
                          type="button"
                          onClick={() =>
                            terminal.bindingCode && void copyCode(terminal.bindingCode)
                          }
                          disabled={!terminal.bindingCode}
                          className="rounded-lg bg-gray-100 px-3 py-1 font-mono"
                        >
                          {copied === terminal.bindingCode
                            ? 'Copiado'
                            : (terminal.bindingCode ?? '—')}
                        </button>
                      </td>
                      <td className="px-4 py-3">{terminal.status}</td>
                      <td className="px-4 py-3">{terminal.boundAt ? 'Sí' : 'No'}</td>
                      <td className="px-4 py-3">
                        <button
                          type="button"
                          onClick={() => openTouchConfig(terminal)}
                          className="rounded-lg border border-[#2D6A4F] px-3 py-1.5 text-xs font-semibold text-[#2D6A4F]"
                        >
                          Configurar terminal
                        </button>
                      </td>
                    </tr>
                  ))}
              </tbody>
            </table>
          </div>
        )}
      </section>

      <section className="rounded-xl border border-gray-200 bg-white p-6">
        <div>
          <h2 className="font-bold">Cajeros</h2>
          <p className="mt-1 text-sm text-gray-500">
            Desactivar corta el acceso y permite reactivarlo. Eliminar es irreversible, pero
            conserva la atribución histórica de ventas y sesiones de caja.
          </p>
        </div>
        <form
          onSubmit={createCashier}
          className="mt-5 grid gap-3 rounded-xl bg-gray-50 p-4 md:grid-cols-[1fr_1fr_auto] md:items-end"
        >
          <label className="text-sm font-medium">
            Email
            <input
              type="email"
              value={newCashier.email}
              onChange={(event) => setNewCashier({ ...newCashier, email: event.target.value })}
              required
              className="mt-1 w-full rounded-xl border px-3 py-2.5"
            />
          </label>
          <label className="text-sm font-medium">
            Contraseña inicial
            <input
              type="password"
              value={newCashier.password}
              onChange={(event) => setNewCashier({ ...newCashier, password: event.target.value })}
              required
              minLength={8}
              maxLength={200}
              className="mt-1 w-full rounded-xl border px-3 py-2.5"
            />
          </label>
          <button
            disabled={savingCashier}
            className="rounded-xl bg-[#2D6A4F] px-5 py-2.5 text-sm font-semibold text-white disabled:opacity-50"
          >
            {savingCashier ? 'Creando…' : 'Crear cajero'}
          </button>
        </form>
        <div className="mt-5 overflow-x-auto rounded-xl border">
          <table className="w-full text-sm">
            <thead className="bg-gray-50 text-left text-xs uppercase text-gray-500">
              <tr>
                <th className="px-4 py-3">Email</th>
                <th className="px-4 py-3">Estado</th>
                <th className="px-4 py-3">Creado</th>
                <th className="px-4 py-3 text-right">Acciones</th>
              </tr>
            </thead>
            <tbody className="divide-y">
              {cashiers.map((cashier) => (
                <tr key={cashier.id} className={cashier.status === 'deleted' ? 'opacity-60' : ''}>
                  <td className="px-4 py-3 font-medium">{cashier.email}</td>
                  <td className="px-4 py-3">
                    <span
                      className={`rounded-full px-2.5 py-1 text-xs font-semibold ${
                        cashier.status === 'active'
                          ? 'bg-green-100 text-green-800'
                          : cashier.status === 'inactive'
                            ? 'bg-amber-100 text-amber-800'
                            : 'bg-gray-200 text-gray-700'
                      }`}
                    >
                      {cashier.status === 'active'
                        ? 'Activo'
                        : cashier.status === 'inactive'
                          ? 'Inactivo'
                          : 'Eliminado'}
                    </span>
                  </td>
                  <td className="px-4 py-3 text-gray-500">
                    {new Date(cashier.createdAt).toLocaleDateString('es-ES')}
                  </td>
                  <td className="px-4 py-3">
                    {cashier.status !== 'deleted' && (
                      <div className="flex justify-end gap-2">
                        <button
                          type="button"
                          onClick={() => void toggleCashier(cashier)}
                          className="rounded-lg border px-3 py-2 text-xs font-semibold"
                        >
                          {cashier.active ? 'Desactivar' : 'Reactivar'}
                        </button>
                        <button
                          type="button"
                          onClick={() => void deleteCashier(cashier)}
                          className="rounded-lg border border-red-200 px-3 py-2 text-xs font-semibold text-red-700"
                        >
                          Eliminar
                        </button>
                      </div>
                    )}
                  </td>
                </tr>
              ))}
              {!loading && cashiers.length === 0 && (
                <tr>
                  <td colSpan={4} className="px-4 py-8 text-center text-gray-500">
                    No hay cajeros configurados.
                  </td>
                </tr>
              )}
            </tbody>
          </table>
        </div>
        {cashierMessage && <p className="mt-3 text-sm">{cashierMessage}</p>}
      </section>

      {configuring && (
        <section className="rounded-xl border border-gray-200 bg-white p-6">
          <div className="flex justify-between">
            <div>
              <h2 className="font-bold">Interfaz táctil · {configuring.name}</h2>
              <p className="mt-1 text-sm text-gray-500">
                Elige hasta ocho productos rápidos y las funciones disponibles en esta caja.
              </p>
            </div>
            <button type="button" onClick={() => setConfiguring(null)} aria-label="Cerrar">
              ✕
            </button>
          </div>
          <div className="mt-5 grid gap-3 md:grid-cols-2">
            <label className="flex items-center gap-3 rounded-xl bg-gray-50 p-4 text-sm font-medium">
              <input
                type="checkbox"
                checked={touchEnabled}
                onChange={(event) => setTouchEnabled(event.target.checked)}
                className="h-5 w-5 accent-[#2D6A4F]"
              />{' '}
              Navegación táctil por categorías
            </label>
            <label className="flex items-center gap-3 rounded-xl bg-gray-50 p-4 text-sm font-medium">
              <input
                type="checkbox"
                checked={discountsEnabled}
                onChange={(event) => setDiscountsEnabled(event.target.checked)}
                className="h-5 w-5 accent-[#2D6A4F]"
              />{' '}
              Permitir descuentos por línea
            </label>
          </div>
          <p className="mt-2 text-xs text-gray-500">
            Desactiva descuentos para terminales de autopago.
          </p>
          <div className="mt-5 grid gap-4 md:grid-cols-2 xl:grid-cols-4">
            {quickSlots.map((variantId, slot) => (
              <label key={slot} className="text-sm font-medium text-gray-700">
                Producto rápido {slot + 1}
                <select
                  value={variantId ?? ''}
                  onChange={(event) =>
                    setQuickSlots((current) =>
                      current.map((value, index) =>
                        index === slot ? event.target.value || null : value,
                      ),
                    )
                  }
                  className="mt-1 w-full rounded-xl border bg-white px-3 py-2.5"
                >
                  <option value="">Sin asignar</option>
                  {catalogOptions.map((product) => (
                    <option key={product.variantId} value={product.variantId}>
                      {product.name} · {product.sku}
                    </option>
                  ))}
                </select>
              </label>
            ))}
          </div>
          <div className="mt-5 flex items-center gap-4">
            <button
              type="button"
              onClick={() => void saveTouchConfig()}
              disabled={savingTouch}
              className="rounded-xl bg-[#2D6A4F] px-5 py-2.5 text-sm font-semibold text-white disabled:opacity-50"
            >
              {savingTouch ? 'Guardando…' : 'Guardar terminal'}
            </button>
            {touchMessage && <p className="text-sm">{touchMessage}</p>}
          </div>
        </section>
      )}

      <section className="rounded-xl border border-gray-200 bg-white p-6">
        <div>
          <h2 className="font-bold">Formas de pago</h2>
          <p className="mt-1 text-sm text-gray-500">
            Crea Bizum, Stripe, Apple Pay u otro método. “Tarjeta” y “otro” se registran
            manualmente; no activan una pasarela externa.
          </p>
        </div>
        <div className="mt-4 grid gap-3 md:grid-cols-2 xl:grid-cols-3">
          {paymentMethods.map((method) => (
            <div
              key={method.id}
              className={`flex items-center justify-between rounded-xl border p-4 ${method.active ? 'border-green-200 bg-green-50' : 'border-gray-200 bg-gray-50 opacity-70'}`}
            >
              <div>
                <strong className="block">{method.label}</strong>
                <span className="text-xs text-gray-500">
                  {method.code} · {method.kind}
                </span>
              </div>
              <button
                type="button"
                onClick={() => void togglePaymentMethod(method)}
                className="rounded-lg border bg-white px-3 py-2 text-xs font-semibold"
              >
                {method.active ? 'Desactivar' : 'Activar'}
              </button>
            </div>
          ))}
        </div>
        <form
          onSubmit={createPaymentMethod}
          className="mt-5 grid gap-3 rounded-xl bg-gray-50 p-4 md:grid-cols-[1fr_1fr_1fr_auto] md:items-end"
        >
          <label className="text-sm font-medium">
            Código
            <input
              value={newMethod.code}
              onChange={(event) =>
                setNewMethod({
                  ...newMethod,
                  code: event.target.value.toLowerCase().replace(/[^a-z0-9_-]/g, ''),
                })
              }
              required
              maxLength={32}
              placeholder="bizum"
              className="mt-1 w-full rounded-xl border px-3 py-2.5"
            />
          </label>
          <label className="text-sm font-medium">
            Nombre visible
            <input
              value={newMethod.label}
              onChange={(event) => setNewMethod({ ...newMethod, label: event.target.value })}
              required
              maxLength={64}
              placeholder="Bizum"
              className="mt-1 w-full rounded-xl border px-3 py-2.5"
            />
          </label>
          <label className="text-sm font-medium">
            Tipo
            <select
              value={newMethod.kind}
              onChange={(event) =>
                setNewMethod({ ...newMethod, kind: event.target.value as PaymentMethod['kind'] })
              }
              className="mt-1 w-full rounded-xl border bg-white px-3 py-2.5"
            >
              <option value="cash">Efectivo</option>
              <option value="card">Tarjeta</option>
              <option value="other">Otro</option>
            </select>
          </label>
          <button
            disabled={savingMethod}
            className="rounded-xl bg-[#2D6A4F] px-5 py-2.5 text-sm font-semibold text-white disabled:opacity-50"
          >
            Añadir
          </button>
        </form>
        {paymentMessage && <p className="mt-3 text-sm">{paymentMessage}</p>}
      </section>

      <form onSubmit={saveReceipt} className="rounded-xl border border-gray-200 bg-white p-6">
        <div>
          <h2 className="font-bold">Empresa, numeración y política del ticket</h2>
          <p className="mt-1 text-sm text-gray-500">
            Estos datos se congelan en cada ticket emitido.
          </p>
        </div>
        <div className="mt-5 grid gap-4 md:grid-cols-2 xl:grid-cols-3">
          <Field
            label="Razón social / nombre"
            value={receipt.name}
            onChange={(value) => setReceipt({ ...receipt, name: value })}
            required
          />
          <Field
            label="NIF / CIF"
            value={receipt.taxId}
            onChange={(value) => setReceipt({ ...receipt, taxId: value })}
          />
          <Field
            label="Dirección"
            value={receipt.address}
            onChange={(value) => setReceipt({ ...receipt, address: value })}
          />
          <Field
            label="Email"
            type="email"
            value={receipt.contactEmail}
            onChange={(value) => setReceipt({ ...receipt, contactEmail: value })}
          />
          <Field
            label="Teléfono"
            value={receipt.contactPhone}
            onChange={(value) => setReceipt({ ...receipt, contactPhone: value })}
          />
          <Field
            label="Cabecera"
            value={receipt.receiptHeader}
            onChange={(value) => setReceipt({ ...receipt, receiptHeader: value })}
          />
          <Field
            label="Pie"
            value={receipt.receiptFooter}
            onChange={(value) => setReceipt({ ...receipt, receiptFooter: value })}
          />
          <Field
            label="Prefijo de ticket"
            value={receipt.prefix}
            onChange={(value) =>
              setReceipt({ ...receipt, prefix: value.toUpperCase().replace(/[^A-Z0-9_-]/g, '') })
            }
            required
          />
          <Field
            label="Próximo número"
            type="number"
            value={String(receipt.nextNumber)}
            onChange={(value) => setReceipt({ ...receipt, nextNumber: Number(value) })}
            required
            min={1}
          />
          <Field
            label="Dígitos (relleno)"
            type="number"
            value={String(receipt.padding)}
            onChange={(value) => setReceipt({ ...receipt, padding: Number(value) })}
            required
            min={1}
            max={12}
          />
        </div>
        <label className="mt-4 block text-sm font-medium">
          Política de devolución
          <textarea
            value={receipt.returnPolicy}
            onChange={(event) => setReceipt({ ...receipt, returnPolicy: event.target.value })}
            required
            maxLength={2000}
            rows={3}
            className="mt-1 w-full rounded-xl border px-3 py-2.5"
          />
        </label>
        <div className="mt-5 flex items-center gap-4">
          <button
            disabled={savingReceipt}
            className="rounded-xl bg-[#2D6A4F] px-5 py-2.5 text-sm font-semibold text-white disabled:opacity-50"
          >
            {savingReceipt ? 'Guardando…' : 'Guardar ticket'}
          </button>
          {receiptMessage && <p className="text-sm">{receiptMessage}</p>}
        </div>
      </form>
    </div>
  );
}

function Field({
  label,
  value,
  onChange,
  type = 'text',
  required = false,
  min,
  max,
}: {
  label: string;
  value: string;
  onChange: (value: string) => void;
  type?: string;
  required?: boolean;
  min?: number;
  max?: number;
}) {
  return (
    <label className="text-sm font-medium text-gray-700">
      {label}
      <input
        type={type}
        value={value}
        onChange={(event) => onChange(event.target.value)}
        required={required}
        min={min}
        max={max}
        className="mt-1 w-full rounded-xl border border-gray-300 px-3 py-2.5"
      />
    </label>
  );
}
