import { describe, expect, test } from 'claude-code/testing'

// Udawany git: gałąź main, dwa zmienione pliki
function udawanyGit(on: any) {
  on('process.run', ($: any, e: any) => {
    const polecenie = JSON.stringify(e)
    if (polecenie.includes('--show-current')) return { value: { stdout: 'main\n', stderr: '', exitCode: 0 } }
    return { value: { stdout: ' M app.py\n?? notatki.md\n', stderr: '', exitCode: 0 } }
  })
}

describe('register', () => {
  test('git push na main bez odpowiedzi nie idzie', async ($, on) => {
    udawanyGit(on)
    on('session.start', ($: any, e: any) => ({ cwd: e.cwd }))
    on('tool.call', () => ({ result: 'wypchnięte' }))
    await $.session.start({ surface: 'terminal', isInteractive: true, cwd: '/work' } as any)
    const r: any = await $.tool.call({ tool: 'Bash', command: 'git push origin main' } as any)
    expect(r.deny).toContain('odmówił')
  })

  test('inne polecenia przechodzą bez pytania', async ($, on) => {
    udawanyGit(on)
    on('session.start', ($: any, e: any) => ({ cwd: e.cwd }))
    on('tool.call', () => ({ result: 'ok' }))
    await $.session.start({ surface: 'terminal', isInteractive: true, cwd: '/work' } as any)
    const r: any = await $.tool.call({ tool: 'Bash', command: 'ls' } as any)
    expect(r.result).toBe('ok')
  })

  test('pasek pokazuje gałąź i liczbę zmienionych plików', async ($, on) => {
    udawanyGit(on)
    on('session.start', ($: any, e: any) => ({ cwd: e.cwd }))
    await $.session.start({ surface: 'terminal', isInteractive: true, cwd: '/work' } as any)
    const ui = await $.ui.mount({
      plugin: 'git-pasek', surface: 'terminal', component: 'AbovePrompt',
      props: { hasSurvey: false, isWorking: false, maxRows: 10, bodyColumns: 120 },
    } as any)
    expect(await ui.find({ type: 'Text', text: /main/ })).toBeDefined()
    expect(await ui.find({ type: 'Text', text: /^2$/ })).toBeDefined()
    await ui.unmount()
  })
})

// Od Claude Code 2.1.295: przycisk z dziećmi i powiadomienie systemowe
describe('push na main: gałąź sprawdzana tuż przed pushem', () => {
  test('przełączenie na main w tej samej turze: i tak pyta', async ($, on) => {
    let galaz = 'feature'
    on('process.run', ($: any, e: any) => {
      const polecenie = JSON.stringify(e)
      if (polecenie.includes('--show-current')) return { value: { stdout: galaz + '\n', stderr: '', exitCode: 0 } }
      return { value: { stdout: '', stderr: '', exitCode: 0 } }
    })
    on('session.start', ($: any, e: any) => ({ cwd: e.cwd }))
    on('tool.call', () => ({ result: 'wypchnięte' }))
    await $.session.start({ surface: 'terminal', isInteractive: true, cwd: '/work' } as any)
    galaz = 'main'
    const r: any = await $.tool.call({ tool: 'Bash', command: 'git push' } as any)
    expect(r.deny).toContain('odmówił')
  })

  test('push na main z innej gałęzi: też pyta', async ($, on) => {
    on('process.run', ($: any, e: any) => {
      const polecenie = JSON.stringify(e)
      if (polecenie.includes('--show-current')) return { value: { stdout: 'feature\n', stderr: '', exitCode: 0 } }
      return { value: { stdout: '', stderr: '', exitCode: 0 } }
    })
    on('session.start', ($: any, e: any) => ({ cwd: e.cwd }))
    on('tool.call', () => ({ result: 'wypchnięte' }))
    await $.session.start({ surface: 'terminal', isInteractive: true, cwd: '/work' } as any)
    const r: any = await $.tool.call({ tool: 'Bash', command: 'git push origin HEAD:main' } as any)
    expect(r.deny).toContain('odmówił')
  })

  test('push --all z innej gałęzi: też pyta', async ($, on) => {
    on('process.run', ($: any, e: any) => {
      const polecenie = JSON.stringify(e)
      if (polecenie.includes('--show-current')) return { value: { stdout: 'feature\n', stderr: '', exitCode: 0 } }
      return { value: { stdout: '', stderr: '', exitCode: 0 } }
    })
    on('session.start', ($: any, e: any) => ({ cwd: e.cwd }))
    on('tool.call', () => ({ result: 'wypchnięte' }))
    await $.session.start({ surface: 'terminal', isInteractive: true, cwd: '/work' } as any)
    const r: any = await $.tool.call({ tool: 'Bash', command: 'git push --all origin' } as any)
    expect(r.deny).toContain('odmówił')
  })

  test('pełny refspec refs/heads/main: też pyta', async ($, on) => {
    on('process.run', ($: any, e: any) => {
      const polecenie = JSON.stringify(e)
      if (polecenie.includes('--show-current')) return { value: { stdout: 'feature\n', stderr: '', exitCode: 0 } }
      return { value: { stdout: '', stderr: '', exitCode: 0 } }
    })
    on('session.start', ($: any, e: any) => ({ cwd: e.cwd }))
    on('tool.call', () => ({ result: 'wypchnięte' }))
    await $.session.start({ surface: 'terminal', isInteractive: true, cwd: '/work' } as any)
    const r: any = await $.tool.call({ tool: 'Bash', command: 'git push origin HEAD:refs/heads/main' } as any)
    expect(r.deny).toContain('odmówił')
  })
})

