import { test, expect } from '@playwright/test'
import { loginAsOperator } from './helpers/auth.js'
import {
  getPaymentSessionTimeout,
  setPaymentSessionTimeout,
  getExtensionDefaultAction,
  setExtensionDefaultAction,
} from './helpers/backend-api.js'

/**
 * Settings page e2e tests.
 *
 * These tests exercise two of the four Phase 3.7 config rows end-to-end:
 *   - payment_session_timeout_minutes (number input)
 *   - extension_default_action_on_timeout (radio)
 *
 * Strategy:
 *   1. Snapshot the current backend value before each test
 *   2. Mutate via the UI
 *   3. Reload to confirm persistence (rules out optimistic-only state)
 *   4. Restore the original value in afterEach (so the suite is rerunnable)
 */

test.describe('Settings page — Phase 3.7 config rows', () => {
  test.beforeEach(async ({ page }) => {
    await loginAsOperator(page)
    await page.goto('/settings')
    await expect(page.getByRole('heading', { name: 'Settings', level: 1 })).toBeVisible()
  })

  // -------------------------------------------------------------------------
  // payment_session_timeout_minutes
  // -------------------------------------------------------------------------
  test.describe('Batas Waktu Sesi Pembayaran', () => {
    let originalValue

    test.beforeEach(async () => {
      originalValue = await getPaymentSessionTimeout()
    })

    test.afterEach(async () => {
      if (typeof originalValue === 'number') {
        await setPaymentSessionTimeout(originalValue)
      }
    })

    test('changing 20 → 25 persists across reload', async ({ page }) => {
      await setPaymentSessionTimeout(20)

      const section = page
        .locator('section', { has: page.getByRole('heading', { name: 'Batas Waktu Sesi Pembayaran' }) })
      const input = section.getByRole('spinbutton')

      await page.reload()
      await expect(input).toHaveValue('20')

      // Mutate via the UI. The component fires a mutation on every keystroke
      // (no Save button), so .fill() with the final value is enough.
      // Wait for the PATCH to complete BEFORE reloading — disabled flip alone
      // is racy because fill() returns before React processes the onChange.
      const patchResponse = page.waitForResponse(r =>
        r.url().includes('/internal/config/payment-session-timeout')
        && r.request().method() === 'PATCH'
        && r.status() === 200
      )
      await input.fill('25')
      await patchResponse

      // Reload and confirm the new value sticks.
      await page.reload()
      await expect(input).toHaveValue('25')

      // And confirm the backend agrees.
      const persisted = await getPaymentSessionTimeout()
      expect(persisted).toBe(25)
    })
  })

  // -------------------------------------------------------------------------
  // extension_default_action_on_timeout (radio)
  // -------------------------------------------------------------------------
  test.describe('Aksi Default Extension', () => {
    let originalValue

    test.beforeEach(async () => {
      originalValue = await getExtensionDefaultAction()
    })

    test.afterEach(async () => {
      if (originalValue) {
        await setExtensionDefaultAction(originalValue)
      }
    })

    test('flipping auto-approve <-> auto-reject persists across reload', async ({ page }) => {
      // Start from a known state.
      await setExtensionDefaultAction('auto_approve')

      const section = page
        .locator('section', { has: page.getByRole('heading', { name: 'Aksi Default jika Bestie Tidak Menjawab Extension' }) })
      const approveRadio = section.getByRole('radio', { name: /Otomatis disetujui/ })
      const rejectRadio = section.getByRole('radio', { name: /Otomatis ditolak/ })

      await page.reload()
      await expect(approveRadio).toBeChecked()
      await expect(rejectRadio).not.toBeChecked()

      // Flip to auto-reject. Use click() instead of check() — check() races against
      // the React re-render that flips `checked` after the mutation roundtrip.
      // Wait for the PATCH to complete before asserting persistence.
      const patchToReject = page.waitForResponse(r =>
        r.url().includes('/internal/config/extension-default-action')
        && r.request().method() === 'PATCH'
        && r.status() === 200
      )
      await rejectRadio.click()
      await patchToReject

      await page.reload()
      await expect(rejectRadio).toBeChecked()
      await expect(approveRadio).not.toBeChecked()
      expect(await getExtensionDefaultAction()).toBe('auto_reject')

      // Flip back to auto-approve.
      const patchToApprove = page.waitForResponse(r =>
        r.url().includes('/internal/config/extension-default-action')
        && r.request().method() === 'PATCH'
        && r.status() === 200
      )
      await approveRadio.click()
      await patchToApprove

      await page.reload()
      await expect(approveRadio).toBeChecked()
      expect(await getExtensionDefaultAction()).toBe('auto_approve')
    })
  })
})
