import { test, expect, Page } from '@playwright/test';

/**
 * Transaction Analytics and Refund E2E Tests
 *
 * Tests the complete transaction analytics and refund flow including:
 * - Transaction list display
 * - Transaction filtering
 * - Transaction detail modal
 * - Refund functionality
 * - Export functionality
 * - Payouts tab
 */

// Helper to login as business owner
async function loginAsBusinessOwner(page: Page, subdomain: string = 'acme') {
  await page.goto(`http://${subdomain}.lvh.me:5173`);
  await page.waitForLoadState('networkidle');

  // Check if login is needed
  const loginHeading = page.getByRole('heading', { name: /sign in/i });
  if (await loginHeading.isVisible({ timeout: 3000 }).catch(() => false)) {
    await page.getByPlaceholder(/username/i).fill(`${subdomain}_owner`);
    await page.getByPlaceholder(/password/i).fill('testpass123');
    await page.getByRole('button', { name: /sign in/i }).click();
    await page.waitForLoadState('networkidle');
  }
}

// Helper to navigate to payments page
async function navigateToPayments(page: Page, subdomain: string = 'acme') {
  const paymentsLink = page.getByRole('link', { name: /payments|billing/i });
  if (await paymentsLink.isVisible({ timeout: 3000 }).catch(() => false)) {
    await paymentsLink.click();
    await page.waitForLoadState('networkidle');
  } else {
    await page.goto(`http://${subdomain}.lvh.me:5173/payments`);
    await page.waitForLoadState('networkidle');
  }
}

// Mock transaction data
const mockTransactions = {
  count: 3,
  total_pages: 1,
  results: [
    {
      id: 1,
      stripe_payment_intent_id: 'pi_test_succeeded_123',
      stripe_charge_id: 'ch_test_succeeded_123',
      transaction_type: 'payment',
      status: 'succeeded',
      amount: 5000,
      amount_display: '$50.00',
      application_fee_amount: 150,
      fee_display: '$1.50',
      net_amount: 4850,
      currency: 'usd',
      customer_name: 'Test Customer',
      customer_email: 'test@example.com',
      created_at: new Date().toISOString(),
      updated_at: new Date().toISOString(),
    },
    {
      id: 2,
      stripe_payment_intent_id: 'pi_test_refunded_456',
      stripe_charge_id: 'ch_test_refunded_456',
      transaction_type: 'payment',
      status: 'refunded',
      amount: 10000,
      amount_display: '$100.00',
      application_fee_amount: 300,
      fee_display: '$3.00',
      net_amount: 9700,
      currency: 'usd',
      customer_name: 'Another Customer',
      customer_email: 'another@example.com',
      created_at: new Date().toISOString(),
      updated_at: new Date().toISOString(),
    },
    {
      id: 3,
      stripe_payment_intent_id: 'pi_test_partial_789',
      stripe_charge_id: 'ch_test_partial_789',
      transaction_type: 'payment',
      status: 'partially_refunded',
      amount: 7500,
      amount_display: '$75.00',
      application_fee_amount: 225,
      fee_display: '$2.25',
      net_amount: 7275,
      currency: 'usd',
      customer_name: 'Partial Customer',
      customer_email: 'partial@example.com',
      created_at: new Date().toISOString(),
      updated_at: new Date().toISOString(),
    },
  ],
};

// Mock transaction detail with refund capability
const mockTransactionDetail = {
  ...mockTransactions.results[0],
  can_refund: true,
  refundable_amount: 5000,
  total_refunded: 0,
  refunds: [],
  payment_method_info: {
    type: 'card',
    brand: 'Visa',
    last4: '4242',
    exp_month: 12,
    exp_year: 2025,
    funding: 'credit',
  },
  description: 'Payment for appointment',
  stripe_data: {},
};

// Mock transaction summary
const mockSummary = {
  total_transactions: 10,
  total_volume: 50000,
  total_volume_display: '$500.00',
  total_fees: 1500,
  total_fees_display: '$15.00',
  net_revenue: 48500,
  net_revenue_display: '$485.00',
  successful_transactions: 8,
  failed_transactions: 1,
  refunded_transactions: 1,
  average_transaction: 5000,
  average_transaction_display: '$50.00',
};

