/**
 * Tests de orientación de páginas PDF — Etapa 5 Sprint 1.5.
 *
 * Verifica que:
 * - PDF Actual/Automatizado: portrait → landscape → portrait
 * - PDF ROI: todas portrait (no tiene página BPMN)
 * - addPage se llama con el argumento correcto en cada caso
 *
 * Nota: estos tests usan mocks de jsPDF y verifican las llamadas a addPage.
 * La orientación real del PDF se valida en los tests E2E (etapa-5-pdfs.spec.ts).
 */
import { describe, it, expect, vi, beforeEach } from 'vitest'

// ─── Mock de jsPDF ─────────────────────────────────────────────────────────────

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(3),
    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'

const mockProcess: Process = {
  id: 'p1', name: 'Test Process',
  clientName: 'Test Client',
  bpmnXml: '', currency: 'USD',
  overheadPercentage: 0.2,
  annualFrequency: 1000, analysisHorizonYears: 3, automationInvestment: 50000,
  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: 1200, totalDirectCost: 1000, totalIndirectCost: 200,
    totalTimeMinutes: 90,
    perActivity: [{
      activityId: 'a1', bpmnElementId: 'task1', activityName: 'Tarea 1',
      expectedDirectCost: 1200, expectedIndirectCost: 200, expectedTotalCost: 1200,
      percentOfTotal: 100, executionProbability: 1.0, expectedExecutions: 1.0,
      executionTimeMinutes: 30, resourceCostBreakdown: [],
    }],
    perResource: [], warnings: [],
  },
  resultAutomated: {
    totalCost: 300, totalDirectCost: 250, totalIndirectCost: 50,
    totalTimeMinutes: 20,
    perActivity: [{
      activityId: 'a1', bpmnElementId: 'task1', activityName: 'Tarea 1',
      expectedDirectCost: 300, expectedIndirectCost: 50, expectedTotalCost: 300,
      percentOfTotal: 100, executionProbability: 1.0, expectedExecutions: 1.0,
      executionTimeMinutes: 10, resourceCostBreakdown: [],
    }],
    perResource: [], warnings: [],
  },
}

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

describe('PDF orientation — Etapa 5', () => {
  beforeEach(() => {
    vi.clearAllMocks()
    // Simular que getWidth/getHeight devuelven 210×297 por defecto (portrait)
    // En landscape, jsPDF realmente cambia los valores internamente
    mockDoc.internal.pageSize.getWidth.mockReturnValue(210)
    mockDoc.internal.pageSize.getHeight.mockReturnValue(297)
  })

  describe('PDF Actual/Automatizado — mezcla portrait-landscape-portrait-portrait', () => {
    it('llama addPage exactamente 3 veces para 4 páginas', async () => {
      const { exportToPdf } = await import('@/lib/export/pdf-export')
      await exportToPdf({
        process: mockProcess,
        simulation: mockSimulation,
        resources: [],
        heatmapImageData: null,
        tab: 'actual',
      })
      expect(mockDoc.addPage).toHaveBeenCalledTimes(3)
    })

    it('primera addPage usa landscape (página BPMN)', async () => {
      const { exportToPdf } = await import('@/lib/export/pdf-export')
      await exportToPdf({
        process: mockProcess,
        simulation: mockSimulation,
        resources: [],
        heatmapImageData: null,
        tab: 'actual',
      })
      const firstCall = mockDoc.addPage.mock.calls[0]
      expect(firstCall[0]).toBe('a4')
      expect(firstCall[1]).toBe('landscape')
    })

    it('segunda addPage usa portrait (análisis + tabla)', async () => {
      const { exportToPdf } = await import('@/lib/export/pdf-export')
      await exportToPdf({
        process: mockProcess,
        simulation: mockSimulation,
        resources: [],
        heatmapImageData: null,
        tab: 'actual',
      })
      const secondCall = mockDoc.addPage.mock.calls[1]
      expect(secondCall[0]).toBe('a4')
      expect(secondCall[1]).toBe('portrait')
    })

    it('tercera addPage usa portrait (nota metodológica)', async () => {
      const { exportToPdf } = await import('@/lib/export/pdf-export')
      await exportToPdf({
        process: mockProcess,
        simulation: mockSimulation,
        resources: [],
        heatmapImageData: null,
        tab: 'actual',
      })
      const thirdCall = mockDoc.addPage.mock.calls[2]
      expect(thirdCall[0]).toBe('a4')
      expect(thirdCall[1]).toBe('portrait')
    })

    it('tab automatizado también usa landscape en página 2', async () => {
      const { exportToPdf } = await import('@/lib/export/pdf-export')
      await exportToPdf({
        process: mockProcess,
        simulation: mockSimulation,
        resources: [],
        heatmapImageData: null,
        tab: 'automatizado',
      })
      const firstCall = mockDoc.addPage.mock.calls[0]
      expect(firstCall[1]).toBe('landscape')
    })
  })

  describe('PDF ROI — todas portrait', () => {
    it('llama addPage 4 veces para 5 páginas (todas sin landscape)', async () => {
      mockDoc.internal.getNumberOfPages.mockReturnValue(5)
      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)
      // Ninguna llamada debe usar landscape
      const hasLandscape = mockDoc.addPage.mock.calls.some(
        (c: unknown[]) => c[1] === 'landscape'
      )
      expect(hasLandscape).toBe(false)
    })
  })

  describe('drawHeatmapImage — dimensiones dinámicas', () => {
    it('usa getWidth() del doc, no constante hardcodeada', async () => {
      const { drawHeatmapImage } = await import('@/lib/export/pdf-sections')
      // Simular página landscape (297mm wide)
      mockDoc.internal.pageSize.getWidth.mockReturnValue(297)
      mockDoc.internal.pageSize.getHeight.mockReturnValue(210)

      const fakeDataUrl = 'data:image/jpeg;base64,/9j/test'
      drawHeatmapImage(mockDoc as any, fakeDataUrl, 40)

      expect(mockDoc.internal.pageSize.getWidth).toHaveBeenCalled()
      // La imagen debe ser más ancha que en portrait (170mm)
      const imgCallArgs = mockDoc.addImage.mock.calls[0]
      // args: [dataUrl, format, x, y, width, height]
      const imgWidth = imgCallArgs[4]
      expect(imgWidth).toBeGreaterThan(170) // más ancho que portrait (297 - 40 = 257mm)
    })
  })
})
