'use client';

import { useMemo, useState } from 'react';
import { formatPrice } from '@/lib/money';
import type { PaymentAllocation, PaymentMethod } from '@/types/checkout';
import { generateIdempotencyKey } from '@/lib/idempotency';

interface PaymentModalProps {
  method: PaymentMethod;
  remainingCents: number;
  onAdd: (allocation: PaymentAllocation) => void;
  onClose: () => void;
}

export default function PaymentModal({
  method,
  remainingCents,
  onAdd,
  onClose,
}: PaymentModalProps) {
  const [mode, setMode] = useState<'total' | 'partial'>('total');
  const [amount, setAmount] = useState(centsToInput(remainingCents));
  const [tendered, setTendered] = useState(centsToInput(remainingCents));
  const [error, setError] = useState('');
  const amountCents = useMemo(() => parseEuros(amount), [amount]);
  const tenderedCents = useMemo(() => parseEuros(tendered), [tendered]);
  const changeCents =
    method.kind === 'cash' && tenderedCents >= amountCents ? tenderedCents - amountCents : 0;

  const chooseMode = (next: 'total' | 'partial') => {
    setMode(next);
    setError('');
    if (next === 'total') {
      setAmount(centsToInput(remainingCents));
      setTendered(centsToInput(remainingCents));
    } else {
      setAmount('');
      setTendered('');
    }
  };

  const add = () => {
    if (amountCents <= 0 || amountCents > remainingCents) {
      setError('El importe debe ser positivo y no superar lo pendiente');
      return;
    }
    if (method.kind === 'cash' && tenderedCents < amountCents) {
      setError('El efectivo entregado debe cubrir el importe aplicado');
      return;
    }
    onAdd({
      id: generateIdempotencyKey(),
      methodCode: method.code,
      methodLabel: method.label,
      kind: method.kind,
      amountCents,
      ...(method.kind === 'cash' ? { tenderedCents } : {}),
      changeCents,
    });
  };

  return (
    <div
      className="fixed inset-0 z-50 flex items-center justify-center bg-black/40 p-4"
      role="dialog"
      aria-modal="true"
      aria-labelledby="payment-title"
    >
      <div className="w-full max-w-md space-y-5 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-[#2D6A4F]">
              Pendiente {formatPrice(remainingCents)}
            </p>
            <h2 id="payment-title" className="text-2xl font-bold text-gray-900">
              {method.label}
            </h2>
          </div>
          <button
            type="button"
            onClick={onClose}
            className="min-h-12 min-w-12 rounded-xl bg-gray-100 text-xl"
            aria-label="Cerrar pago"
          >
            ✕
          </button>
        </div>

        <div className="grid grid-cols-2 gap-3">
          <button
            type="button"
            onClick={() => chooseMode('total')}
            className={`min-h-14 rounded-xl border-2 font-bold ${mode === 'total' ? 'border-[#2D6A4F] bg-green-50 text-[#2D6A4F]' : 'border-gray-200'}`}
          >
            Paga el total
          </button>
          <button
            type="button"
            onClick={() => chooseMode('partial')}
            className={`min-h-14 rounded-xl border-2 font-bold ${mode === 'partial' ? 'border-[#2D6A4F] bg-green-50 text-[#2D6A4F]' : 'border-gray-200'}`}
          >
            Paga una parte
          </button>
        </div>

        <label className="block text-sm font-semibold text-gray-700">
          Importe que se aplica (€)
          <input
            value={amount}
            onChange={(event) => {
              setAmount(event.target.value);
              setError('');
            }}
            inputMode="decimal"
            readOnly={mode === 'total'}
            autoFocus={mode === 'partial'}
            className="mt-1 w-full rounded-xl border-2 border-gray-200 px-4 py-3 text-2xl font-bold outline-none focus:border-[#2D6A4F] read-only:bg-gray-50"
            aria-describedby="payment-error"
          />
        </label>

        {method.kind === 'cash' && (
          <label className="block text-sm font-semibold text-gray-700">
            Efectivo entregado (€)
            <input
              value={tendered}
              onChange={(event) => {
                setTendered(event.target.value);
                setError('');
              }}
              inputMode="decimal"
              className="mt-1 w-full rounded-xl border-2 border-gray-200 px-4 py-3 text-2xl font-bold outline-none focus:border-[#2D6A4F]"
            />
          </label>
        )}

        {method.kind === 'cash' && tenderedCents >= amountCents && amountCents > 0 && (
          <div className="flex items-center justify-between rounded-xl bg-amber-50 p-4 text-amber-900">
            <span className="font-semibold">A devolver</span>
            <strong className="text-2xl">{formatPrice(changeCents)}</strong>
          </div>
        )}
        {error && (
          <p id="payment-error" className="text-sm font-medium text-red-600" aria-live="polite">
            {error}
          </p>
        )}

        <button
          type="button"
          onClick={add}
          className="min-h-14 w-full rounded-xl bg-[#2D6A4F] px-5 font-bold text-white hover:bg-[#1B4332]"
        >
          Añadir pago
        </button>
      </div>
    </div>
  );
}

function parseEuros(value: string): number {
  const normalized = value.trim().replace(',', '.');
  if (!/^\d+(?:\.\d{0,2})?$/.test(normalized)) return 0;
  return Math.round(Number(normalized) * 100);
}

function centsToInput(cents: number): string {
  return (cents / 100).toFixed(2);
}
