// @ts-check
const { test, expect } = require('@playwright/test');
const { login } = require('./helpers/auth');

async function loginAsAdmin(page) {
  await login(page, 'admin');
  await page.locator('input[name="lg_idx"]').first().check();
  await page.click('button[type="submit"]');
  await page.waitForURL(url => !url.pathname.includes('select-local-government'), { timeout: 30000 });
}

async function loginAsLocal(page) {
  await login(page, 'local');
}

// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
// CT-01: 페이지네이션
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
test.describe('CT-01: 페이지네이션', () => {
  test('발주 목록에 데이터 테이블 존재', async ({ page }) => {
    await loginAsLocal(page);
    await page.goto('/bag/bag-orders');
    await expect(page.locator('table.data-table')).toBeVisible();
  });

  test('판매 목록에 데이터 테이블 존재', async ({ page }) => {
    await loginAsLocal(page);
    await page.goto('/bag/bag-sales');
    await expect(page.locator('table.data-table')).toBeVisible();
  });
});

// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
// CT-02: 엑셀 저장
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
test.describe('CT-02: 엑셀 저장', () => {
  test('발주 엑셀 다운로드', async ({ page }) => {
    await loginAsLocal(page);
    await page.goto('/bag/bag-orders');
    const downloadPromise = page.waitForEvent('download', { timeout: 10000 });
    await page.locator('a[href*="export"]').first().click();
    const download = await downloadPromise;
    expect(download.suggestedFilename()).toContain('.csv');
  });

  test('재고 엑셀 다운로드', async ({ page }) => {
    await loginAsLocal(page);
    await page.goto('/bag/bag-inventory');
    const downloadPromise = page.waitForEvent('download', { timeout: 10000 });
    await page.locator('a[href*="export"]').first().click();
    const download = await downloadPromise;
    expect(download.suggestedFilename()).toContain('.csv');
  });
});

// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
// CT-03: 인쇄 버튼
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
test.describe('CT-03: 인쇄 버튼', () => {
  test('발주 목록에 인쇄 버튼 존재', async ({ page }) => {
    await loginAsLocal(page);
    await page.goto('/bag/bag-orders');
    await expect(page.locator('button:has-text("인쇄"), a:has-text("인쇄")')).toBeVisible();
  });
});

// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
// CT-06: 대시보드 실 데이터
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
test.describe('CT-06: 대시보드 실 데이터', () => {
  test('대시보드에 통계 표시', async ({ page }) => {
    await loginAsLocal(page);
    await page.goto('/admin');
    const content = await page.textContent('main');
    expect(content).toBeTruthy();
    expect(content.length).toBeGreaterThan(50);
  });
});

// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
// P2-15: 지정판매소 다조건 조회
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
test.describe('P2-15: 지정판매소 다조건 조회', () => {
  test('이름 검색 필터', async ({ page }) => {
    await loginAsLocal(page);
    await page.goto('/bag/designated-shops?ds_name=CU');
    await expect(page).toHaveURL(/ds_name=CU/);
    await expect(page.locator('input[name="ds_name"]')).toHaveValue('CU');
    await expect(page.locator('#ds-list-body')).toBeAttached();
  });

  test('상태 필터', async ({ page }) => {
    await loginAsLocal(page);
    await page.goto('/bag/designated-shops?ds_state=1');
    await expect(page.locator('select[name="ds_state"]')).toHaveValue('1');
    await expect(page.locator('#ds-list-body')).toBeAttached();
  });

  test('검색 폼에서 이름 입력 후 조회', async ({ page }) => {
    await loginAsLocal(page);
    await page.goto('/bag/designated-shops');
    const nameInput = page.locator('input[name="ds_name"]');
    if (await nameInput.count() > 0) {
      await nameInput.fill('GS');
      await page.click('button:has-text("조회")');
      await expect(page).toHaveURL(/ds_name=GS/);
    }
  });
});

// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
// P2-17: 지정판매소 지도
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
test.describe('P2-17: 지정판매소 지도', () => {
  test('지도 페이지 접근', async ({ page }) => {
    await loginAsLocal(page);
    await page.goto('/bag/designated-shops/map');
    await expect(page).toHaveURL(/\/map/);
  });
});

// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
// P2-18: 지정판매소 현황
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
test.describe('P2-18: 지정판매소 현황', () => {
  test('현황 페이지 접근', async ({ page }) => {
    await loginAsLocal(page);
    await page.goto('/bag/designated-shops/status');
    await expect(page).toHaveURL(/\/status/);
    await expect(page.locator('table.data-table').first()).toBeVisible();
    await expect(page.getByRole('columnheader', { name: '종전(전년도말)' })).toBeVisible();
    await expect(page.getByRole('link', { name: '엑셀저장' })).toBeVisible();
  });

  test('GBMS형 신규/취소 현황(구·군 고정)', async ({ page }) => {
    await loginAsLocal(page);
    await page.goto('/bag/designated-shops/district-new-cancel');
    await expect(page).toHaveURL(/district-new-cancel/);
    await expect(page.locator('.gbms-dnc-table')).toBeVisible();
    await expect(page.getByRole('columnheader', { name: '군·구' })).toBeVisible();
    await expect(page.getByRole('link', { name: '엑셀저장' })).toBeVisible();
  });
});

// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
// P5-04: 년 판매 현황
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
test.describe('P5-04: 년 판매 현황', () => {
  test('년 판매 현황 접근', async ({ page }) => {
    await loginAsLocal(page);
    await page.goto('/bag/reports/yearly-sales');
    await expect(page).toHaveURL(/yearly-sales/);
    await expect(page.locator('#yearly-sales-table')).toBeVisible();
    await expect(page.getByRole('button', { name: '조회' })).toBeVisible();
    await expect(page.getByRole('link', { name: '엑셀저장' })).toBeVisible();
    await expect(page.getByRole('button', { name: '인쇄' })).toBeVisible();
    await expect(page.locator('select[name="gugun_code"]')).toBeVisible();
    await expect(page.locator('select[name="sa_idx"]')).toBeVisible();
  });

  test('연도 변경 조회', async ({ page }) => {
    await loginAsLocal(page);
    await page.goto('/bag/reports/yearly-sales?year=2025');
    await expect(page).toHaveURL(/year=2025/);
  });
});

// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
// P5-05: 지정판매소별 판매현황
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
test.describe('P5-05: 판매소별 판매현황', () => {
  test('판매소별 현황 접근', async ({ page }) => {
    await loginAsLocal(page);
    await page.goto('/bag/reports/shop-sales');
    await expect(page).toHaveURL(/shop-sales/);
    await expect(page.locator('#shop-sales-table')).toBeVisible();
    await expect(page.getByRole('heading', { name: '지정 판매소별 판매현황' }).first()).toBeVisible();
    await expect(page.getByRole('button', { name: '조회' })).toBeVisible();
    await expect(page.getByRole('link', { name: '엑셀저장' })).toBeVisible();
    await expect(page.getByRole('button', { name: '인쇄' })).toBeVisible();
    await expect(page.getByRole('columnheader', { name: '지정판매소' })).toBeVisible();
    await expect(page.getByRole('columnheader', { name: '1월' })).toBeVisible();
    await expect(page.locator('input[name="metric"][value="qty"]')).toBeVisible();
  });

  test('월별 수량 셀에 음수가 표시되지 않음', async ({ page }) => {
    await loginAsLocal(page);
    await page.goto('/bag/reports/shop-sales?metric=qty');
    await expect(page.locator('#shop-sales-table')).toBeVisible();
    const texts = await page.locator('#shop-sales-table td.num-cell').allTextContents();
    for (const raw of texts) {
      const n = raw.replace(/,/g, '').trim();
      if (n === '') {
        continue;
      }
      expect(n.startsWith('-'), `음수 셀: ${raw}`).toBe(false);
    }
  });
});

// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
// P5-06: 홈택스 엑셀
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
test.describe('P5-06: 홈택스 세금계산서 엑셀', () => {
  test('홈택스 처리 화면 및 조회 표', async ({ page }) => {
    await loginAsLocal(page);
    await page.goto('/bag/reports/hometax-export');
    await expect(page.getByRole('heading', { name: '홈택스 처리' }).first()).toBeVisible();
    await expect(page.locator('#hometax-result-table')).toBeVisible();
    await expect(page.locator('#hometax-result-table thead th').first()).toHaveText('전자세금계산서종류');
    await expect(page.getByText('총 건수')).toBeVisible();
  });

  test('홈택스 엑셀 다운로드 응답', async ({ page }) => {
    await loginAsLocal(page);
    const y = new Date().getFullYear();
    const res = await page.request.get(
      `/bag/reports/hometax-export?search=1&start_date=${y}-01-01&end_date=${y}-12-31&write_date=${y}-05-14&export=1`
    );
    expect(res.status()).toBe(200);
    const ct = (res.headers()['content-type'] || '').toLowerCase();
    expect(ct).toContain('application/vnd.ms-excel');
  });
});

// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
// P5-08: 반품/파기 현황
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
test.describe('P5-08: 반품/파기 현황', () => {
  test('반품/파기 목록 접근', async ({ page }) => {
    await loginAsLocal(page);
    await page.goto('/bag/reports/returns');
    await expect(page).toHaveURL(/returns/);
    await expect(page.getByText('반품/파기 현황')).toBeVisible();
    await expect(page.locator('input[name="io_type"][value="in"]')).toBeVisible();
    await expect(page.locator('input[name="io_type"][value="out"]')).toBeVisible();
    await expect(page.locator('th:has-text("반품처")')).toBeVisible();
    await expect(page.locator('th:has-text("종류")')).toBeVisible();
  });

  test('기간·입출고 조회 및 엑셀', async ({ page }) => {
    await loginAsLocal(page);
    await page.goto('/bag/reports/returns?search=1&start_date=2026-05-01&end_date=2026-05-31&io_type=out');
    await expect(page.locator('table.data-table')).toBeVisible();
    await expect(page.locator('table.data-table tbody tr').first()).not.toContainText('해당 자료가 없습니다');
    await expect(page.getByText('반품').first()).toBeVisible();
    await expect(page.getByRole('link', { name: '엑셀저장' })).toBeVisible();
    const res = await page.request.get(
      '/bag/reports/returns/export?search=1&start_date=2026-05-01&end_date=2026-05-31&io_type=out'
    );
    expect(res.status()).toBe(200);
    const ct = (res.headers()['content-type'] || '').toLowerCase();
    expect(ct).toContain('application/vnd.ms-excel');
  });

  test('5월 입고(파기) 조회', async ({ page }) => {
    await loginAsLocal(page);
    await page.goto('/bag/reports/returns?search=1&start_date=2026-05-01&end_date=2026-05-31&io_type=in');
    await expect(page.locator('table.data-table')).toBeVisible();
    await expect(page.locator('table.data-table tbody tr').first()).not.toContainText('해당 자료가 없습니다');
    await expect(page.getByText('물류창고')).toBeVisible();
    await expect(page.getByText('파기').first()).toBeVisible();
  });
});

// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
// P5-10: LOT 수불 조회
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
test.describe('P5-10: LOT 수불 조회', () => {
  test('LOT 수불 페이지 접근', async ({ page }) => {
    await loginAsLocal(page);
    await page.goto('/bag/reports/lot-flow');
    await expect(page).toHaveURL(/lot-flow/);
    await expect(page.getByText('LOT 수불 현황')).toBeVisible();
    await expect(page.getByLabel('봉투번호')).toBeVisible();
  });

  test('바코드 조회 폼', async ({ page }) => {
    await loginAsLocal(page);
    await page.goto('/bag/reports/lot-flow?search=1&barcode=TEST-NOT-FOUND');
    await expect(page).toHaveURL(/barcode=TEST-NOT-FOUND/);
    await expect(page.getByRole('columnheader', { name: '입출고처' })).toBeVisible();
  });
});

// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
// P5-11: 기타 입출고
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
test.describe('P5-11: 기타 입출고', () => {
  test('기타 입출고 페이지 접근', async ({ page }) => {
    await loginAsLocal(page);
    await page.goto('/bag/reports/misc-flow');
    await expect(page).toHaveURL(/misc-flow/);
  });

  test('기타 입출고 화면 구성 (스크린샷·기능목록)', async ({ page }) => {
    await loginAsLocal(page);
    await page.goto('/bag/reports/misc-flow');
    await expect(page.locator('select[name="flow_y"]')).toBeVisible();
    await expect(page.locator('select[name="flow_m"]')).toBeVisible();
    await expect(page.locator('select[name="flow_y"] option').first()).toHaveText('전체');
    await expect(page.locator('select[name="flow_m"] option').nth(1)).toHaveText('1월');
    await expect(page.locator('select[name="bag_kind"]')).toBeVisible();
    await expect(page.getByText('입출고 리스트')).toBeVisible();
    await expect(page.getByText('입출고 일자')).toBeVisible();
    await expect(page.getByText('입출고 봉투 코드')).toBeVisible();
    await expect(page.locator('select[name="bmf_type"]')).toBeVisible();
    await expect(page.locator('input[name="bmf_qty"]')).toBeVisible();
  });
});

// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
// 사이트 메뉴 CRUD (DOM 조작)
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
test.describe('사이트 메뉴 CRUD 동작', () => {
  test.beforeEach(async ({ page }) => {
    await loginAsLocal(page);
  });

  test('불출 처리 폼 → 사이트 레이아웃', async ({ page }) => {
    await page.goto('/bag/issue/create');
    await expect(page.locator('a:has-text("발주 입고 관리")')).toBeVisible();
    expect(await page.locator('a:has-text("회원 관리")').count()).toBe(0);
    await expect(page.locator('select[name="bi2_bag_code"]')).toBeVisible();
  });

  test('발주 등록 폼 → 사이트 레이아웃', async ({ page }) => {
    await page.goto('/bag/order/create');
    await expect(page.locator('a:has-text("불출 관리")')).toBeVisible();
    await expect(page.locator('input[name="bo_order_date"]')).toBeVisible();
  });

  test('입고 처리 폼 → 사이트 레이아웃', async ({ page }) => {
    await page.goto('/bag/receiving/create');
    await expect(page.locator('a:has-text("재고 관리")')).toBeVisible();
  });

  test('판매 등록 폼 → 사이트 레이아웃', async ({ page }) => {
    await page.goto('/bag/sale/create');
    await expect(page.locator('a:has-text("판매 현황")')).toBeVisible();
    await expect(page.locator('select[name="bs_ds_idx"]')).toBeVisible();
  });

  test('주문 접수 폼 → 사이트 레이아웃', async ({ page }) => {
    await page.goto('/bag/shop-order/create');
    await expect(page.locator('a:has-text("봉투 수불 관리")')).toBeVisible();
    await expect(page.locator('select[name="so_ds_idx"]')).toBeVisible();
  });

});

// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
// 엑셀 내보내기 다운로드
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
test.describe('엑셀 내보내기 다운로드', () => {
  test('지정판매소 엑셀', async ({ page }) => {
    await loginAsLocal(page);
    await page.goto('/bag/designated-shops/browse');
    const downloadPromise = page.waitForEvent('download', { timeout: 10000 });
    await page.locator('a[href*="designated-shops/export"]').first().click();
    const download = await downloadPromise;
    expect(download.suggestedFilename()).toContain('.csv');
  });

  test('판매 엑셀', async ({ page }) => {
    await loginAsLocal(page);
    await page.goto('/bag/bag-sales');
    const downloadPromise = page.waitForEvent('download', { timeout: 10000 });
    await page.locator('a[href*="export"]').first().click();
    const download = await downloadPromise;
    expect(download.suggestedFilename()).toContain('.csv');
  });
});
