/**
 * Feature Documentation: Merge Focus
 *
 * When the user clicks "Resolve Conflicts", the command is sent to the agent
 * and the terminal automatically switches to the Agent tab and focuses it.
 * This ensures the user can immediately see the agent working on the conflicts,
 * even if they were previously on a different terminal tab.
 *
 * Run with: pnpm test:feature-docs merge-focus
 */
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.setTimeout(60000)

/** Navigate the explorer panel to the source-control tab */
async function openSourceControl(p: Page) {
  const explorerButton = p.locator('[data-panel-id="explorer-toggle"], [title*="Explorer"]').first()
  if (await explorerButton.isVisible()) {
    const cls = await explorerButton.getAttribute('class').catch(() => '')
    if (!cls?.includes('bg-accent')) {
      await explorerButton.click()
      await expect(explorerButton).toHaveClass(/bg-accent/, { timeout: 2000 }).catch(() => {})
    }
  }

  await p.evaluate(() => {
    const store = (window as Record<string, unknown>).__sessionStore as {
      getState: () => { activeSessionId: string; setExplorerFilter: (id: string, filter: string) => void }
    }
    if (!store) return
    const state = store.getState()
    state.setExplorerFilter(state.activeSessionId, 'source-control')
  })
  // Wait for the source control view to render
  const scView = p.locator('text=Source Control, text=Merge in progress').first()
  await scView.waitFor({ state: 'visible', timeout: 3000 }).catch(() => {})
}

test.beforeAll(async () => {
  await fs.promises.mkdir(SCREENSHOTS, { recursive: true })
  const result = await resetApp({ scenario: 'marketing', mockMerge: 'conflicts' })
  page = result.page
})

test.afterAll(async () => {
  await generateFeaturePage(
    {
      title: 'Merge Focus',
      description:
        'When the user clicks "Resolve Conflicts" during a merge, the app sends the command to the agent terminal ' +
        'and automatically switches to the Agent tab and focuses it. This means even if the user was on a different ' +
        'terminal tab (e.g. a user shell), they are brought straight to the agent to watch it resolve the conflicts.',
      steps,
    },
    FEATURE_DIR,
  )
  await generateIndex(FEATURES_ROOT)
})

test.describe.serial('Feature: Merge Focus', () => {
  test('Step 1: Merge conflicts detected with Resolve Conflicts button', async () => {
    await openSourceControl(page)

    const mergeBanner = page.locator('text=Merge in progress')
    await expect(mergeBanner).toBeVisible({ timeout: 5000 })

    const resolveBtn = page.locator('button:has-text("Resolve Conflicts")')
    await expect(resolveBtn).toBeVisible()
    await expect(resolveBtn).toBeEnabled()

    const explorer = page.locator('[data-panel-id="explorer"]')
    await screenshotElement(page, explorer, path.join(SCREENSHOTS, '01-merge-conflicts.png'), {
      maxHeight: 600,
    })
    steps.push({
      screenshotPath: 'screenshots/01-merge-conflicts.png',
      caption: 'Merge conflicts detected',
      description:
        'The source control panel shows a "Merge in progress" banner with an orange "Resolve Conflicts" button. ' +
        'The user is currently viewing the explorer and may be on any terminal tab.',
    })
  })

  test('Step 2: Switch to a user terminal tab', async () => {
    // Add a user terminal tab and switch to it
    const addTabBtn = page.locator('button[title="New terminal tab"]:visible')
    await addTabBtn.click()

    // Wait for the new tab to appear and be active
    const userTab = page.locator('[data-tab-type="user"]').first()
    await expect(userTab).toBeVisible({ timeout: 2000 }).catch(() => {})

    // Verify we're on the new tab (not Agent)
    const terminalArea = page.locator('[data-panel-id="terminal"]')
    await screenshotElement(page, terminalArea, path.join(SCREENSHOTS, '02-user-tab.png'), {
      maxHeight: 400,
    })
    steps.push({
      screenshotPath: 'screenshots/02-user-tab.png',
      caption: 'User switches to a different terminal tab',
      description:
        'The user has opened a second terminal tab and is viewing it. ' +
        'The Agent tab is in the background. Previously, clicking "Resolve Conflicts" from here ' +
        'would send the command to the agent but leave the user staring at the wrong tab.',
    })
  })

  test('Step 3: Click Resolve Conflicts — focus moves to Agent tab', async () => {
    // Click Resolve Conflicts
    const resolveBtn = page.locator('button:has-text("Resolve Conflicts")')
    await resolveBtn.click()

    // Wait for the resolving state to appear
    const resolvingText = page.locator('text=Resolving Conflicts...')
    await expect(resolvingText).toBeVisible({ timeout: 3000 })

    // Verify the Agent tab is now active
    const agentTabActive = await page.evaluate(() => {
      const store = (window as Record<string, unknown>).__sessionStore as {
        getState: () => {
          sessions: { id: string; terminalTabs: { activeTabId: string | null } }[]
          activeSessionId: string
        }
      }
      if (!store) return null
      const state = store.getState()
      const session = state.sessions.find(s => s.id === state.activeSessionId)
      return session?.terminalTabs.activeTabId
    })

    // Agent tab ID is '__agent__' or null (null defaults to agent)
    expect(agentTabActive === '__agent__' || agentTabActive === null).toBeTruthy()

    // Verify the agent terminal's xterm textarea has input focus
    const hasFocus = await page.evaluate(() => {
      const container = document.querySelector('[data-panel-id="terminal"]')
      if (!container) return false
      const textarea = container.querySelector('.xterm-helper-textarea')
      return textarea === document.activeElement
    })
    expect(hasFocus).toBe(true)

    // Screenshot the terminal area showing the Agent tab is active
    const terminalArea = page.locator('[data-panel-id="terminal"]')
    await screenshotElement(page, terminalArea, path.join(SCREENSHOTS, '03-agent-focused.png'), {
      maxHeight: 400,
    })
    steps.push({
      screenshotPath: 'screenshots/03-agent-focused.png',
      caption: 'Agent tab is automatically focused',
      description:
        'After clicking "Resolve Conflicts", the app switches to the Agent terminal tab and focuses it. ' +
        'The user can immediately see the agent working on resolving the merge conflicts. ' +
        'The button in the explorer now shows "Resolving Conflicts..." to indicate the request was sent.',
    })
  })

  test('Step 4: Explorer shows agent was asked to resolve', async () => {
    const explorer = page.locator('[data-panel-id="explorer"]')
    await screenshotElement(page, explorer, path.join(SCREENSHOTS, '04-resolving-state.png'), {
      maxHeight: 600,
    })
    steps.push({
      screenshotPath: 'screenshots/04-resolving-state.png',
      caption: 'Explorer confirms the agent is resolving conflicts',
      description:
        'The source control panel now shows "Resolving Conflicts..." (disabled) and a message ' +
        'telling the user to wait for the agent to finish before committing the merge.',
    })
  })
})
