'use client';

import { useState, useMemo } from 'react';
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter } from '@/components/ui/dialog';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Trash2, Plus, Loader2, CheckCircle2, AlertCircle } from 'lucide-react';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
import { type Bank, type PaymentBreakdown, type PaymentMethod, type Customer } from '@/lib/types';
import { handleValidateCouponCode } from '@/lib/actions';

interface PaymentMethodModalProps {
  isOpen: boolean;
  onOpenChange: (open: boolean) => void;
  invoiceTotal: number;
  onConfirm: (payments: PaymentBreakdown[]) => boolean | void | Promise<boolean | void>;
  customers?: Customer[];
  banks?: Bank[];
  defaultVisaBankAccountId?: string;
  currencySymbol?: string;
  translations?: {
    selectPaymentMethod?: string;
    paymentMethods?: string;
    paymentMethodsDescription?: string;
    cash?: string;
    visa?: string;
    receivables?: string;
    coupon?: string;
    couponCode?: string;
    totalAmount?: string;
    paymentBreakdown?: string;
    remainingBalance?: string;
    addPaymentMethod?: string;
    confirm?: string;
    cancel?: string;
    amount?: string;
    remove?: string;
    errorExceeds?: string;
    errorMinimum?: string;
    errorVisaBankRequired?: string;
  };
}

