'use client';

/**
 * ============================================
 * ORDER ACTIONS
 * ============================================
 * Reusable "Repeat order" + "Change payment method" actions for a placed order.
 * Mirrors the "⋯" menu in Shopware's account order list / order detail.
 *
 *   variant="menu"    → compact "⋯" dropdown (used on the order list cards)
 *   variant="buttons" → inline buttons (used on the order detail page)
 */

import { useState, useRef, useEffect, useCallback } from 'react';
import { useRouter } from 'next/navigation';
import { useCart } from '@/lib/cart-context';
import {
  Order,
  PaymentMethod,
  getPaymentMethods,
  isPaymentMethodExcluded,
  getActiveTransaction,
  addProductsToCart,
  changeOrderPaymentMethod,
  handlePayment,
} from '@/lib/shopware-api';

interface OrderActionsProps {
  order: Order;
  variant?: 'menu' | 'buttons';
  className?: string;
  /** Called after the order's payment method was changed (e.g. to reload it). */
  onChanged?: () => void | Promise<void>;
}

export default function OrderActions({
  order,
  variant = 'menu',
  className = '',
  onChanged,
}: OrderActionsProps) {
  const router = useRouter();
  const { refreshCart } = useCart();

  const [menuOpen, setMenuOpen] = useState(false);
  const menuRef = useRef<HTMLDivElement>(null);

  const [reordering, setReordering] = useState(false);
  const [actionError, setActionError] = useState('');

  // Change-payment modal
  const [payModalOpen, setPayModalOpen] = useState(false);
  const [paymentMethods, setPaymentMethods] = useState<PaymentMethod[]>([]);
  const [methodsLoading, setMethodsLoading] = useState(false);
  const [selectedPayment, setSelectedPayment] = useState('');
  const [savingPayment, setSavingPayment] = useState(false);
  const [payError, setPayError] = useState('');

  // Close the dropdown on outside click / Escape
  useEffect(() => {
    if (!menuOpen) return;
    const onDown = (e: MouseEvent) => {
      if (menuRef.current && !menuRef.current.contains(e.target as Node)) {
        setMenuOpen(false);
      }
    };
    const onKey = (e: KeyboardEvent) => e.key === 'Escape' && setMenuOpen(false);
    document.addEventListener('mousedown', onDown);
    document.addEventListener('keydown', onKey);
    return () => {
      document.removeEventListener('mousedown', onDown);
      document.removeEventListener('keydown', onKey);
    };
  }, [menuOpen]);

  // ── Repeat order ──────────────────────────────────────────────────────────
  const handleReorder = useCallback(async () => {
    setMenuOpen(false);
    setActionError('');
    const items = (order.lineItems || [])
      .filter((i) => (i.type === 'product' || !i.type) && i.productId)
      .map((i) => ({ id: i.productId as string, quantity: i.quantity }));

    if (items.length === 0) {
      setActionError('This order has no products that can be re-added.');
      return;
    }

    setReordering(true);
    try {
      await addProductsToCart(items);
      await refreshCart();
      router.push('/checkout/cart');
    } catch (e: any) {
      setActionError(e?.message || 'Could not add the items to your cart.');
    } finally {
      setReordering(false);
    }
  }, [order, refreshCart, router]);

  // ── Change payment method ───────────────────────────────────────────────
  const openPayModal = useCallback(async () => {
    setMenuOpen(false);
    setPayError('');
    setPayModalOpen(true);
    setMethodsLoading(true);
    try {
      const data = await getPaymentMethods();
      // Hide methods excluded from the storefront (e.g. Direct Debit) so a
      // customer can't switch a placed order onto one we don't support yet.
      const all = (data.elements || []).filter((m) => !isPaymentMethodExcluded(m));
      // Prefer methods usable after the order was placed
      const usable = all.filter((m) => m.afterOrderEnabled);
      const list = usable.length > 0 ? usable : all;
      setPaymentMethods(list);
      const current = getActiveTransaction(order)?.paymentMethod?.id;
      setSelectedPayment(current || list[0]?.id || '');
    } catch (e: any) {
      setPayError(e?.message || 'Failed to load payment methods.');
    } finally {
      setMethodsLoading(false);
    }
  }, [order]);

  const handleSavePayment = useCallback(async () => {
    if (!selectedPayment) return;
    setSavingPayment(true);
    setPayError('');
    try {
      await changeOrderPaymentMethod(order.id, selectedPayment);
      // (Re)initiate the transaction — async methods return a redirect URL.
      try {
        const origin = window.location.origin;
        const result = await handlePayment(
          order.id,
          `${origin}/account/orders/${order.id}`,
          `${origin}/account/orders/${order.id}?paymentError=1`
        );
        if (result?.redirectUrl) {
          window.location.href = result.redirectUrl;
          return;
        }
      } catch {
        // Synchronous method (invoice, COD, …) — nothing to redirect to.
      }
      setPayModalOpen(false);
      await onChanged?.();
    } catch (e: any) {
      setPayError(e?.message || 'Failed to change the payment method.');
    } finally {
      setSavingPayment(false);
    }
  }, [order.id, selectedPayment, onChanged]);

  // ── Shared modal ──────────────────────────────────────────────────────────
  const modal = payModalOpen && (
    <div
      className="fixed inset-0 z-[60] flex items-start justify-center overflow-y-auto bg-black/40 px-4 py-10"
      onClick={() => !savingPayment && setPayModalOpen(false)}
    >
      <div
        className="relative w-full max-w-lg bg-white rounded-xl shadow-xl"
        onClick={(e) => e.stopPropagation()}
      >
        <div className="flex items-center justify-between px-6 py-4 border-b border-surface-100">
          <h3 className="font-semibold text-surface-900">Change payment method</h3>
          <button
            type="button"
            onClick={() => !savingPayment && setPayModalOpen(false)}
            aria-label="Close"
            className="text-surface-400 hover:text-surface-700"
          >
            <svg className="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
              <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
            </svg>
          </button>
        </div>

        <div className="px-6 py-5">
          <p className="text-sm text-surface-500 mb-4">
            Order <strong className="text-surface-700">#{order.orderNumber}</strong>
          </p>

          {payError && (
            <div className="mb-4 p-3 bg-red-50 border border-red-200 rounded-lg text-sm text-red-700">
              {payError}
            </div>
          )}

          {methodsLoading ? (
            <p className="text-sm text-surface-500">Loading payment methods…</p>
          ) : paymentMethods.length === 0 ? (
            <p className="text-sm text-surface-400">No payment methods available for this order.</p>
          ) : (
            <div className="space-y-2">
              {paymentMethods.map((method) => (
                <label
                  key={method.id}
                  className={`flex items-start gap-3 p-3 rounded-lg border cursor-pointer transition-all ${
                    selectedPayment === method.id
                      ? 'border-brand-500 bg-brand-50/50'
                      : 'border-surface-200 hover:border-surface-300'
                  }`}
                >
                  <input
                    type="radio"
                    name="order-payment"
                    checked={selectedPayment === method.id}
                    onChange={() => setSelectedPayment(method.id)}
                    className="mt-1 accent-brand-500"
                  />
                  <div className="flex items-center gap-3">
                    {method.media?.url && (
                      // eslint-disable-next-line @next/next/no-img-element
                      <img src={method.media.url} alt={method.name} className="w-9 h-9 object-contain" />
                    )}
                    <div>
                      <p className="text-sm font-medium text-surface-900">
                        {method.translated?.name || method.name}
                      </p>
                      {(method.translated?.description || method.description) && (
                        <p className="text-xs text-surface-500">
                          {method.translated?.description || method.description}
                        </p>
                      )}
                    </div>
                  </div>
                </label>
              ))}
            </div>
          )}

          <div className="flex gap-3 mt-6">
            <button
              type="button"
              onClick={handleSavePayment}
              disabled={savingPayment || methodsLoading || !selectedPayment}
              className="px-5 py-2.5 bg-brand-500 hover:bg-brand-600 disabled:bg-brand-300 text-white text-sm font-semibold rounded-lg transition-colors"
            >
              {savingPayment ? 'Saving…' : 'Save payment method'}
            </button>
            <button
              type="button"
              onClick={() => setPayModalOpen(false)}
              disabled={savingPayment}
              className="px-5 py-2.5 border border-surface-200 hover:border-surface-300 text-surface-700 text-sm font-semibold rounded-lg transition-colors"
            >
              Cancel
            </button>
          </div>
        </div>
      </div>
    </div>
  );

  // ── Inline buttons variant (order detail page) ────────────────────────────
  if (variant === 'buttons') {
    return (
      <>
        <div className={`flex flex-wrap items-center gap-3 ${className}`}>
          <button
            type="button"
            onClick={handleReorder}
            disabled={reordering}
            className="inline-flex items-center gap-2 px-4 py-2 text-sm font-semibold border border-surface-300 hover:border-surface-400 text-surface-800 rounded-lg transition-colors disabled:opacity-50"
          >
            <svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
              <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15" />
            </svg>
            {reordering ? 'Adding…' : 'Repeat order'}
          </button>
          <button
            type="button"
            onClick={openPayModal}
            className="inline-flex items-center gap-2 px-4 py-2 text-sm font-semibold border border-surface-300 hover:border-surface-400 text-surface-800 rounded-lg transition-colors"
          >
            <svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
              <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M3 10h18M7 15h1m4 0h1m-7 4h12a3 3 0 003-3V8a3 3 0 00-3-3H6a3 3 0 00-3 3v8a3 3 0 003 3z" />
            </svg>
            Change payment method
          </button>
        </div>
        {actionError && <p className="text-sm text-red-600 mt-2">{actionError}</p>}
        {modal}
      </>
    );
  }

  // ── Dropdown menu variant (order list cards) ─────────────────────────────
  // Outer div carries placement (e.g. "absolute top-4 right-4"); the inner div
  // is the positioning context for the dropdown so the two never conflict.
  return (
    <div className={className}>
      <div ref={menuRef} className="relative">
        <button
          type="button"
          onClick={(e) => {
            e.preventDefault();
            e.stopPropagation();
            setMenuOpen((o) => !o);
          }}
          aria-label="Order actions"
          aria-haspopup="true"
          aria-expanded={menuOpen}
          className="w-9 h-9 flex items-center justify-center rounded-lg text-surface-400 hover:text-surface-900 hover:bg-surface-100 transition-colors"
        >
          <svg className="w-5 h-5" fill="currentColor" viewBox="0 0 24 24">
            <circle cx="5" cy="12" r="2" />
            <circle cx="12" cy="12" r="2" />
            <circle cx="19" cy="12" r="2" />
          </svg>
        </button>

        {menuOpen && (
          <div className="absolute right-0 top-11 z-20 w-56 bg-white border border-surface-200 rounded-xl shadow-lg py-1 overflow-hidden">
            <button
              type="button"
              onClick={(e) => { e.preventDefault(); openPayModal(); }}
              className="w-full text-left px-4 py-2.5 text-sm text-surface-700 hover:bg-surface-50 transition-colors"
            >
              Change payment method
            </button>
            <button
              type="button"
              onClick={(e) => { e.preventDefault(); handleReorder(); }}
              disabled={reordering}
              className="w-full text-left px-4 py-2.5 text-sm text-surface-700 hover:bg-surface-50 transition-colors disabled:opacity-50"
            >
              {reordering ? 'Adding to cart…' : 'Repeat order'}
            </button>
          </div>
        )}

        {actionError && (
          <p className="absolute right-0 top-11 z-20 w-56 bg-white border border-red-200 rounded-lg shadow-lg p-3 text-xs text-red-600">
            {actionError}
          </p>
        )}
      </div>
      {modal}
    </div>
  );
}
