'use client';

import Link from 'next/link';
import { useMemo, useState } from 'react';
import { useProactiveRefund } from '@/lib/queries/use-returns';
import type { OrderItemData, ProactiveRefundMode } from '@alqove/api-client';

interface Props {
  orderId: string;
  items: OrderItemData[];
  shippingCost: number;
  open: boolean;
  onClose: () => void;
  onSuccess?: () => void;
}

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

export function ProactiveRefundModal({
  orderId,
  items,
  shippingCost,
  open,
  onClose,
  onSuccess,
}: Props) {
  const [mode, setMode] = useState<ProactiveRefundMode>('keep-it');
  const [selected, setSelected] = useState<Set<string>>(
    () => new Set(items.map((i) => i.id)),
  );
  // Track whether the user has manually edited the amount (so we stop
  // recomputing from the item subtotal).
  const [amountTouched, setAmountTouched] = useState(false);
  const [refundShipping, setRefundShipping] = useState(false);
  const [reasonText, setReasonText] = useState('');
  const [submitError, setSubmitError] = useState<string | null>(null);
  const [conflict, setConflict] = useState(false);

  const subtotalCents = useMemo(
    () =>
      items
        .filter((it) => selected.has(it.id))
        .reduce((acc, it) => acc + it.price_snapshot, 0),
    [items, selected],
  );

  const [amountInput, setAmountInput] = useState<string>(
    () => (subtotalCents / 100).toFixed(2),
  );

  // Recompute default whenever items toggle (unless user has typed).
  const computedAmountStr = useMemo(
    () => (subtotalCents / 100).toFixed(2),
    [subtotalCents],
  );
  // Sync if untouched.
  if (!amountTouched && amountInput !== computedAmountStr) {
    // Acceptable in render: setState during render guards on equality.
    setAmountInput(computedAmountStr);
  }

  const proactive = useProactiveRefund(orderId);

  if (!open) return null;

  const toggleItem = (id: string) => {
    setSelected((prev) => {
      const next = new Set(prev);
      if (next.has(id)) next.delete(id);
      else next.add(id);
      return next;
    });
  };

  const submit = async () => {
    setSubmitError(null);
    setConflict(false);
    if (selected.size === 0) {
      setSubmitError('Select at least one item.');
      return;
    }
    const amountCents = Math.round(Number(amountInput) * 100);
    if (!Number.isFinite(amountCents) || amountCents <= 0) {
      setSubmitError('Refund amount must be greater than 0.');
      return;
    }
    const cap = subtotalCents + (refundShipping ? shippingCost : 0);
    if (amountCents > cap) {
      setSubmitError(
        `Refund amount cannot exceed selected items${refundShipping ? ' + shipping' : ''} ($${dollars(cap)}).`,
      );
      return;
    }
    try {
      const resp = await proactive.mutateAsync({
        mode,
        item_ids: Array.from(selected),
        amount_cents: amountCents,
        refund_original_shipping: refundShipping,
        reason_text: reasonText.trim() || null,
      });
      onSuccess?.();
      onClose();
      return resp;
    } catch (e) {
      const err = e as { status?: number; message?: string };
      if (err.status === 409) {
        setConflict(true);
      } else {
        setSubmitError(err.message ?? 'Failed to issue refund.');
      }
    }
  };

  const submitLabel = mode === 'ship-back' ? 'Issue refund + label' : 'Issue refund';

  return (
    <div
      role="dialog"
      aria-modal="true"
      aria-label="Issue proactive refund"
      className="fixed inset-0 z-50 flex items-center justify-center bg-slate-900/50 p-4"
    >
      <div className="w-full max-w-lg rounded-lg bg-white p-6 shadow-xl">
        <div className="flex items-start justify-between">
          <div>
            <h2 className="text-lg font-semibold text-slate-900">Issue refund</h2>
            <p className="mt-1 text-xs text-slate-500">
              Proactively refund the buyer — no return request needed.
            </p>
          </div>
          <button
            type="button"
            onClick={onClose}
            className="text-slate-400 hover:text-slate-600"
          >
            <span aria-hidden>×</span>
            <span className="sr-only">Close</span>
          </button>
        </div>

        <div className="mt-4 space-y-4">
          <fieldset>
            <legend className="text-sm font-medium text-slate-700">Mode</legend>
            <div className="mt-2 space-y-1">
              <label className="flex items-start gap-2 text-sm text-slate-800">
                <input
                  type="radio"
                  name="proactive-mode"
                  value="keep-it"
                  checked={mode === 'keep-it'}
                  onChange={() => setMode('keep-it')}
                />
                <span>Keep the item, refund only</span>
              </label>
              <label className="flex items-start gap-2 text-sm text-slate-800">
                <input
                  type="radio"
                  name="proactive-mode"
                  value="ship-back"
                  checked={mode === 'ship-back'}
                  onChange={() => setMode('ship-back')}
                />
                <span>Issue a return label, refund on receipt</span>
              </label>
            </div>
          </fieldset>

          <fieldset>
            <legend className="text-sm font-medium text-slate-700">Items</legend>
            <ul className="mt-2 space-y-2">
              {items.map((it) => (
                <li key={it.id}>
                  <label className="flex items-center gap-3 text-sm text-slate-800">
                    <input
                      type="checkbox"
                      checked={selected.has(it.id)}
                      onChange={() => toggleItem(it.id)}
                      className="h-4 w-4 rounded border-slate-300"
                    />
                    <span className="flex-1">{it.title_snapshot}</span>
                    <span className="text-slate-500">${dollars(it.price_snapshot)}</span>
                  </label>
                </li>
              ))}
            </ul>
          </fieldset>

          <div>
            <label htmlFor="proactive-amount" className="text-sm font-medium text-slate-700">
              Refund amount
            </label>
            <div className="mt-1 flex items-center gap-2">
              <span className="text-sm text-slate-500">$</span>
              <input
                id="proactive-amount"
                type="number"
                step="0.01"
                min="0"
                value={amountInput}
                onChange={(e) => {
                  setAmountTouched(true);
                  setAmountInput(e.target.value);
                }}
                className="block w-32 rounded-md border border-slate-300 px-2 py-1 text-sm"
              />
            </div>
          </div>

          {selected.size >= 1 && (
            <label className="flex items-center gap-2 text-sm text-slate-800">
              <input
                type="checkbox"
                checked={refundShipping}
                onChange={(e) => setRefundShipping(e.target.checked)}
              />
              Refund original shipping (${dollars(shippingCost)})
            </label>
          )}

          <div>
            <label htmlFor="proactive-reason" className="text-sm font-medium text-slate-700">
              Reason note (optional)
            </label>
            <textarea
              id="proactive-reason"
              value={reasonText}
              onChange={(e) => setReasonText(e.target.value)}
              maxLength={500}
              rows={2}
              className="mt-1 block w-full rounded-md border border-slate-300 p-2 text-sm"
            />
          </div>

          {submitError && <p className="text-sm text-red-600">{submitError}</p>}
          {conflict && (
            <p className="rounded bg-amber-50 p-3 text-sm text-amber-800">
              There&apos;s already an open return on this order —{' '}
              <Link
                href={`/seller/orders/${orderId}`}
                className="text-forest-700 underline"
              >
                view it instead
              </Link>
              .
            </p>
          )}
        </div>

        <div className="mt-6 flex items-center justify-end gap-2">
          <button
            type="button"
            onClick={onClose}
            className="rounded-md border border-slate-300 px-4 py-2 text-sm text-slate-700 hover:bg-slate-50"
          >
            Cancel
          </button>
          <button
            type="button"
            onClick={submit}
            disabled={proactive.isPending}
            className="rounded-md bg-slate-900 px-4 py-2 text-sm font-medium text-white hover:bg-slate-800 disabled:cursor-not-allowed disabled:opacity-60"
          >
            {proactive.isPending ? 'Issuing…' : submitLabel}
          </button>
        </div>
      </div>
    </div>
  );
}