export function PaymentMethodModal({
  isOpen,
  onOpenChange,
  invoiceTotal,
  onConfirm,
  customers = [],
  banks = [],
  defaultVisaBankAccountId = '',
  currencySymbol = '',
  translations = {},
}: PaymentMethodModalProps) {
  const fmt = (amount: number) => currencySymbol ? `${amount.toFixed(2)} ${currencySymbol}` : amount.toFixed(2);
  const t = {
    selectPaymentMethod: translations.selectPaymentMethod ?? 'اختر طريقة الدفع',
    paymentMethods: translations.paymentMethods ?? 'طرق الدفع',
    paymentMethodsDescription: translations.paymentMethodsDescription ?? 'اختر طرق الدفع المناسبة لتسديد الفاتورة.',
    cash: translations.cash ?? 'نقدي',
    visa: translations.visa ?? 'فيزا',
    receivables: translations.receivables ?? 'ذمم',
    coupon: translations.coupon ?? 'كوبون',
    couponCode: translations.couponCode ?? 'كود الكوبون',
    totalAmount: translations.totalAmount ?? 'إجمالي الفاتورة',
    paymentBreakdown: translations.paymentBreakdown ?? 'تفاصيل الدفع',
    remainingBalance: translations.remainingBalance ?? 'الرصيد المتبقي',
    addPaymentMethod: translations.addPaymentMethod ?? 'إضافة طريقة دفع',
    confirm: translations.confirm ?? 'تأكيد',
    cancel: translations.cancel ?? 'إلغاء',
    amount: translations.amount ?? 'المبلغ',
    remove: translations.remove ?? 'حذف',
    errorExceeds: translations.errorExceeds ?? 'إجمالي الدفع لا يمكن أن يتجاوز المبلغ الإجمالي',
    errorMinimum: translations.errorMinimum ?? 'يجب إضافة طريقة دفع واحدة على الأقل',
    errorVisaBankRequired: translations.errorVisaBankRequired ?? 'يجب اختيار بنك لمدفوعات البطاقة',
  };

  const [payments, setPayments] = useState<PaymentBreakdown[]>([]);
  const [error, setError] = useState('');
  const [editingCustomerIndex, setEditingCustomerIndex] = useState<number | null>(null);
  type CouponValidationState =
    | { status: 'idle' }
    | { status: 'checking' }
    | { status: 'valid'; message: string; remainingAmount?: number }
    | { status: 'invalid'; message: string };
  const [couponStatusByIndex, setCouponStatusByIndex] = useState<Record<number, CouponValidationState>>({});

  const couponErrorMessage = (errorCode: string | undefined): string => {
    switch (errorCode) {
      case 'COUPON_CODE_REQUIRED':
        return 'أدخل رقم الكوبون أو اختر طريقة دفع أخرى.';
      case 'COUPON_NOT_FOUND':
        return 'رقم الكوبون غير موجود. تأكد من الرقم أو اختر طريقة دفع أخرى.';
      case 'COUPON_USED':
        return 'هذا الكوبون مستخدم بالكامل. اختر طريقة دفع أخرى.';
      case 'COUPON_EXPIRED':
        return 'هذا الكوبون منتهي الصلاحية. اختر طريقة دفع أخرى.';
      case 'COUPON_CANCELLED':
        return 'تم إلغاء هذا الكوبون. اختر طريقة دفع أخرى.';
      case 'COUPON_NO_BALANCE':
        return 'لا يوجد رصيد متبقي في هذا الكوبون.';
      case 'UNAUTHORIZED':
        return 'غير مصرح بالتحقق من الكوبون.';
      default:
        return 'تعذر التحقق من الكوبون. تأكد من الرقم أو اختر طريقة دفع أخرى.';
    }
  };

  const validateCouponAt = async (index: number, rawCode: string) => {
    const code = String(rawCode || '').trim();
    if (!code) {
      setCouponStatusByIndex((prev) => ({ ...prev, [index]: { status: 'idle' } }));
      return;
    }

    setCouponStatusByIndex((prev) => ({ ...prev, [index]: { status: 'checking' } }));
    try {
      const result = await handleValidateCouponCode(code);
      if (result.success) {
        const remainingAmount = Number(result.coupon?.remainingAmount || 0);
        setCouponStatusByIndex((prev) => ({
          ...prev,
          [index]: {
            status: 'valid',
            message: `رصيد الكوبون: ${fmt(remainingAmount)}`,
            remainingAmount,
          },
        }));
      } else {
        setCouponStatusByIndex((prev) => ({
          ...prev,
          [index]: { status: 'invalid', message: couponErrorMessage(result.error) },
        }));
      }
    } catch {
      setCouponStatusByIndex((prev) => ({
        ...prev,
        [index]: { status: 'invalid', message: couponErrorMessage(undefined) },
      }));
    }
  };

  // Calculate totals
  const totalPaid = useMemo(() => payments.reduce((sum, p) => sum + (p.amount || 0), 0), [payments]);
  const remainingBalance = useMemo(() => invoiceTotal - totalPaid, [invoiceTotal, totalPaid]);

  const handleAddPayment = (method: PaymentMethod) => {
    const newPayment: PaymentBreakdown = {
      method,
      amount: 0,
      customerName: undefined,
      bankAccountId: method === 'visa' ? (String(defaultVisaBankAccountId || '').trim() || undefined) : undefined,
      couponCode: undefined,
    };
    setPayments([...payments, newPayment]);
    if (method === 'receivables') {
      setEditingCustomerIndex(payments.length);
    }
    setError('');
  };

  const handleUpdatePayment = (index: number, amount?: number, customerName?: string, couponCode?: string, bankAccountId?: string) => {
    const updated = [...payments];
    if (amount !== undefined) {
      updated[index].amount = Math.max(0, amount);
    }
    if (customerName !== undefined) {
      updated[index].customerName = customerName;
    }
    if (couponCode !== undefined) {
      updated[index].couponCode = couponCode;
    }
    if (bankAccountId !== undefined) {
      updated[index].bankAccountId = bankAccountId;
    }
    setPayments(updated);

    // Validate
    const newTotal = updated.reduce((sum, p) => sum + (p.amount || 0), 0);
    if (newTotal > invoiceTotal) {
      setError(t.errorExceeds);
    } else {
      setError('');
    }
  };

  const handleRemovePayment = (index: number) => {
    setPayments(payments.filter((_, i) => i !== index));
    setCouponStatusByIndex((prev) => {
      const next: Record<number, CouponValidationState> = {};
      Object.entries(prev).forEach(([key, value]) => {
        const currentIndex = Number(key);
        if (currentIndex === index) return;
        const nextIndex = currentIndex > index ? currentIndex - 1 : currentIndex;
        next[nextIndex] = value;
      });
      return next;
    });
    setError('');
  };

  const handleConfirm = async () => {
    if (payments.length === 0) {
      setError(t.errorMinimum);
      return;
    }

    const total = payments.reduce((sum, p) => sum + (p.amount || 0), 0);
    if (total > invoiceTotal) {
      setError(t.errorExceeds);
      return;
    }

    const invalidCouponLine = payments.find(
      (payment) => payment.method === 'coupon' && Number(payment.amount || 0) > 0 && !String(payment.couponCode || '').trim()
    );
    if (invalidCouponLine) {
      setError(`${t.couponCode}: ${'مطلوب عند استخدام الكوبون'}`);
      return;
    }

    // Re-validate any coupon lines whose status is not yet 'valid' (idle / invalid / checking)
    const couponIndexes = payments
      .map((payment, index) => ({ payment, index }))
      .filter(({ payment }) => payment.method === 'coupon' && Number(payment.amount || 0) > 0)
      .map(({ index }) => index);

    const indexesNeedingValidation = couponIndexes.filter((index) => {
      const status = couponStatusByIndex[index];
      return !status || status.status !== 'valid';
    });

    if (indexesNeedingValidation.length > 0) {
      await Promise.all(
        indexesNeedingValidation.map((index) => validateCouponAt(index, payments[index].couponCode || ''))
      );
      // After validation, force user to review results (do not auto-submit on same click)
      setError('تحقق من أرقام الكوبونات أدناه قبل المتابعة.');
      return;
    }

    const invalidVisaLine = payments.find(
      (payment) => payment.method === 'visa' && Number(payment.amount || 0) > 0 && !String(payment.bankAccountId || '').trim()
    );
    if (invalidVisaLine) {
      setError(t.errorVisaBankRequired);
      return;
    }

    const confirmResult = await onConfirm(payments);
    if (confirmResult === false) {
      return;
    }

    setPayments([]);
    onOpenChange(false);
  };

  const hasCheckingCoupon = payments.some((payment, index) => {
    if (payment.method !== 'coupon') return false;
    if (Number(payment.amount || 0) <= 0) return false;
    return couponStatusByIndex[index]?.status === 'checking';
  });

  const hasInvalidCoupon = payments.some((payment, index) => {
    if (payment.method !== 'coupon') return false;
    if (Number(payment.amount || 0) <= 0) return false;
    return couponStatusByIndex[index]?.status === 'invalid';
  });

  const handleFooterConfirm = async () => {
    if (hasInvalidCoupon) {
      const invalidIndexes = payments
        .map((payment, index) => ({ payment, index }))
        .filter(({ payment, index }) => {
          if (payment.method !== 'coupon') return false;
          if (Number(payment.amount || 0) <= 0) return false;
          return couponStatusByIndex[index]?.status === 'invalid';
        })
        .map(({ index }) => index);

      await Promise.all(
        invalidIndexes.map((index) => validateCouponAt(index, payments[index].couponCode || ''))
      );
      setError('يوجد كوبون غير صالح. تأكد من رقم الكوبون أو اختر طريقة دفع أخرى قبل المتابعة.');
      return;
    }

    await handleConfirm();
  };

  const getMethodLabel = (method: PaymentMethod): string => {
    switch (method) {
      case 'cash':
        return t.cash;
      case 'visa':
        return t.visa;
      case 'receivables':
        return t.receivables;
      case 'coupon':
        return t.coupon;
      default:
        return method;
    }
  };

  const getMethodColor = (method: PaymentMethod): string => {
    switch (method) {
      case 'cash':
        return 'bg-green-100 border-green-300';
      case 'visa':
        return 'bg-blue-100 border-blue-300';
      case 'receivables':
        return 'bg-amber-100 border-amber-300';
      case 'coupon':
        return 'bg-purple-100 border-purple-300';
      default:
        return 'bg-gray-100 border-gray-300';
    }
  };

  return (
    <Dialog open={isOpen} onOpenChange={onOpenChange}>
      <DialogContent className="max-w-2xl">
        <DialogHeader>
          <DialogTitle>{t.paymentMethods}</DialogTitle>
          <DialogDescription className="sr-only">{t.paymentMethodsDescription || 'اختر طرق الدفع المناسبة لتسديد الفاتورة.'}</DialogDescription>
        </DialogHeader>

        <div className="space-y-6">
          {/* Invoice Total Display */}
          <div className="bg-gray-50 p-4 rounded-lg border border-gray-200">
            <div className="flex justify-between items-center">
              <span className="text-sm font-medium text-gray-600">{t.totalAmount}</span>
              <span className="text-lg font-bold text-gray-900">{fmt(invoiceTotal)}</span>
            </div>
          </div>

          {/* Payment Methods */}
          <div className="space-y-3">
            <Label className="font-semibold">{t.selectPaymentMethod}</Label>
            <div className="grid grid-cols-4 gap-2">
              <Button
                type="button"
                variant="outline"
                className="bg-green-50 border-green-300 hover:bg-green-100"
                onClick={() => handleAddPayment('cash')}
              >
                {t.cash}
              </Button>
              <Button
                type="button"
                variant="outline"
                className="bg-blue-50 border-blue-300 hover:bg-blue-100"
                onClick={() => handleAddPayment('visa')}
              >
                {t.visa}
              </Button>
              <Button
                type="button"
                variant="outline"
                className="bg-amber-50 border-amber-300 hover:bg-amber-100"
                onClick={() => handleAddPayment('receivables')}
              >
                {t.receivables}
              </Button>
              <Button
                type="button"
                variant="outline"
                className="bg-purple-50 border-purple-300 hover:bg-purple-100"
                onClick={() => handleAddPayment('coupon')}
              >
                {t.coupon}
              </Button>
            </div>
          </div>

          {/* Payment Breakdown */}
          {payments.length > 0 && (
            <div className="space-y-3">
              <Label className="font-semibold">{t.paymentBreakdown}</Label>
              <div className="space-y-2 bg-gray-50 p-4 rounded-lg">
                {payments.map((payment, index) => {
                  // Calculate remaining balance for this payment slot
                  const otherPaymentsSum = payments.reduce((sum, p, i) => i !== index ? sum + (p.amount || 0) : sum, 0);
                  const availableForThisSlot = invoiceTotal - otherPaymentsSum;
                  
                  return (
                    <div key={index} className={`flex flex-col gap-3 p-3 rounded border-2 ${getMethodColor(payment.method)}`}>
                      <div className="flex items-center gap-2">
                        <div className="flex-1 min-w-0">
                          <Label className="text-sm font-medium">{getMethodLabel(payment.method)}</Label>
                        </div>
                        <div className="flex items-center gap-2">
                          <Input
                            type="number"
                            min="0"
                            step="0.01"
                            max={invoiceTotal}
                            value={payment.amount}
                            onChange={(e) => handleUpdatePayment(index, parseFloat(e.target.value) || 0)}
                            placeholder={t.amount}
                            className="text-right w-28"
                          />
                          <button
                            type="button"
                            onClick={() => {
                              const otherPaymentsSum = payments.reduce((sum, p, i) => i !== index ? sum + (p.amount || 0) : sum, 0);
                              const availableForThisSlot = invoiceTotal - otherPaymentsSum;
                              handleUpdatePayment(index, availableForThisSlot);
                            }}
                            className="px-2 py-1 text-xs font-semibold bg-blue-500 hover:bg-blue-600 text-white rounded transition-colors whitespace-nowrap"
                            title={`ملء بالمتبقي`}
                          >
                            ملء
                          </button>
                        </div>
                        <Button
                          type="button"
                          variant="ghost"
                          size="sm"
                          onClick={() => handleRemovePayment(index)}
                          className="text-red-600 hover:text-red-700 hover:bg-red-50"
                        >
                          <Trash2 className="w-4 h-4" />
                        </Button>
                      </div>
                      
                      {/* Customer selector for receivables */}
                      {payment.method === 'receivables' && (
                        <div className="pt-2 border-t border-amber-200">
                          <Label className="text-xs font-medium mb-2 block">اختر الزبون</Label>
                          <Select
                            value={payment.customerName || ''}
                            onValueChange={(customerId) => {
                              const customer = customers.find(c => c.id === customerId);
                              if (customer) {
                                handleUpdatePayment(index, undefined, customer.name);
                              }
                            }}
                          >
                            <SelectTrigger className="w-full">
                              <SelectValue placeholder="اختر الزبون..." />
                            </SelectTrigger>
                            <SelectContent>
                              {customers.map((customer) => (
                                <SelectItem key={customer.id} value={customer.id}>
                                  {customer.name}
                                </SelectItem>
                              ))}
                            </SelectContent>
                          </Select>
                          {payment.customerName && (
                            <p className="text-xs text-amber-600 mt-1">✓ {payment.customerName}</p>
                          )}
                        </div>
                      )}

                      {payment.method === 'visa' && (
                        <div className="pt-2 border-t border-blue-200">
                          <Label className="text-xs font-medium mb-2 block">البنك</Label>
                          <Select
                            value={payment.bankAccountId || 'none'}
                            onValueChange={(bankId) => handleUpdatePayment(index, undefined, undefined, undefined, bankId === 'none' ? '' : bankId)}
                          >
                            <SelectTrigger className="w-full">
                              <SelectValue placeholder="اختر بنك نقاط الدفع..." />
                            </SelectTrigger>
                            <SelectContent>
                              <SelectItem value="none">بدون تحديد</SelectItem>
                              {(banks || []).map((bank) => (
                                <SelectItem key={bank.id} value={bank.id}>
                                  {bank.name}
                                </SelectItem>
                              ))}
                            </SelectContent>
                          </Select>
                        </div>
                      )}

                      {/* Coupon code input for coupon payments */}
                      {payment.method === 'coupon' && (() => {
                        const couponState = couponStatusByIndex[index] || { status: 'idle' as const };
                        return (
                          <div className="pt-2 border-t border-purple-200 space-y-2">
                            <Label className="text-xs font-medium mb-2 block">{t.couponCode}</Label>
                            <Input
                              value={payment.couponCode || ''}
                              onChange={(e) => {
                                handleUpdatePayment(index, undefined, undefined, e.target.value);
                              }}
                              onBlur={(e) => validateCouponAt(index, e.target.value)}
                              placeholder="CPN-00000001"
                              className="text-left"
                            />
                            {couponState.status === 'checking' && (
                              <div className="flex items-center gap-2 text-xs text-muted-foreground">
                                <Loader2 className="h-3 w-3 animate-spin" />
                                <span>جاري التحقق من الكوبون...</span>
                              </div>
                            )}
                            {couponState.status === 'valid' && (
                              <div className="flex items-center gap-2 rounded border border-green-200 bg-green-50 px-2 py-1 text-xs text-green-700">
                                <CheckCircle2 className="h-4 w-4" />
                                <span>{couponState.message}</span>
                              </div>
                            )}
                            {couponState.status === 'invalid' && (
                              <div className="space-y-2 rounded border border-red-200 bg-red-50 p-2 text-xs text-red-700">
                                <div className="flex items-start gap-2">
                                  <AlertCircle className="mt-0.5 h-4 w-4 shrink-0" />
                                  <span>{couponState.message}</span>
                                </div>
                                <div className="flex flex-wrap gap-2">
                                  <Button
                                    type="button"
                                    size="sm"
                                    variant="outline"
                                    className="h-8 px-3"
                                    onClick={() => handleRemovePayment(index)}
                                  >
                                    اختيار طريقة دفع أخرى
                                  </Button>
                                </div>
                              </div>
                            )}
                          </div>
                        );
                      })()}
                    </div>
                  );
                })}
              </div>
            </div>
          )}

          {/* Totals Summary */}
          <div className="space-y-2 bg-blue-50 p-4 rounded-lg border border-blue-200">
            <div className="flex justify-between items-center">
              <span className="text-sm font-medium text-gray-700">المدفوع:</span>
              <span className="font-semibold text-gray-900">{fmt(totalPaid)}</span>
            </div>
            <div className="flex justify-between items-center">
              <span className={`text-sm font-medium ${remainingBalance === 0 ? 'text-green-700' : 'text-orange-700'}`}>
                {t.remainingBalance}
              </span>
              <span className={`font-bold ${remainingBalance === 0 ? 'text-green-900' : 'text-orange-900'}`}>
                {fmt(remainingBalance)}
              </span>
            </div>
          </div>

          {/* Error Message */}
          {error && <div className="text-sm text-red-600 bg-red-50 p-3 rounded border border-red-200">{error}</div>}
        </div>

        <DialogFooter className="flex gap-2">
          <Button
            type="button"
            variant="outline"
            onClick={() => {
              setPayments([]);
              setError('');
              onOpenChange(false);
            }}
          >
            {t.cancel}
          </Button>
          <Button
            type="button"
            onClick={() => { void handleFooterConfirm(); }}
            disabled={hasCheckingCoupon}
            className="bg-blue-600 hover:bg-blue-700 disabled:cursor-not-allowed disabled:opacity-60"
          >
            {hasCheckingCoupon ? 'جاري التحقق...' : hasInvalidCoupon ? 'صحح الكوبون أولاً' : t.confirm}
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}
