'use client';

import { useEffect, useMemo, useState } from 'react';
import { posApi } from '@/lib/api-client';
import { formatPrice } from '@/lib/money';
import { generateIdempotencyKey } from '@/lib/idempotency';
import type { PosReceipt, PosSaleResponse } from '@/types/checkout';

interface OrderItem {
  id: string;
  name: string;
  quantity: number;
  returnedQuantity: number;
  freeItem: boolean;
  unitPriceCents: number;
  discountCents: number;
}

interface ReturnModalProps {
  receipt: PosReceipt;
  orderId: string;
  cashSessionId: string;
  terminalId: string;
  onClose: () => void;
  onReturned: (newReceipt: PosReceipt) => void;
}

export default function ReturnModal({
  receipt,
  orderId,
  cashSessionId,
  terminalId,
  onClose,
  onReturned,
}: ReturnModalProps) {
  const [items, setItems] = useState<OrderItem[]>([]);
  const [lines, setLines] = useState<Record<string, number>>({});
  const [reason, setReason] = useState('Cambio/devolución');
  const [error, setError] = useState('');
  const [loading, setLoading] = useState(true);
  const [saving, setSaving] = useState(false);

  useEffect(() => {
    void (async () => {
      try {
        const data = await posApi.listOrderItems<{ items: OrderItem[] }>(orderId);
        setItems(
          data.items.map((item) => ({
            id: item.id,
            name: item.name,
            quantity: item.quantity,
            returnedQuantity: item.returnedQuantity,
            freeItem: item.freeItem,
            unitPriceCents: item.unitPriceCents,
            discountCents: item.discountCents,
          })),
        );
        setLines(
          Object.fromEntries(data.items.map((item) => [item.id, 0])),
        );
      } catch (err) {
        setError(err instanceof Error ? err.message : 'No se pudieron cargar las líneas');
      } finally {
        setLoading(false);
      }
    })();
  }, [orderId]);

  const totalRefund = useMemo(() => {
    return items.reduce((sum, item) => {
      const requested = lines[item.id] ?? 0;
      if (requested <= 0) return sum;
      const perUnit = Math.max(item.unitPriceCents - item.discountCents, 0);
      return sum + perUnit * requested;
    }, 0);
  }, [lines, items]);

  const submit = async () => {
    setError('');
    const itemsPayload = items
      .map((item) => ({ orderItemId: item.id, returnedQuantity: lines[item.id] ?? 0 }))
      .filter((line) => line.returnedQuantity > 0);
    if (itemsPayload.length === 0) {
      setError('Selecciona al menos una unidad para devolver');
      return;
    }
    setSaving(true);
    try {
      const result = await posApi.createReturn<PosSaleResponse>(orderId, {
        idempotencyKey: generateIdempotencyKey(),
        cashSessionId,
        terminalId,
        reason: reason.trim() || 'Devolución',
        items: itemsPayload,
      });
      onReturned(result.receipt);
    } catch (err) {
      setError(err instanceof Error ? err.message : 'No se pudo registrar la devolución');
    } finally {
      setSaving(false);
    }
  };

  return (
    <div
      className="fixed inset-0 z-[70] flex items-center justify-center bg-black/40 p-4"
      role="dialog"
      aria-modal="true"
      aria-labelledby="return-title"
    >
      <div className="w-full max-w-md space-y-4 rounded-2xl bg-white p-6 shadow-2xl">
        <div className="flex items-start justify-between gap-4">
          <div>
            <p className="text-sm font-semibold text-amber-600">
              Devolución · ticket {receipt.receiptNumber}
            </p>
            <h2 id="return-title" className="text-2xl font-bold text-gray-900">
              Devolver artículos
            </h2>
          </div>
          <button
            type="button"
            onClick={onClose}
            aria-label="Cerrar"
            className="text-2xl text-gray-400 hover:text-gray-700"
          >
            ✕
          </button>
        </div>

        {loading ? (
          <p className="text-sm text-gray-500">Cargando…</p>
        ) : (
          <>
            <ul className="space-y-2">
              {items.map((item) => {
                const requested = lines[item.id] ?? 0;
                const max = item.quantity - item.returnedQuantity;
                const step = item.freeItem ? max : 1;
                return (
                  <li
                    key={item.id}
                    className="flex items-center justify-between rounded-xl border border-gray-200 bg-gray-50 p-3 text-sm"
                  >
                    <div>
                      <p className="font-medium text-gray-800">{item.name}</p>
                      <p className="text-xs text-gray-500">
                        Vendidas {item.quantity} · devueltas {item.returnedQuantity}
                        {item.freeItem ? ' · artículo libre' : ''}
                      </p>
                    </div>
                    <div className="flex items-center gap-2">
                      <button
                        type="button"
                        onClick={() =>
                          setLines((current) => ({
                            ...current,
                            [item.id]: Math.max(0, requested - step),
                          }))
                        }
                        disabled={requested <= 0}
                        className="h-8 w-8 rounded-lg border text-lg font-bold disabled:opacity-40"
                      >
                        −
                      </button>
                      <span className="w-8 text-center text-lg font-bold">{requested}</span>
                      <button
                        type="button"
                        onClick={() =>
                          setLines((current) => ({
                            ...current,
                            [item.id]: Math.min(max, requested + step),
                          }))
                        }
                        disabled={requested === max}
                        className="h-8 w-8 rounded-lg border text-lg font-bold disabled:opacity-40"
                      >
                        +
                      </button>
                    </div>
                  </li>
                );
              })}
            </ul>

            <label className="block text-sm font-medium text-gray-700">
              Motivo
              <input
                type="text"
                required
                maxLength={500}
                value={reason}
                onChange={(event) => setReason(event.target.value)}
                className="mt-1 w-full rounded-xl border border-gray-300 px-3 py-2"
              />
            </label>

            <div className="rounded-xl bg-amber-50 p-3 text-sm">
              <p className="flex justify-between font-bold">
                <span>Reembolso estimado</span>
                <span>{formatPrice(totalRefund)}</span>
              </p>
            </div>

            {error && (
              <p className="text-sm font-medium text-red-600" aria-live="polite">
                {error}
              </p>
            )}
            <div className="flex gap-2">
              <button
                type="button"
                onClick={onClose}
                disabled={saving}
                className="flex-1 rounded-xl border border-gray-300 py-3 text-sm font-bold disabled:opacity-50"
              >
                Cancelar
              </button>
              <button
                type="button"
                onClick={() => void submit()}
                disabled={saving || totalRefund === 0}
                className="flex-1 rounded-xl bg-amber-500 py-3 text-sm font-bold text-white disabled:opacity-50"
              >
                {saving ? 'Procesando…' : 'Confirmar devolución'}
              </button>
            </div>
          </>
        )}
      </div>
    </div>
  );
}