// Mock balance
const mockBalance = {
  available: [{ amount: 150000, currency: 'usd', amount_display: '$1,500.00' }],
  pending: [{ amount: 25000, currency: 'usd', amount_display: '$250.00' }],
  available_total: 150000,
  pending_total: 25000,
};

// Mock payment config (can accept payments)
const mockPaymentConfig = {
  payment_mode: 'connect',
  tier: 'Professional',
  can_accept_payments: true,
  api_keys: null,
  connect_account: {
    id: 1,
    stripe_account_id: 'acct_test123',
    account_type: 'custom',
    status: 'active',
    charges_enabled: true,
    payouts_enabled: true,
    details_submitted: true,
    onboarding_complete: true,
  },
};

test.describe('Transaction Analytics - Overview Tab', () => {
  test.beforeEach(async ({ page }) => {
    // Clear storage
    await page.context().clearCookies();

    // Mock API responses
    await page.route('**/api/payments/config/status/**', (route) => {
      route.fulfill({
        status: 200,
        contentType: 'application/json',
        body: JSON.stringify(mockPaymentConfig),
      });
    });

    await page.route('**/api/payments/transactions/**', (route) => {
      if (route.request().url().includes('/summary')) {
        route.fulfill({
          status: 200,
          contentType: 'application/json',
          body: JSON.stringify(mockSummary),
        });
      } else {
        route.fulfill({
          status: 200,
          contentType: 'application/json',
          body: JSON.stringify(mockTransactions),
        });
      }
    });

    await page.route('**/api/payments/transactions/balance/**', (route) => {
      route.fulfill({
        status: 200,
        contentType: 'application/json',
        body: JSON.stringify(mockBalance),
      });
    });
  });

  test('should display overview tab with summary cards', async ({ page }) => {
    await loginAsBusinessOwner(page);
    await navigateToPayments(page);

    // Should show the Payments & Analytics heading
    await expect(page.getByRole('heading', { name: /payments.*analytics/i })).toBeVisible();

    // Should show overview tab by default
    await expect(page.getByRole('button', { name: /overview/i })).toBeVisible();

    // Wait for data to load
    await page.waitForTimeout(1000);

    // Should show summary cards
    await expect(page.getByText(/total revenue/i)).toBeVisible();
    await expect(page.getByText(/available balance/i)).toBeVisible();
    await expect(page.getByText(/success rate/i)).toBeVisible();
  });

  test('should show recent transactions in overview', async ({ page }) => {
    await loginAsBusinessOwner(page);
    await navigateToPayments(page);

    // Wait for transactions to load
    await page.waitForTimeout(1000);

    // Should show recent transactions section
    await expect(page.getByText(/recent transactions/i)).toBeVisible();

    // Should show View All link
    await expect(page.getByText(/view all/i)).toBeVisible();
  });
});

