import { expect, test } from '@playwright/test';
import { Wait } from './helpers/wait';
import { getAdminToken, installAdminToken, navigateInBlazor, waitForAdminSection } from './helpers/admin-auth';

const username = process.env.E2E_ADMIN_USERNAME ?? 'admin';
const password = process.env.E2E_ADMIN_PASSWORD;
const baseUrl = (process.env.E2E_BASE_URL ?? 'https://www.taxbaik.com').replace(/\/$/, '');

test.describe('admin CRM pages', () => {
  test.describe.configure({ mode: 'serial' });

  test.beforeEach(async ({ page }) => {
    test.skip(!password, 'E2E_ADMIN_PASSWORD is required.');
    const token = await getAdminToken(page.request, baseUrl, username, password);
    await installAdminToken(page, token);
  });

  test('TaxProfiles page loads with grid and add button', async ({ page }) => {
    await navigateInBlazor(page, `${baseUrl}/admin/tax-profiles`);
    await expect(page).toHaveURL(/\/admin\/tax-profiles$/);
    await waitForAdminSection(page, '세무 프로필');

    await expect(page.getByRole('button', { name: '새 프로필 추가' })).toBeVisible({ timeout: Wait.long });

    await expect(page.locator('.admin-grid, .mud-alert')).toBeVisible({ timeout: Wait.long });
  });

  test('TaxFilingSchedules page loads with D-day tracking', async ({ page }) => {
    await navigateInBlazor(page, `${baseUrl}/admin/tax-filing-schedules`);
    await expect(page).toHaveURL(/\/admin\/tax-filing-schedules$/);
    await waitForAdminSection(page, '신고 일정');

    await expect(page.getByRole('button', { name: '새 일정 추가' })).toBeVisible({ timeout: Wait.long });

    await expect(page.locator('.admin-grid, .mud-alert')).toBeVisible({ timeout: Wait.long });
  });

  test('Contracts page loads with MRR display', async ({ page }) => {
    await navigateInBlazor(page, `${baseUrl}/admin/contracts`);
    await expect(page).toHaveURL(/\/admin\/contracts$/);
    await waitForAdminSection(page, '계약 관리');

    await expect(page.getByRole('button', { name: '새 계약 추가' })).toBeVisible({ timeout: Wait.long });

    await expect(page.locator('.admin-grid, .mud-alert')).toBeVisible({ timeout: Wait.long });
  });

  test('ConsultingActivities page loads with activity records', async ({ page }) => {
    await navigateInBlazor(page, `${baseUrl}/admin/consulting-activities`);
    await expect(page).toHaveURL(/\/admin\/consulting-activities$/);
    await waitForAdminSection(page, '상담 활동 관리');

    await expect(page.getByRole('button', { name: '새 활동 기록' })).toBeVisible({ timeout: Wait.long });

    await expect(page.locator('.admin-grid, .mud-alert')).toBeVisible({ timeout: Wait.long });
  });

  test('RevenueTrackings page loads with payment status tracking', async ({ page }) => {
    await navigateInBlazor(page, `${baseUrl}/admin/revenue-trackings`);
    await expect(page).toHaveURL(/\/admin\/revenue-trackings$/);
    await waitForAdminSection(page, '수익 추적 관리');

    await expect(page.getByRole('button', { name: '새 청구 추가' })).toBeVisible({ timeout: Wait.long });

    await expect(page.locator('.admin-grid, .mud-alert')).toBeVisible({ timeout: Wait.long });
  });

  test('CRM navigation group is visible and expandable', async ({ page }) => {
    await navigateInBlazor(page, `${baseUrl}/admin/dashboard`);

    // 좌측 패널 네비게이션 확인
    const crmGroup = page.getByRole('button', { name: 'CRM & 세무관리' });
    await expect(crmGroup).toBeVisible({ timeout: Wait.long });

    // CRM 그룹의 모든 링크 확인
    const expectedLinks = [
      '세무 프로필',
      '신고 일정',
      '계약 관리',
      '상담 활동',
      '수익 추적'
    ];

    for (const linkText of expectedLinks) {
      const link = page.getByText(linkText, { exact: true });
      await expect(link).toBeVisible({ timeout: Wait.long });
    }
  });

  test('TaxProfiles editor panel is visible on add button click', async ({ page }) => {
    await navigateInBlazor(page, `${baseUrl}/admin/tax-profiles`);

    const addButton = page.getByText('새 프로필 추가');
    await expect(addButton).toBeVisible();
    await addButton.click();
    await expect(page.locator('.admin-editor-panel')).toBeVisible({ timeout: Wait.medium });
  });

  test('No console errors on CRM page navigation', async ({ page }) => {
    const consoleErrors: string[] = [];
    page.on('console', message => {
      if (message.type() === 'error') {
        const text = message.text();
        if (
          text.includes("The value 'get' is not a function") ||
          text.includes('mono_download_assets') ||
          text.includes('Fetch API cannot load')
        ) {
          return;
        }
        consoleErrors.push(text);
      }
    });

    const crmPages = [
      '/admin/tax-profiles',
      '/admin/tax-filing-schedules',
      '/admin/contracts',
      '/admin/consulting-activities',
      '/admin/revenue-trackings'
    ];

    for (const path of crmPages) {
      await navigateInBlazor(page, `${baseUrl}${path}`);
      await expect(page.locator('#blazor-loading')).toBeHidden({ timeout: Wait.medium });
    }

    expect(consoleErrors, 'no console errors during CRM navigation').toEqual([]);
  });

  test('TaxProfiles form displays valid business type combo choices', async ({ page }) => {
    await navigateInBlazor(page, `${baseUrl}/admin/tax-profiles`);
    await expect(page.locator('.admin-grid, .mud-alert')).toBeVisible({ timeout: Wait.long });
    
    const addButton = page.getByText('새 프로필 추가');
    await addButton.click();
    
    // 분할 편집기(admin-editor-panel) 노출 대기
    await expect(page.locator('.admin-editor-panel')).toBeVisible({ timeout: Wait.medium });
    
    const select = page.locator('.admin-editor-panel .mud-select').filter({ hasText: '사업 유형' }).first();
    await expect(select).toBeVisible({ timeout: Wait.medium });
    await expect(select).toContainText('사업 유형', { timeout: Wait.medium });

    const token = await getAdminToken(page.request, baseUrl, username, password!);
    const response = await page.request.get(`${baseUrl}/api/commoncode/group/BUSINESS_TYPE`, {
      headers: { Authorization: `Bearer ${token}` },
    });
    expect(response.status()).toBe(200);
    const body = await response.json();
    const values = (body?.data ?? []).map((item: { codeValue: string }) => item.codeValue);
    expect(values).toEqual(expect.arrayContaining(['일반제조업', '도소매업', '서비스업']));
  });

  test('TaxFilingSchedules form displays filing type combo choices', async ({ page }) => {
    await navigateInBlazor(page, `${baseUrl}/admin/tax-filing-schedules`);
    await expect(page.locator('.admin-grid, .mud-alert')).toBeVisible({ timeout: Wait.long });
    
    const addButton = page.getByText('새 일정 추가');
    await addButton.click();
    
    await expect(page.locator('.admin-editor-panel')).toBeVisible({ timeout: Wait.medium });
    
    const select = page.locator('.admin-editor-panel .mud-select').filter({ hasText: '신고 유형' }).first();
    await expect(select).toBeVisible({ timeout: Wait.medium });
    await expect(select).toContainText('신고 유형', { timeout: Wait.medium });

    const token = await getAdminToken(page.request, baseUrl, username, password!);
    const response = await page.request.get(`${baseUrl}/api/commoncode/group/FILING_TYPE`, {
      headers: { Authorization: `Bearer ${token}` },
    });
    expect(response.status()).toBe(200);
    const body = await response.json();
    const values = (body?.data ?? []).map((item: { codeValue: string }) => item.codeValue);
    expect(values).toEqual(expect.arrayContaining(['종합소득세', '부가가치세']));
  });

  test('Contracts form displays service type combo choices', async ({ page }) => {
    await navigateInBlazor(page, `${baseUrl}/admin/contracts`);
    await expect(page.locator('.admin-grid, .mud-alert')).toBeVisible({ timeout: Wait.long });
    
    const addButton = page.getByRole('button', { name: '새 계약 추가' });
    await addButton.click();
    
    await expect(page.locator('.admin-editor-panel')).toBeVisible({ timeout: 5000 });
    
    const select = page.locator('.admin-editor-panel .mud-select').filter({ hasText: '서비스 유형' }).first();
    await expect(select).toBeVisible({ timeout: Wait.medium });
    await expect(select).toContainText('서비스 유형', { timeout: Wait.medium });

    const token = await getAdminToken(page.request, baseUrl, username, password!);
    const response = await page.request.get(`${baseUrl}/api/commoncode/group/CONTRACT_SERVICE_TYPE`, {
      headers: { Authorization: `Bearer ${token}` },
    });
    expect(response.status()).toBe(200);
    const body = await response.json();
    const values = (body?.data ?? []).map((item: { codeValue: string }) => item.codeValue);
    expect(values).toEqual(expect.arrayContaining(['개인기장대리', '법인기장대리']));
  });
}
);
