/**
 * Tests para la página 1 rediseñada del PDF ROI — Etapa 6 Sprint 1.5.
 *
 * Verifica:
 * - drawRoiPage1 invoca los bloques clave (hero, top3, grid, banner)
 * - exportToPdf ROI llama addPage 4 veces (5 páginas)
 * - Ninguna página ROI usa landscape
 * - El hero llama setFontSize(28) para la cifra principal
 */
import { describe, it, expect, vi, beforeEach } from 'vitest'

const mockDoc = {
  setProperties: vi.fn(),
  setFont: vi.fn(),
  setFontSize: vi.fn(),
  setTextColor: vi.fn(),
  setFillColor: vi.fn(),
  setDrawColor: vi.fn(),
  setLineWidth: vi.fn(),
  text: vi.fn(),
  rect: vi.fn(),
  roundedRect: vi.fn(),
  line: vi.fn(),
  addImage: vi.fn(),
  addPage: vi.fn(),
  setPage: vi.fn(),
  save: vi.fn(),
  splitTextToSize: vi.fn().mockImplementation((t: string) => [t]),
  lastAutoTable: { finalY: 150 },
  internal: {
    getNumberOfPages: vi.fn().mockReturnValue(5),
    pageSize: {
      getWidth: vi.fn().mockReturnValue(210),
      getHeight: vi.fn().mockReturnValue(297),
    },
  },
}

vi.mock('jspdf', () => {
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  function MockJsPDF(this: any) { return mockDoc }
  return { jsPDF: MockJsPDF }
})

vi.mock('jspdf-autotable', () => ({
  default: vi.fn(),
}))

import type { Process, Simulation } from '@/domain/types'
import type { RoiResult } from '@/domain/roi'

const mockProcess: Process = {
  id: 'p1', name: 'Test Process',
  clientName: 'Test Client',
  bpmnXml: '', currency: 'USD',
  overheadPercentage: 0.2,
  annualFrequency: 5000, analysisHorizonYears: 3, automationInvestment: 80000,
  createdAt: 0, updatedAt: 0,
  groupId: null, tags: [],
}

const mockSimulation: Simulation = {
  id: 'sim1', processId: 'p1',
  executedAt: new Date('2026-05-17T10:00:00Z').getTime(),
  result: {
    totalCost: 600, totalDirectCost: 500, totalIndirectCost: 100,
    totalTimeMinutes: 90,
    perActivity: [
      {
        activityId: 'a1', bpmnElementId: 'task1', activityName: 'Tarea Alpha',
        expectedDirectCost: 400, expectedIndirectCost: 80, expectedTotalCost: 400,
        percentOfTotal: 66, executionProbability: 1.0, expectedExecutions: 1.0,
        executionTimeMinutes: 30, resourceCostBreakdown: [],
      },
      {
        activityId: 'a2', bpmnElementId: 'task2', activityName: 'Tarea Beta',
        expectedDirectCost: 200, expectedIndirectCost: 40, expectedTotalCost: 200,
        percentOfTotal: 34, executionProbability: 1.0, expectedExecutions: 1.0,
        executionTimeMinutes: 20, resourceCostBreakdown: [],
      },
    ],
    perResource: [], warnings: [],
  },
  resultAutomated: {
    totalCost: 60, totalDirectCost: 50, totalIndirectCost: 10,
    totalTimeMinutes: 10,
    perActivity: [
      {
        activityId: 'a1', bpmnElementId: 'task1', activityName: 'Tarea Alpha',
        expectedDirectCost: 40, expectedIndirectCost: 10, expectedTotalCost: 40,
        percentOfTotal: 66, executionProbability: 1.0, expectedExecutions: 1.0,
        executionTimeMinutes: 5, resourceCostBreakdown: [],
      },
      {
        activityId: 'a2', bpmnElementId: 'task2', activityName: 'Tarea Beta',
        expectedDirectCost: 20, expectedIndirectCost: 5, expectedTotalCost: 20,
        percentOfTotal: 34, executionProbability: 1.0, expectedExecutions: 1.0,
        executionTimeMinutes: 5, resourceCostBreakdown: [],
      },
    ],
    perResource: [], warnings: [],
  },
}

const mockRoi: RoiResult = {
  savingsPerExecution: 540,
  savingsPerExecutionPercent: 90,
  annualSavings: 2_700_000,
  paybackMonths: 0.36,
  paybackYears: 0.03,
  cumulativeSavingsHorizon: 8_020_000,
  breaksEvenInHorizon: true,
  roiAnnualPercent: 3375,
}