test.describe('Transaction List and Filtering', () => {
  test.beforeEach(async ({ page }) => {
    await page.context().clearCookies();

    await page.route('**/api/payments/config/status/**', (route) => {
      route.fulfill({
        status: 200,
        contentType: 'application/json',
        body: JSON.stringify(mockPaymentConfig),
      });
    });

    await page.route('**/api/payments/transactions/**', (route) => {
      const url = route.request().url();
      if (url.includes('/summary')) {
        route.fulfill({
          status: 200,
          contentType: 'application/json',
          body: JSON.stringify(mockSummary),
        });
      } else if (url.includes('/balance')) {
        route.fulfill({
          status: 200,
          contentType: 'application/json',
          body: JSON.stringify(mockBalance),
        });
      } else if (url.includes('status=succeeded')) {
        // Filtered by succeeded status
        route.fulfill({
          status: 200,
          contentType: 'application/json',
          body: JSON.stringify({
            count: 1,
            total_pages: 1,
            results: [mockTransactions.results[0]],
          }),
        });
      } else {
        route.fulfill({
          status: 200,
          contentType: 'application/json',
          body: JSON.stringify(mockTransactions),
        });
      }
    });
  });

  test('should navigate to transactions tab and display list', async ({ page }) => {
    await loginAsBusinessOwner(page);
    await navigateToPayments(page);

    // Click on Transactions tab
    await page.getByRole('button', { name: /transactions/i }).click();
    await page.waitForTimeout(500);

    // Should show transaction table headers
    await expect(page.getByText('Customer').first()).toBeVisible();
    await expect(page.getByText('Amount').first()).toBeVisible();
    await expect(page.getByText('Status').first()).toBeVisible();
  });

  test('should show status filters', async ({ page }) => {
    await loginAsBusinessOwner(page);
    await navigateToPayments(page);

    // Click on Transactions tab
    await page.getByRole('button', { name: /transactions/i }).click();

    // Should show status filter dropdown
    const statusFilter = page.locator('select').filter({ hasText: /all statuses/i });
    await expect(statusFilter).toBeVisible();

    // Should have filter options
    await statusFilter.click();
    await expect(page.getByRole('option', { name: /succeeded/i })).toBeVisible();
    await expect(page.getByRole('option', { name: /pending/i })).toBeVisible();
    await expect(page.getByRole('option', { name: /failed/i })).toBeVisible();
    await expect(page.getByRole('option', { name: /refunded/i })).toBeVisible();
  });

  test('should show transaction type filters', async ({ page }) => {
    await loginAsBusinessOwner(page);
    await navigateToPayments(page);

    // Click on Transactions tab
    await page.getByRole('button', { name: /transactions/i }).click();

    // Should show type filter dropdown
    const typeFilter = page.locator('select').filter({ hasText: /all types/i });
    await expect(typeFilter).toBeVisible();
  });

  test('should show date range inputs', async ({ page }) => {
    await loginAsBusinessOwner(page);
    await navigateToPayments(page);

    // Click on Transactions tab
    await page.getByRole('button', { name: /transactions/i }).click();

    // Should show date inputs
    const dateInputs = page.locator('input[type="date"]');
    await expect(dateInputs.first()).toBeVisible();
  });

  test('should show refresh button', async ({ page }) => {
    await loginAsBusinessOwner(page);
    await navigateToPayments(page);

    // Click on Transactions tab
    await page.getByRole('button', { name: /transactions/i }).click();

    // Should show refresh button
    await expect(page.getByRole('button', { name: /refresh/i })).toBeVisible();
  });

  test('should display status badges correctly', async ({ page }) => {
    await loginAsBusinessOwner(page);
    await navigateToPayments(page);

    // Click on Transactions tab
    await page.getByRole('button', { name: /transactions/i }).click();
    await page.waitForTimeout(500);

    // Should show different status badges
    await expect(page.getByText('Succeeded').first()).toBeVisible();
    await expect(page.getByText('Refunded').first()).toBeVisible();
    await expect(page.getByText('Partially Refunded').first()).toBeVisible();
  });
});

