/**
 * Feature Documentation: Shell Selection
 *
 * Demonstrates the shell selection feature in Settings, and reproduces
 * a bug where the dropdown resets to the system default after closing
 * and reopening Settings.
 *
 * Run with: pnpm test:feature-docs shell-selection
 */
import { test, expect, resetApp } from '../_shared/electron-fixture'
import type { Page } from '@playwright/test'
import path from 'path'
import fs from 'fs'
import { fileURLToPath } from 'url'
import { screenshotElement } from '../_shared/screenshot-helpers'
import { generateFeaturePage, generateIndex, FeatureStep } from '../_shared/template'

const __filename = fileURLToPath(import.meta.url)
const __dirname = path.dirname(__filename)

const FEATURE_DIR = __dirname
const SCREENSHOTS = path.join(FEATURE_DIR, 'screenshots')
const FEATURES_ROOT = path.join(__dirname, '..')

let page: Page
const steps: FeatureStep[] = []


test.beforeAll(async () => {
  await fs.promises.mkdir(SCREENSHOTS, { recursive: true })

  ;({ page } = await resetApp())
})

test.afterAll(async () => {
  await generateFeaturePage(
    {
      title: 'Shell Selection',
      description:
        'Users can choose which shell is used for terminal sessions via the Settings panel. ' +
        'This is especially useful on Windows where users may prefer Git Bash over PowerShell. ' +
        'This walkthrough also documents a bug where the dropdown resets to the system default ' +
        'after closing and reopening settings.',
      steps,
    },
    FEATURE_DIR,
  )
  await generateIndex(FEATURES_ROOT)

})

/** Helper to open settings panel */
async function openSettings() {
  const settingsButton = page.locator('button[title^="Settings"]')
  await settingsButton.click()
  await page.waitForSelector('[data-panel-id="settings"]', { state: 'visible', timeout: 5000 })
  // Wait for shells to load (the async listShells call)
  await page.waitForSelector('[data-panel-id="settings"] select', { timeout: 5000 })
}

/** Helper to close settings panel */
async function closeSettings() {
  const settingsButton = page.locator('button[title^="Settings"]')
  await settingsButton.click()
  await page.waitForSelector('[data-panel-id="settings"]', { state: 'hidden', timeout: 5000 })
}

test.describe.serial('Feature: Shell Selection', () => {
  test('Step 1: Open settings — shell dropdown shows system default', async () => {
    await openSettings()

    const settingsPanel = page.locator('[data-panel-id="settings"]')
    const shellSelect = settingsPanel.locator('select')
    await expect(shellSelect).toBeVisible()

    // Verify the dropdown exists and shows the default shell
    const selectedValue = await shellSelect.inputValue()
    const options = await shellSelect.locator('option').allTextContents()
    expect(options.length).toBeGreaterThan(1)

    await screenshotElement(page, settingsPanel, path.join(SCREENSHOTS, '01-initial-settings.png'), {
      maxHeight: 500,
    })
    steps.push({
      screenshotPath: 'screenshots/01-initial-settings.png',
      caption: 'Settings panel with Terminal Shell dropdown showing system default',
      description:
        `The shell dropdown is visible with ${options.length} options. ` +
        `The currently selected shell is "${selectedValue}".`,
    })
  })

  test('Step 2: Change shell to Bash', async () => {
    const settingsPanel = page.locator('[data-panel-id="settings"]')
    const shellSelect = settingsPanel.locator('select')

    // Select Bash
    await shellSelect.selectOption('/bin/bash')

    // Wait for the select to reflect the new value
    await expect(shellSelect).toHaveValue('/bin/bash')

    await screenshotElement(page, settingsPanel, path.join(SCREENSHOTS, '02-changed-to-bash.png'), {
      maxHeight: 500,
    })
    steps.push({
      screenshotPath: 'screenshots/02-changed-to-bash.png',
      caption: 'Shell changed to Bash',
      description:
        'After selecting Bash from the dropdown, the value is now "/bin/bash". ' +
        'The store has been updated and a debounced save has been scheduled.',
    })
  })

  test('Step 3: Close settings and wait', async () => {
    await closeSettings()

    // Wait for the debounced save to have had time to fire by confirming the
    // settings panel is fully hidden, then allowing the 500ms debounce to flush.
    await expect(page.locator('[data-panel-id="settings"]')).not.toBeVisible()
    // The save debounce is 500ms — wait long enough for it to fire.
    // No observable UI change to wait for here, so a timeout is appropriate.
    // eslint-disable-next-line no-restricted-syntax
    await page.waitForTimeout(1000)

    steps.push({
      screenshotPath: 'screenshots/02-changed-to-bash.png', // reuse previous screenshot
      caption: 'Settings closed, waiting for save to complete',
      description:
        'Settings panel is closed. We wait for the debounced save to complete.',
    })
  })

  test('Step 4: Reopen settings — BUG: dropdown shows system default instead of Bash', async () => {
    await openSettings()

    const settingsPanel = page.locator('[data-panel-id="settings"]')
    const shellSelect = settingsPanel.locator('select')
    await expect(shellSelect).toBeVisible()

    const selectedValue = await shellSelect.inputValue()

    await screenshotElement(page, settingsPanel, path.join(SCREENSHOTS, '03-reopened-bug.png'), {
      maxHeight: 500,
    })
    steps.push({
      screenshotPath: 'screenshots/03-reopened-bug.png',
      caption: `BUG: After reopening, dropdown shows "${selectedValue}" instead of "/bin/bash"`,
      description:
        'After closing and reopening settings, the shell dropdown has reverted to showing ' +
        'the system default shell instead of the user\'s chosen "/bin/bash". ' +
        'The root cause: loadRepos() re-reads config on mount, and the select value expression ' +
        'falls back to availableShells.find((s) => s.isDefault) when defaultShell is empty.',
    })

    await closeSettings()
  })
})
