/* eslint-disable import-x/order */
import { render, screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { beforeEach, describe, expect, it, vi } from 'vitest';

// Mock lucide-react icons
vi.mock('lucide-react', () => ({
  AlertCircle: (props: Record<string, unknown>) => <span data-testid="alert-icon" {...props} />,
  CreditCard: (props: Record<string, unknown>) => <span data-testid="credit-card-icon" {...props} />,
  Loader2: (props: Record<string, unknown>) => <span data-testid="loader-icon" {...props} />,
  Smartphone: (props: Record<string, unknown>) => <span data-testid="smartphone-icon" {...props} />,
  Wallet: (props: Record<string, unknown>) => <span data-testid="wallet-icon" {...props} />,
}));

const mockCreatePayment = vi.fn();
const mockCreateSubscription = vi.fn();
const mockUpgradeSubscription = vi.fn();

vi.mock('@/lib/payment-api', () => ({
  paymentApi: {
    createPayment: (...args: unknown[]) => mockCreatePayment(...args),
  },
}));

vi.mock('@/lib/subscription-api', () => ({
  subscriptionApi: {
    createSubscription: (...args: unknown[]) => mockCreateSubscription(...args),
    upgradeSubscription: (...args: unknown[]) => mockUpgradeSubscription(...args),
  },
}));

vi.mock('@/lib/currency', () => ({
  formatVND: (amount: string | number) => `${Number(amount).toLocaleString()} đ`,
}));

vi.mock('@/components/error-boundary', () => ({
  ComponentErrorBoundary: ({ children }: { children: React.ReactNode }) => <>{children}</>,
}));

import { CheckoutModal } from '../checkout-modal';

const basePlan = {
  id: 'plan-1',
  tier: 'AGENT_PRO',
  name: 'Môi giới Pro',
  priceMonthlyVND: '499000',
  priceYearlyVND: '4990000',
  maxListings: 50,
  maxSavedSearches: 10,
  features: {},
  isActive: true,
};

describe('CheckoutModal', () => {
  const onOpenChange = vi.fn();

  beforeEach(() => {
    vi.clearAllMocks();
    mockCreatePayment.mockResolvedValue({ paymentUrl: 'https://vnpay.vn/pay', paymentId: 'p1', providerTxId: 'tx1' });
    mockCreateSubscription.mockResolvedValue({ subscriptionId: 's1' });
    mockUpgradeSubscription.mockResolvedValue({ subscriptionId: 's1' });
    // Mock window.location
    Object.defineProperty(window, 'location', {
      writable: true,
      value: { ...window.location, href: 'http://localhost:3000/vi/pricing', origin: 'http://localhost:3000', pathname: '/vi/pricing' },
    });
  });

  it('renders nothing when plan is null', () => {
    const { container } = render(
      <CheckoutModal open={true} onOpenChange={onOpenChange} plan={null} billingCycle="monthly" />,
    );
    expect(container.querySelector('[role="dialog"]')).not.toBeInTheDocument();
  });

  it('renders order summary with plan name and monthly price', () => {
    render(
      <CheckoutModal open={true} onOpenChange={onOpenChange} plan={basePlan} billingCycle="monthly" />,
    );
    expect(screen.getByText('Đăng ký gói dịch vụ')).toBeInTheDocument();
    expect(screen.getAllByText('Môi giới Pro').length).toBeGreaterThanOrEqual(1);
    expect(screen.getByText('Hàng tháng')).toBeInTheDocument();
    expect(screen.getAllByText(/499,000/).length).toBeGreaterThanOrEqual(1);
  });

  it('renders yearly badge and yearly price', () => {
    render(
      <CheckoutModal open={true} onOpenChange={onOpenChange} plan={basePlan} billingCycle="yearly" />,
    );
    expect(screen.getByText('Hàng năm')).toBeInTheDocument();
    expect(screen.getByText('-17%')).toBeInTheDocument();
    expect(screen.getAllByText(/4,990,000/).length).toBeGreaterThanOrEqual(1);
  });

  it('renders upgrade title when isUpgrade=true', () => {
    render(
      <CheckoutModal open={true} onOpenChange={onOpenChange} plan={basePlan} billingCycle="monthly" isUpgrade currentTier="FREE" />,
    );
    expect(screen.getByText('Nâng cấp gói dịch vụ')).toBeInTheDocument();
    expect(screen.getByText(/Miễn phí/)).toBeInTheDocument();
  });

  it('renders all three payment providers', () => {
    render(
      <CheckoutModal open={true} onOpenChange={onOpenChange} plan={basePlan} billingCycle="monthly" />,
    );
    expect(screen.getByText('VNPay')).toBeInTheDocument();
    expect(screen.getByText('MoMo')).toBeInTheDocument();
    expect(screen.getByText('ZaloPay')).toBeInTheDocument();
  });

  it('selects a different payment provider on click', async () => {
    render(
      <CheckoutModal open={true} onOpenChange={onOpenChange} plan={basePlan} billingCycle="monthly" />,
    );
    const momoButton = screen.getByText('MoMo').closest('button')!;
    await userEvent.click(momoButton);
    // MoMo button should now have primary styling (ring-1 ring-primary)
    expect(momoButton.className).toContain('border-primary');
  });

  it('calls createSubscription + createPayment on checkout', async () => {
    render(
      <CheckoutModal open={true} onOpenChange={onOpenChange} plan={basePlan} billingCycle="monthly" />,
    );
    await userEvent.click(screen.getByRole('button', { name: /thanh toán/i }));

    await waitFor(() => {
      expect(mockCreateSubscription).toHaveBeenCalledWith('AGENT_PRO', 'monthly');
      expect(mockCreatePayment).toHaveBeenCalledWith(
        expect.objectContaining({
          provider: 'VNPAY',
          type: 'SUBSCRIPTION',
          amountVND: 499000,
        }),
      );
    });
  });

  it('calls upgradeSubscription instead of createSubscription for upgrades', async () => {
    render(
      <CheckoutModal open={true} onOpenChange={onOpenChange} plan={basePlan} billingCycle="monthly" isUpgrade />,
    );
    await userEvent.click(screen.getByRole('button', { name: /thanh toán/i }));

    await waitFor(() => {
      expect(mockUpgradeSubscription).toHaveBeenCalledWith('AGENT_PRO');
      expect(mockCreateSubscription).not.toHaveBeenCalled();
    });
  });

  it('displays error message when payment fails', async () => {
    mockCreateSubscription.mockRejectedValue(new Error('Hệ thống bận'));
    render(
      <CheckoutModal open={true} onOpenChange={onOpenChange} plan={basePlan} billingCycle="monthly" />,
    );
    await userEvent.click(screen.getByRole('button', { name: /thanh toán/i }));

    await waitFor(() => {
      expect(screen.getByText('Hệ thống bận')).toBeInTheDocument();
    });
  });

  it('disables close button and providers while processing', async () => {
    // Make the payment hang
    mockCreateSubscription.mockReturnValue(new Promise(() => {}));
    render(
      <CheckoutModal open={true} onOpenChange={onOpenChange} plan={basePlan} billingCycle="monthly" />,
    );
    await userEvent.click(screen.getByRole('button', { name: /thanh toán/i }));

    await waitFor(() => {
      expect(screen.getByText(/đang xử lý/i)).toBeInTheDocument();
      expect(screen.getByRole('button', { name: /hủy/i })).toBeDisabled();
    });
  });

  it('dismiss error on close button click', async () => {
    mockCreateSubscription.mockRejectedValue(new Error('Lỗi test'));
    render(
      <CheckoutModal open={true} onOpenChange={onOpenChange} plan={basePlan} billingCycle="monthly" />,
    );
    await userEvent.click(screen.getByRole('button', { name: /thanh toán/i }));

    await waitFor(() => {
      expect(screen.getByText('Lỗi test')).toBeInTheDocument();
    });

    await userEvent.click(screen.getByText('Đóng'));
    expect(screen.queryByText('Lỗi test')).not.toBeInTheDocument();
  });
});
