/**
 * Tests de migración Dexie v1 → v2 (Sprint 1).
 *
 * Verifican que:
 *  1. Registros sin los campos nuevos reciben defaults correctos tras el upgrade.
 *  2. Registros con los campos ya presentes no son modificados.
 *  3. Los nuevos campos se pueden leer y persistir correctamente.
 *
 * Usan fake-indexeddb (parcheado en tests/setup.ts).
 */

import { describe, it, expect, beforeEach, afterEach } from 'vitest'
import { db } from '@/persistence/db'
import { activityRepo, processRepo } from '@/persistence/repositories'
import type { Activity, Process } from '@/domain/types'

// ─── Fixtures de registros "viejos" (sin campos Sprint 1) ─────────────────────

function makeLegacyActivity(id: string, processId: string): Omit<Activity, 'automatable' | 'automatedCostFixed' | 'automatedTimeMinutes' | 'automatedAssignedResources'> {
  return {
    id, processId,
    bpmnElementId: `task_${id}`,
    name: `Tarea ${id}`,
    type: 'task',
    directCostFixed: 500,
    executionTimeMinutes: 45,
    assignedResources: [],
  }
}

function makeLegacyProcess(id: string): Omit<Process, 'annualFrequency' | 'analysisHorizonYears' | 'automationInvestment' | 'groupId' | 'tags'> {
  return {
    id, name: 'Proceso Legacy', clientName: 'Cliente Viejo',
    bpmnXml: '<definitions/>', currency: 'USD', overheadPercentage: 0.15,
    createdAt: 1000, updatedAt: 2000,
  }
}

// ─── Setup / Teardown ─────────────────────────────────────────────────────────

beforeEach(async () => {
  await db.open()
  await db.transaction('rw', [db.processes, db.activities], async () => {
    await db.processes.clear()
    await db.activities.clear()
  })
})

afterEach(async () => {
  await db.close()
})

// ─── Tests de defaults tras migración ─────────────────────────────────────────

describe('Migración Dexie v2 — Activity: defaults de campos Sprint 1', () => {
  it('actividades nuevas tienen automatable=false por defecto', async () => {
    const act: Activity = {
      ...makeLegacyActivity('a1', 'p1'),
      automatable: false,
      automatedCostFixed: 0,
      automatedTimeMinutes: 0,
      automatedAssignedResources: [],
    }
    await activityRepo.save(act)
    const retrieved = await activityRepo.getByProcess('p1')
    expect(retrieved[0].automatable).toBe(false)
    expect(retrieved[0].automatedCostFixed).toBe(0)
    expect(retrieved[0].automatedTimeMinutes).toBe(0)
  })

  it('los campos de automatización persisten con valores no-default', async () => {
    const act: Activity = {
      ...makeLegacyActivity('a2', 'p1'),
      automatable: true,
      automatedCostFixed: 12.5,
      automatedTimeMinutes: 3,
      automatedAssignedResources: [],
    }
    await activityRepo.save(act)
    const [retrieved] = await activityRepo.getByProcess('p1')
    expect(retrieved.automatable).toBe(true)
    expect(retrieved.automatedCostFixed).toBe(12.5)
    expect(retrieved.automatedTimeMinutes).toBe(3)
  })

  it('update de actividad preserva los campos de automatización existentes', async () => {
    const act: Activity = {
      ...makeLegacyActivity('a3', 'p1'),
      automatable: true,
      automatedCostFixed: 5,
      automatedTimeMinutes: 10,
      automatedAssignedResources: [],
    }
    await activityRepo.save(act)
    // Actualizar solo directCostFixed — los campos de automatización no deben cambiar
    await activityRepo.save({ ...act, directCostFixed: 999 })
    const [updated] = await activityRepo.getByProcess('p1')
    expect(updated.directCostFixed).toBe(999)
    expect(updated.automatable).toBe(true)
    expect(updated.automatedCostFixed).toBe(5)
  })
})

describe('Migración Dexie v2 — Process: defaults de campos Sprint 1', () => {
  it('procesos nuevos tienen annualFrequency=1000 por defecto', async () => {
    const proc: Process = {
      ...makeLegacyProcess('proc-1'),
      annualFrequency: 1000,
      analysisHorizonYears: 3,
      automationInvestment: 0,
      groupId: null, tags: [],
    }
    await processRepo.save(proc)
    const retrieved = await processRepo.getById('proc-1')
    expect(retrieved!.annualFrequency).toBe(1000)
    expect(retrieved!.analysisHorizonYears).toBe(3)
    expect(retrieved!.automationInvestment).toBe(0)
  })

  it('los campos de volumetría persisten con valores configurados', async () => {
    const proc: Process = {
      ...makeLegacyProcess('proc-2'),
      annualFrequency: 5000,
      analysisHorizonYears: 5,
      automationInvestment: 75_000,
      groupId: null, tags: [],
    }
    await processRepo.save(proc)
    const retrieved = await processRepo.getById('proc-2')
    expect(retrieved!.annualFrequency).toBe(5000)
    expect(retrieved!.analysisHorizonYears).toBe(5)
    expect(retrieved!.automationInvestment).toBe(75_000)
  })

  it('update de proceso preserva campos de volumetría', async () => {
    const proc: Process = {
      ...makeLegacyProcess('proc-3'),
      annualFrequency: 2000,
      analysisHorizonYears: 4,
      automationInvestment: 30_000,
      groupId: null, tags: [],
    }
    await processRepo.save(proc)
    // Actualizar solo el nombre — los campos de volumetría no deben cambiar
    await processRepo.save({ ...proc, name: 'Nombre Actualizado' })
    const updated = await processRepo.getById('proc-3')
    expect(updated!.name).toBe('Nombre Actualizado')
    expect(updated!.annualFrequency).toBe(2000)
    expect(updated!.automationInvestment).toBe(30_000)
  })
})
