/**
 * Tests de la sección "Análisis de Impacto" del GlobalSettingsPanel.
 *
 * Los mocks usan vi.hoisted() para que currentProcess sea una referencia
 * estable entre renders (evita el loop infinito del useEffect de sync).
 */

import { describe, it, expect, vi, beforeEach } from 'vitest'
import { render, screen, fireEvent, act } from '@testing-library/react'
import { TooltipProvider } from '@/components/ui/tooltip'

// ─── Mocks con referencia estable ─────────────────────────────────────────────

const processStoreMock = vi.hoisted(() => ({
  currentProcess: {
    id: 'p1', name: 'Proceso test', clientName: 'Cliente A',
    bpmnXml: '<def/>', currency: 'USD', overheadPercentage: 0.2,
    annualFrequency: 1000, analysisHorizonYears: 3, automationInvestment: 0,
    createdAt: 0, updatedAt: 0,
  },
  updateProcess: vi.fn(),
  subscribe: vi.fn(),
}))

vi.mock('@/store/process-store', () => ({
  useProcessStore: () => processStoreMock,
}))

vi.mock('@/store/simulation-store', () => ({
  useSimulationStore: () => ({
    resultActual: null,
    resultAutomated: null,
    invalidateResults: vi.fn(),
  }),
}))

vi.mock('@/auth/AuthContext', () => ({
  useAuth: () => ({ user: { id: 'test-user-id' } }),
}))

import { GlobalSettingsPanel } from '@/features/workspace/GlobalSettingsPanel'

// ─── Helper ───────────────────────────────────────────────────────────────────

function renderPanel() {
  return render(
    <TooltipProvider>
      <GlobalSettingsPanel />
    </TooltipProvider>
  )
}

// ─── Tests ────────────────────────────────────────────────────────────────────

beforeEach(() => {
  processStoreMock.updateProcess.mockReset()
  processStoreMock.updateProcess.mockResolvedValue(undefined)
  // Restaurar defaults del proceso
  processStoreMock.currentProcess.annualFrequency = 1000
  processStoreMock.currentProcess.analysisHorizonYears = 3
  processStoreMock.currentProcess.automationInvestment = 0
})

describe('GlobalSettingsPanel — sección Análisis de Impacto', () => {
  it('renderiza los 3 campos de impacto con sus labels correctos', () => {
    renderPanel()
    expect(screen.getByLabelText(/Frecuencia anual/i)).toBeInTheDocument()
    expect(screen.getByText(/Horizonte de análisis/i)).toBeInTheDocument()
    expect(screen.getByLabelText(/Inversión en automatización/i)).toBeInTheDocument()
  })

  it('frecuencia anual muestra el default 1000 del proceso', () => {
    renderPanel()
    const freqInput = screen.getByLabelText(/Frecuencia anual/i) as HTMLInputElement
    expect(freqInput.value).toBe('1000')
  })

  it('editar frecuencia y guardar incluye el nuevo valor en updateProcess', async () => {
    renderPanel()
    const freqInput = screen.getByLabelText(/Frecuencia anual/i)

    await act(async () => {
      fireEvent.change(freqInput, { target: { value: '5000' } })
    })

    // Después de cambiar, el botón debería mostrar "Guardar configuración"
    const guardarBtn = await screen.findByRole('button', { name: /Guardar/i })
    await act(async () => { fireEvent.click(guardarBtn) })

    expect(processStoreMock.updateProcess).toHaveBeenCalledOnce()
    const calledWith = processStoreMock.updateProcess.mock.calls[0][0]
    expect(calledWith.annualFrequency).toBe(5000)
  })

  it('horizonte de análisis se muestra en texto (default 3 años)', () => {
    renderPanel()
    expect(screen.getByText('3 años')).toBeInTheDocument()
  })

  it('guardar incluye horizonte actual en updateProcess', async () => {
    renderPanel()
    const freqInput = screen.getByLabelText(/Frecuencia anual/i)

    await act(async () => {
      fireEvent.change(freqInput, { target: { value: '1200' } })
    })

    const guardarBtn = await screen.findByRole('button', { name: /Guardar/i })
    await act(async () => { fireEvent.click(guardarBtn) })

    const calledWith = processStoreMock.updateProcess.mock.calls[0][0]
    expect(calledWith.analysisHorizonYears).toBe(3)
    expect(calledWith.analysisHorizonYears).toBeGreaterThanOrEqual(1)
    expect(calledWith.analysisHorizonYears).toBeLessThanOrEqual(10)
  })

  it('editar inversión en automatización y guardar la incluye correctamente', async () => {
    renderPanel()
    const investInput = screen.getByLabelText(/Inversión en automatización/i)

    await act(async () => {
      fireEvent.change(investInput, { target: { value: '75000' } })
    })

    const guardarBtn = await screen.findByRole('button', { name: /Guardar/i })
    await act(async () => { fireEvent.click(guardarBtn) })

    const calledWith = processStoreMock.updateProcess.mock.calls[0][0]
    expect(calledWith.automationInvestment).toBe(75000)
  })

  it('sección "ANÁLISIS DE IMPACTO" aparece con su label de sección', () => {
    renderPanel()
    expect(screen.getByText(/Análisis de Impacto/i)).toBeInTheDocument()
  })
})