test.describe('Transaction Detail Modal', () => {
  test.beforeEach(async ({ page }) => {
    await page.context().clearCookies();

    await page.route('**/api/payments/config/status/**', (route) => {
      route.fulfill({
        status: 200,
        contentType: 'application/json',
        body: JSON.stringify(mockPaymentConfig),
      });
    });

    await page.route('**/api/payments/transactions/**', (route) => {
      const url = route.request().url();
      if (url.match(/\/transactions\/\d+\/?$/)) {
        // Single transaction detail
        route.fulfill({
          status: 200,
          contentType: 'application/json',
          body: JSON.stringify(mockTransactionDetail),
        });
      } else if (url.includes('/summary')) {
        route.fulfill({
          status: 200,
          contentType: 'application/json',
          body: JSON.stringify(mockSummary),
        });
      } else if (url.includes('/balance')) {
        route.fulfill({
          status: 200,
          contentType: 'application/json',
          body: JSON.stringify(mockBalance),
        });
      } else {
        route.fulfill({
          status: 200,
          contentType: 'application/json',
          body: JSON.stringify(mockTransactions),
        });
      }
    });
  });

  test('should open transaction detail modal when clicking row', async ({ page }) => {
    await loginAsBusinessOwner(page);
    await navigateToPayments(page);

    // Click on Transactions tab
    await page.getByRole('button', { name: /transactions/i }).click();
    await page.waitForTimeout(500);

    // Click on a transaction row (click the View button)
    await page.getByRole('button', { name: /view/i }).first().click();
    await page.waitForTimeout(500);

    // Modal should open
    await expect(page.getByRole('heading', { name: /transaction details/i })).toBeVisible();
  });

  test('should display customer information in modal', async ({ page }) => {
    await loginAsBusinessOwner(page);
    await navigateToPayments(page);

    // Navigate to transactions and open modal
    await page.getByRole('button', { name: /transactions/i }).click();
    await page.waitForTimeout(500);
    await page.getByRole('button', { name: /view/i }).first().click();
    await page.waitForTimeout(500);

    // Should show customer section
    await expect(page.getByText(/customer/i)).toBeVisible();
  });

  test('should display amount breakdown in modal', async ({ page }) => {
    await loginAsBusinessOwner(page);
    await navigateToPayments(page);

    // Navigate to transactions and open modal
    await page.getByRole('button', { name: /transactions/i }).click();
    await page.waitForTimeout(500);
    await page.getByRole('button', { name: /view/i }).first().click();
    await page.waitForTimeout(500);

    // Should show amount breakdown
    await expect(page.getByText(/gross amount/i)).toBeVisible();
    await expect(page.getByText(/platform fee/i)).toBeVisible();
  });

  test('should show Issue Refund button for refundable transactions', async ({ page }) => {
    await loginAsBusinessOwner(page);
    await navigateToPayments(page);

    // Navigate to transactions and open modal
    await page.getByRole('button', { name: /transactions/i }).click();
    await page.waitForTimeout(500);
    await page.getByRole('button', { name: /view/i }).first().click();
    await page.waitForTimeout(500);

    // Should show Issue Refund button
    await expect(page.getByRole('button', { name: /issue refund/i })).toBeVisible();
  });

  test('should close modal when clicking X button', async ({ page }) => {
    await loginAsBusinessOwner(page);
    await navigateToPayments(page);

    // Navigate to transactions and open modal
    await page.getByRole('button', { name: /transactions/i }).click();
    await page.waitForTimeout(500);
    await page.getByRole('button', { name: /view/i }).first().click();
    await page.waitForTimeout(500);

    // Close modal
    const closeButton = page.locator('[role="dialog"]').getByRole('button').first();
    if (await closeButton.isVisible()) {
      await closeButton.click();
    } else {
      // Alternative: click X button by finding it
      await page.keyboard.press('Escape');
    }

    await page.waitForTimeout(300);

    // Modal should be closed
    await expect(page.getByRole('heading', { name: /transaction details/i })).not.toBeVisible();
  });
});