describe('nowości 2.1.295', () => {
  test('kliknięcie paska pokazuje zmienione pliki', async ($, on) => {
    udawanyGit(on)
    const dymki: string[] = []
    on('ui.toast', ($: any, e: any) => { dymki.push(e.text); return { value: undefined } })
    on('session.start', ($: any, e: any) => ({ cwd: e.cwd }))
    await $.session.start({ surface: 'terminal', isInteractive: true, cwd: '/work' } as any)
    const ui = await $.ui.mount({
      plugin: 'git-pasek', surface: 'terminal', component: 'AbovePrompt',
      props: { hasSurvey: false, isWorking: false, maxRows: 10, bodyColumns: 120 },
    } as any)
    await ui.press({ key: 'git-pasek' } as any)
    expect(dymki.join(' ')).toContain('app.py')
    expect(dymki.join(' ')).toContain('notatki.md')
    await ui.unmount()
  })

  test('długa tura: powiadomienie z gałęzią i liczbą zmian', async ($, on) => {
    udawanyGit(on)
    const powiadomienia: any[] = []
    on('ui.notify', ($: any, e: any) => { powiadomienia.push(e); return { value: { isSent: true, channel: 'iterm2' } } })
    on('session.start', ($: any, e: any) => ({ cwd: e.cwd }))
    on('turn.complete', () => ({ text: '' }))
    await $.session.start({ surface: 'terminal', isInteractive: true, cwd: '/work' } as any)
    await $.turn.complete({ answer: 'ok', durationMs: 45_000, isAborted: false, turnId: 't1', reason: 'answer' } as any)
    expect(powiadomienia.length).toBe(1)
    expect(powiadomienia[0].text).toContain('main')
    expect(powiadomienia[0].text).toContain('zmienione: 2')
  })

  test('krótka tura: bez powiadomienia', async ($, on) => {
    udawanyGit(on)
    const powiadomienia: any[] = []
    on('ui.notify', ($: any, e: any) => { powiadomienia.push(e); return { value: { isSent: true, channel: 'iterm2' } } })
    on('session.start', ($: any, e: any) => ({ cwd: e.cwd }))
    on('turn.complete', () => ({ text: '' }))
    await $.session.start({ surface: 'terminal', isInteractive: true, cwd: '/work' } as any)
    await $.turn.complete({ answer: 'ok', durationMs: 5_000, isAborted: false, turnId: 't2', reason: 'answer' } as any)
    expect(powiadomienia.length).toBe(0)
  })
})