describe('PDF ROI — Página 1 rediseñada (Etapa 6)', () => {
  beforeEach(() => {
    vi.clearAllMocks()
    mockDoc.internal.pageSize.getWidth.mockReturnValue(210)
    mockDoc.internal.pageSize.getHeight.mockReturnValue(297)
    mockDoc.internal.getNumberOfPages.mockReturnValue(5)
  })

  it('drawRoiPage1 completa sin errores y llama text() múltiples veces', async () => {
    const { drawRoiPage1 } = await import('@/lib/export/pdf-sections-roi')
    expect(() =>
      drawRoiPage1(
        mockDoc as any,
        mockProcess,
        mockRoi,
        mockSimulation.executedAt,
        mockSimulation.result.perActivity,
        mockSimulation.resultAutomated!.perActivity,
        'USD'
      )
    ).not.toThrow()
    expect(mockDoc.text.mock.calls.length).toBeGreaterThan(5)
  })

  it('drawRoiPage1 incluye texto "InQ ROI" en el header denso', async () => {
    const { drawRoiPage1 } = await import('@/lib/export/pdf-sections-roi')
    drawRoiPage1(
      mockDoc as any,
      mockProcess,
      mockRoi,
      mockSimulation.executedAt,
      mockSimulation.result.perActivity,
      mockSimulation.resultAutomated!.perActivity,
      'USD'
    )
    const textCalls = mockDoc.text.mock.calls.map((c: unknown[]) => c[0])
    expect(textCalls).toContain('InQ ROI')
  })

  it('drawRoiPage1 incluye texto "TOP 3 ACTIVIDADES POR AHORRO"', async () => {
    const { drawRoiPage1 } = await import('@/lib/export/pdf-sections-roi')
    drawRoiPage1(
      mockDoc as any,
      mockProcess,
      mockRoi,
      mockSimulation.executedAt,
      mockSimulation.result.perActivity,
      mockSimulation.resultAutomated!.perActivity,
      'USD'
    )
    const textCalls = mockDoc.text.mock.calls.map((c: unknown[]) => c[0])
    expect(textCalls).toContain('TOP 3 ACTIVIDADES POR AHORRO')
  })

  it('drawRoiPage1 usa setFontSize(26) para la cifra del KPI Hero (Etapa 11: bajada de 28→26pt)', async () => {
    const { drawRoiPage1 } = await import('@/lib/export/pdf-sections-roi')
    drawRoiPage1(
      mockDoc as any,
      mockProcess,
      mockRoi,
      mockSimulation.executedAt,
      mockSimulation.result.perActivity,
      mockSimulation.resultAutomated!.perActivity,
      'USD'
    )
    const fontSizes = mockDoc.setFontSize.mock.calls.map((c: number[]) => c[0])
    expect(fontSizes).toContain(26)
  })

  it('drawRoiPage1 dibuja rectángulos para la grilla 2x2 y barras top3', async () => {
    const { drawRoiPage1 } = await import('@/lib/export/pdf-sections-roi')
    drawRoiPage1(
      mockDoc as any,
      mockProcess,
      mockRoi,
      mockSimulation.executedAt,
      mockSimulation.result.perActivity,
      mockSimulation.resultAutomated!.perActivity,
      'USD'
    )
    // roundedRect para cards de KPI secundarios (4 cards) + metadata strip
    expect(mockDoc.roundedRect).toHaveBeenCalled()
    // rect para elementos del banner y barras top3
    expect(mockDoc.rect).toHaveBeenCalled()
  })

  it('exportToPdf ROI: 4 addPage calls (5 páginas) sin landscape', async () => {
    const { exportToPdf } = await import('@/lib/export/pdf-export')
    await exportToPdf({
      process: mockProcess,
      simulation: mockSimulation,
      resources: [],
      heatmapImageData: null,
      tab: 'roi',
      activities: [],
    })
    expect(mockDoc.addPage).toHaveBeenCalledTimes(4)
    const hasLandscape = mockDoc.addPage.mock.calls.some(
      (c: unknown[]) => c[1] === 'landscape'
    )
    expect(hasLandscape).toBe(false)
  })

  it('drawRoiPage1 dibuja nombre de actividad del top3 para actividades con ahorro', async () => {
    const { drawRoiPage1 } = await import('@/lib/export/pdf-sections-roi')
    drawRoiPage1(
      mockDoc as any,
      mockProcess,
      mockRoi,
      mockSimulation.executedAt,
      mockSimulation.result.perActivity,
      mockSimulation.resultAutomated!.perActivity,
      'USD'
    )
    const textCalls = mockDoc.text.mock.calls.map((c: unknown[]) => c[0])
    expect(textCalls).toContain('Tarea Alpha')
  })
})