test.describe('Refund Functionality', () => {
  test.beforeEach(async ({ page }) => {
    await page.context().clearCookies();

    await page.route('**/api/payments/config/status/**', (route) => {
      route.fulfill({
        status: 200,
        contentType: 'application/json',
        body: JSON.stringify(mockPaymentConfig),
      });
    });

    await page.route('**/api/payments/transactions/**', (route) => {
      const url = route.request().url();
      if (url.match(/\/transactions\/\d+\/refund\/?$/)) {
        // Refund endpoint
        route.fulfill({
          status: 200,
          contentType: 'application/json',
          body: JSON.stringify({
            success: true,
            refund_id: 're_test123',
            amount: 5000,
            amount_display: '$50.00',
            status: 'succeeded',
            reason: 'requested_by_customer',
            transaction_status: 'refunded',
          }),
        });
      } else if (url.match(/\/transactions\/\d+\/?$/)) {
        route.fulfill({
          status: 200,
          contentType: 'application/json',
          body: JSON.stringify(mockTransactionDetail),
        });
      } else if (url.includes('/summary')) {
        route.fulfill({
          status: 200,
          contentType: 'application/json',
          body: JSON.stringify(mockSummary),
        });
      } else if (url.includes('/balance')) {
        route.fulfill({
          status: 200,
          contentType: 'application/json',
          body: JSON.stringify(mockBalance),
        });
      } else {
        route.fulfill({
          status: 200,
          contentType: 'application/json',
          body: JSON.stringify(mockTransactions),
        });
      }
    });
  });

  test('should show refund form when clicking Issue Refund', async ({ page }) => {
    await loginAsBusinessOwner(page);
    await navigateToPayments(page);

    // Navigate to transactions and open modal
    await page.getByRole('button', { name: /transactions/i }).click();
    await page.waitForTimeout(500);
    await page.getByRole('button', { name: /view/i }).first().click();
    await page.waitForTimeout(500);

    // Click Issue Refund
    await page.getByRole('button', { name: /issue refund/i }).click();

    // Should show refund form
    await expect(page.getByText(/full refund/i)).toBeVisible();
    await expect(page.getByText(/partial refund/i)).toBeVisible();
    await expect(page.getByText(/refund reason/i)).toBeVisible();
  });

  test('should show refund reason options', async ({ page }) => {
    await loginAsBusinessOwner(page);
    await navigateToPayments(page);

    // Navigate to transactions and open modal
    await page.getByRole('button', { name: /transactions/i }).click();
    await page.waitForTimeout(500);
    await page.getByRole('button', { name: /view/i }).first().click();
    await page.waitForTimeout(500);

    // Click Issue Refund
    await page.getByRole('button', { name: /issue refund/i }).click();

    // Should show reason dropdown
    const reasonSelect = page.locator('select').filter({ hasText: /requested by customer/i });
    await expect(reasonSelect).toBeVisible();
  });

  test('should show partial refund amount input when partial selected', async ({ page }) => {
    await loginAsBusinessOwner(page);
    await navigateToPayments(page);

    // Navigate to transactions and open modal
    await page.getByRole('button', { name: /transactions/i }).click();
    await page.waitForTimeout(500);
    await page.getByRole('button', { name: /view/i }).first().click();
    await page.waitForTimeout(500);

    // Click Issue Refund
    await page.getByRole('button', { name: /issue refund/i }).click();

    // Select partial refund
    await page.getByLabel(/partial refund/i).check();

    // Should show amount input
    await expect(page.locator('input[type="number"]')).toBeVisible();
  });

  test('should have Confirm Refund and Cancel buttons', async ({ page }) => {
    await loginAsBusinessOwner(page);
    await navigateToPayments(page);

    // Navigate to transactions and open modal
    await page.getByRole('button', { name: /transactions/i }).click();
    await page.waitForTimeout(500);
    await page.getByRole('button', { name: /view/i }).first().click();
    await page.waitForTimeout(500);

    // Click Issue Refund
    await page.getByRole('button', { name: /issue refund/i }).click();

    // Should show confirm and cancel buttons
    await expect(page.getByRole('button', { name: /confirm refund/i })).toBeVisible();
    await expect(page.getByRole('button', { name: /cancel/i })).toBeVisible();
  });

  test('should hide refund form when clicking Cancel', async ({ page }) => {
    await loginAsBusinessOwner(page);
    await navigateToPayments(page);

    // Navigate to transactions and open modal
    await page.getByRole('button', { name: /transactions/i }).click();
    await page.waitForTimeout(500);
    await page.getByRole('button', { name: /view/i }).first().click();
    await page.waitForTimeout(500);

    // Click Issue Refund
    await page.getByRole('button', { name: /issue refund/i }).click();
    await expect(page.getByText(/full refund/i)).toBeVisible();

    // Click Cancel
    await page.getByRole('button', { name: /cancel/i }).click();

    // Refund form should be hidden
    await expect(page.getByText(/full refund/i)).not.toBeVisible();
  });
});

test.describe('Export Functionality', () => {
  test.beforeEach(async ({ page }) => {
    await page.context().clearCookies();

    await page.route('**/api/payments/config/status/**', (route) => {
      route.fulfill({
        status: 200,
        contentType: 'application/json',
        body: JSON.stringify(mockPaymentConfig),
      });
    });

    await page.route('**/api/payments/transactions/**', (route) => {
      const url = route.request().url();
      if (url.includes('/export')) {
        // Return a blob for export
        route.fulfill({
          status: 200,
          contentType: 'text/csv',
          body: 'id,amount,status\n1,5000,succeeded',
        });
      } else if (url.includes('/summary')) {
        route.fulfill({
          status: 200,
          contentType: 'application/json',
          body: JSON.stringify(mockSummary),
        });
      } else if (url.includes('/balance')) {
        route.fulfill({
          status: 200,
          contentType: 'application/json',
          body: JSON.stringify(mockBalance),
        });
      } else {
        route.fulfill({
          status: 200,
          contentType: 'application/json',
          body: JSON.stringify(mockTransactions),
        });
      }
    });
  });

  test('should show Export Data button', async ({ page }) => {
    await loginAsBusinessOwner(page);
    await navigateToPayments(page);

    // Should show Export Data button
    await expect(page.getByRole('button', { name: /export data/i })).toBeVisible();
  });

  test('should open export modal when clicking Export Data', async ({ page }) => {
    await loginAsBusinessOwner(page);
    await navigateToPayments(page);

    // Click Export Data button
    await page.getByRole('button', { name: /export data/i }).click();

    // Should show export modal
    await expect(page.getByRole('heading', { name: /export transactions/i })).toBeVisible();
  });

  test('should show export format options', async ({ page }) => {
    await loginAsBusinessOwner(page);
    await navigateToPayments(page);

    // Click Export Data button
    await page.getByRole('button', { name: /export data/i }).click();

    // Should show format options
    await expect(page.getByText('CSV')).toBeVisible();
    await expect(page.getByText('Excel')).toBeVisible();
    await expect(page.getByText('PDF')).toBeVisible();
    await expect(page.getByText('QuickBooks')).toBeVisible();
  });

  test('should have date range inputs in export modal', async ({ page }) => {
    await loginAsBusinessOwner(page);
    await navigateToPayments(page);

    // Click Export Data button
    await page.getByRole('button', { name: /export data/i }).click();

    // Should show date range inputs
    await expect(page.getByText(/date range/i)).toBeVisible();
    const dateInputs = page.locator('[role="dialog"]').locator('input[type="date"]');
    await expect(dateInputs.first()).toBeVisible();
  });

  test('should close export modal when clicking X', async ({ page }) => {
    await loginAsBusinessOwner(page);
    await navigateToPayments(page);

    // Click Export Data button
    await page.getByRole('button', { name: /export data/i }).click();
    await expect(page.getByRole('heading', { name: /export transactions/i })).toBeVisible();

    // Close modal
    await page.keyboard.press('Escape');
    await page.waitForTimeout(300);

    // Modal should be closed
    await expect(page.getByRole('heading', { name: /export transactions/i })).not.toBeVisible();
  });
});

test.describe('Payouts Tab', () => {
  test.beforeEach(async ({ page }) => {
    await page.context().clearCookies();

    await page.route('**/api/payments/config/status/**', (route) => {
      route.fulfill({
        status: 200,
        contentType: 'application/json',
        body: JSON.stringify(mockPaymentConfig),
      });
    });

    await page.route('**/api/payments/transactions/**', (route) => {
      const url = route.request().url();
      if (url.includes('/payouts')) {
        route.fulfill({
          status: 200,
          contentType: 'application/json',
          body: JSON.stringify({
            payouts: [
              {
                id: 'po_test123',
                amount: 100000,
                amount_display: '$1,000.00',
                currency: 'usd',
                status: 'paid',
                arrival_date: Date.now() / 1000,
                method: 'standard',
              },
              {
                id: 'po_test456',
                amount: 50000,
                amount_display: '$500.00',
                currency: 'usd',
                status: 'pending',
                arrival_date: Date.now() / 1000 + 86400,
                method: 'standard',
              },
            ],
          }),
        });
      } else if (url.includes('/balance')) {
        route.fulfill({
          status: 200,
          contentType: 'application/json',
          body: JSON.stringify(mockBalance),
        });
      } else if (url.includes('/summary')) {
        route.fulfill({
          status: 200,
          contentType: 'application/json',
          body: JSON.stringify(mockSummary),
        });
      } else {
        route.fulfill({
          status: 200,
          contentType: 'application/json',
          body: JSON.stringify(mockTransactions),
        });
      }
    });
  });

  test('should navigate to payouts tab', async ({ page }) => {
    await loginAsBusinessOwner(page);
    await navigateToPayments(page);

    // Click on Payouts tab
    await page.getByRole('button', { name: /payouts/i }).click();

    // Should show balance summary
    await expect(page.getByText(/available for payout/i)).toBeVisible();
    await expect(page.getByText(/pending/i)).toBeVisible();
  });

  test('should display payout history', async ({ page }) => {
    await loginAsBusinessOwner(page);
    await navigateToPayments(page);

    // Click on Payouts tab
    await page.getByRole('button', { name: /payouts/i }).click();

    // Should show payout history section
    await expect(page.getByText(/payout history/i)).toBeVisible();
  });

  test('should show payout table headers', async ({ page }) => {
    await loginAsBusinessOwner(page);
    await navigateToPayments(page);

    // Click on Payouts tab
    await page.getByRole('button', { name: /payouts/i }).click();
    await page.waitForTimeout(500);

    // Should show table headers
    await expect(page.getByText('Payout ID').first()).toBeVisible();
    await expect(page.getByText('Arrival Date').first()).toBeVisible();
  });
});

test.describe('Payment Setup Required State', () => {
  test('should show setup required message when payments not configured', async ({ page }) => {
    await page.context().clearCookies();

    // Mock unconfigured payment status
    await page.route('**/api/payments/config/status/**', (route) => {
      route.fulfill({
        status: 200,
        contentType: 'application/json',
        body: JSON.stringify({
          payment_mode: 'none',
          tier: 'Professional',
          can_accept_payments: false,
          api_keys: null,
          connect_account: null,
        }),
      });
    });

    await page.route('**/api/payments/transactions/**', (route) => {
      route.fulfill({
        status: 200,
        contentType: 'application/json',
        body: JSON.stringify({ count: 0, total_pages: 0, results: [] }),
      });
    });

    await loginAsBusinessOwner(page);
    await navigateToPayments(page);

    // Should show setup required message
    await expect(page.getByText(/payment setup required/i)).toBeVisible();
    await expect(page.getByRole('button', { name: /go to settings/i })).toBeVisible();
  });

  test('should navigate to settings when clicking Go to Settings', async ({ page }) => {
    await page.context().clearCookies();

    await page.route('**/api/payments/config/status/**', (route) => {
      route.fulfill({
        status: 200,
        contentType: 'application/json',
        body: JSON.stringify({
          payment_mode: 'none',
          tier: 'Professional',
          can_accept_payments: false,
          api_keys: null,
          connect_account: null,
        }),
      });
    });

    await page.route('**/api/payments/transactions/**', (route) => {
      route.fulfill({
        status: 200,
        contentType: 'application/json',
        body: JSON.stringify({ count: 0, total_pages: 0, results: [] }),
      });
    });

    await loginAsBusinessOwner(page);
    await navigateToPayments(page);

    // Click Go to Settings
    await page.getByRole('button', { name: /go to settings/i }).click();

    // Settings tab should be active
    const settingsTab = page.getByRole('button', { name: /settings/i });
    await expect(settingsTab).toHaveClass(/border-brand-500|text-brand/);
  });
});

test.describe('Error Handling', () => {
  test('should handle transaction load error gracefully', async ({ page }) => {
    await page.context().clearCookies();

    await page.route('**/api/payments/config/status/**', (route) => {
      route.fulfill({
        status: 200,
        contentType: 'application/json',
        body: JSON.stringify(mockPaymentConfig),
      });
    });

    // Mock transaction API error
    await page.route('**/api/payments/transactions/**', (route) => {
      if (route.request().url().includes('/summary')) {
        route.fulfill({
          status: 200,
          contentType: 'application/json',
          body: JSON.stringify(mockSummary),
        });
      } else if (route.request().url().includes('/balance')) {
        route.fulfill({
          status: 200,
          contentType: 'application/json',
          body: JSON.stringify(mockBalance),
        });
      } else if (route.request().url().match(/\/transactions\/\d+\/?$/)) {
        route.fulfill({
          status: 500,
          contentType: 'application/json',
          body: JSON.stringify({ error: 'Internal server error' }),
        });
      } else {
        route.fulfill({
          status: 200,
          contentType: 'application/json',
          body: JSON.stringify(mockTransactions),
        });
      }
    });

    await loginAsBusinessOwner(page);
    await navigateToPayments(page);

    // Navigate to transactions and try to open modal
    await page.getByRole('button', { name: /transactions/i }).click();
    await page.waitForTimeout(500);
    await page.getByRole('button', { name: /view/i }).first().click();
    await page.waitForTimeout(500);

    // Should show error message in modal
    await expect(page.getByText(/failed to load/i)).toBeVisible();
  });
});
