import { drizzle } from "drizzle-orm/postgres-js";
import postgres from "postgres";
import * as schema from "./src/lib/schema";
import { CONTRATO, IPC_DATOS, ACUERDO_VERBAL, CALENDARIO_AJUSTES } from "./src/lib/contract";
import { calcularAjustesIpc, obtenerAlquilerEsperado, generarPeriodos } from "./src/lib/ipc";

const connectionString = process.env.DATABASE_URL;
if (!connectionString) {
  console.error("DATABASE_URL environment variable is required");
  process.exit(1);
}

const client = postgres(connectionString);
const db = drizzle(client, { schema });

async function seed() {
  console.log("Seeding database...");

  // Clear existing data (order matters for potential FK constraints)
  await db.delete(schema.gastosServicios);
  await db.delete(schema.servicios);
  await db.delete(schema.historialCambios);
  await db.delete(schema.pagos);
  await db.delete(schema.cuotasEsperadas);
  await db.delete(schema.ajustesIpc);
  await db.delete(schema.indicesIpc);
  await db.delete(schema.contratos);

  // 1. Insert contract
  await db.insert(schema.contratos).values({
    direccion: CONTRATO.direccion,
    locadora: CONTRATO.locadora,
    locatarios: JSON.stringify(CONTRATO.locatarios),
    fechaInicio: CONTRATO.fechaInicio,
    fechaFin: CONTRATO.fechaFin,
    montoBaseInicial: CONTRATO.montoBaseInicial,
    diaVencimiento: CONTRATO.diaVencimiento,
    penalDiario: CONTRATO.penalDiario,
    calendarioAjustes: CALENDARIO_AJUSTES.map(c => ({ fechaAjuste: c.fechaAjuste, mesIndiceInicio: c.mesIndiceInicio, mesIndiceFin: c.mesIndiceFin })),
  });

  // 2. Insert IPC data
  const sortedMonths = Object.keys(IPC_DATOS).sort();
  for (let i = 0; i < sortedMonths.length; i++) {
    const key = sortedMonths[i];
    const [anio, mes] = key.split("-").map(Number);
    const valor = IPC_DATOS[key];
    let variacionMensual: number | null = null;
    if (i > 0) {
      const prevValor = IPC_DATOS[sortedMonths[i - 1]];
      variacionMensual = ((valor / prevValor) - 1) * 100;
    }
    await db.insert(schema.indicesIpc).values({
      anio,
      mes,
      valor,
      variacionMensual,
      fuente: "INDEC",
    });
  }

  // 3. Calculate and insert IPC adjustments
  const ajustes = calcularAjustesIpc(IPC_DATOS, [...CALENDARIO_AJUSTES], CONTRATO.montoBaseInicial);
  for (const ajuste of ajustes) {
    await db.insert(schema.ajustesIpc).values({
      contratoId: 1,
      fechaAjuste: ajuste.fechaAjuste + "-01",
      mesIndiceInicio: ajuste.mesIndiceInicio,
      mesIndiceFin: ajuste.mesIndiceFin,
      indiceInicio: ajuste.indiceInicio,
      indiceFin: ajuste.indiceFin,
      coeficiente: ajuste.coeficiente,
      montoAnterior: ajuste.montoAnterior,
      montoNuevo: ajuste.montoNuevo,
    });
  }

  // 4. Generate expected payments and assumed actual payments
  const periodos = generarPeriodos("2026-03", CONTRATO.fechaInicio);
  for (const periodo of periodos) {
    const [anio, mes] = periodo.split("-").map(Number);
    const diaVenc = Math.min(CONTRATO.diaVencimiento, new Date(anio, mes, 0).getDate());
    const fechaVencimiento = `${periodo}-${String(diaVenc).padStart(2, "0")}`;
    const montoEsperadoIpc = obtenerAlquilerEsperado(periodo, ajustes, CONTRATO.montoBaseInicial);
    const montoAcordado = periodo >= ACUERDO_VERBAL.desdePeriodo ? ACUERDO_VERBAL.montoAcordado : null;

    await db.insert(schema.cuotasEsperadas).values({
      contratoId: 1,
      periodo,
      montoEsperadoIpc,
      montoAcordado,
      fechaVencimiento,
    });

    if (periodo !== "2026-03") {
      const [anio, mes] = periodo.split("-").map(Number);
      const ultimoDia = new Date(anio, mes, 0).getDate();
      const fechaPagoReal = `${periodo}-${String(ultimoDia).padStart(2, "0")}`;

      await db.insert(schema.pagos).values({
        contratoId: 1,
        periodo,
        fechaPago: fechaPagoReal,
        monto: CONTRATO.montoBaseInicial,
        notas: "Pago asumido (monto base sin ajuste IPC)",
        creadoPor: "seed",
      });
    }
  }

  // 5. Create servicios
  const serviciosData = [
    { nombre: "ABL", porcentaje: 45, color: "#dc2626" },
    { nombre: "AYSA", porcentaje: 45, color: "#2563eb" },
    { nombre: "Edenor", porcentaje: 45, color: "#f59e0b" },
  ];

  for (const svc of serviciosData) {
    await db.insert(schema.servicios).values(svc);
  }

  // 7. Create sample gastos_servicios entries
  const servicioIds = [1, 2, 3]; // ABL, AYSA, Edenor
  const sampleServicios = [
    { nombre: "ABL", entries: [
      { periodo: "2025-03", montoFacturado: 85000, montoPagado: 38250 },
      { periodo: "2025-04", montoFacturado: 88200, montoPagado: 39690 },
      { periodo: "2025-05", montoFacturado: 91500, montoPagado: 41175 },
      { periodo: "2025-06", montoFacturado: 94800, montoPagado: 42660 },
      { periodo: "2025-07", montoFacturado: 98200, montoPagado: 44190 },
      { periodo: "2025-08", montoFacturado: 101500, montoPagado: 45675 },
      { periodo: "2025-09", montoFacturado: 105200, montoPagado: 47340 },
      { periodo: "2025-10", montoFacturado: 108900, montoPagado: 49005 },
      { periodo: "2025-11", montoFacturado: 112800, montoPagado: 50760 },
      { periodo: "2025-12", montoFacturado: 116500, montoPagado: 52425 },
      { periodo: "2026-01", montoFacturado: 120200, montoPagado: 54090 },
      { periodo: "2026-02", montoFacturado: 124500, montoPagado: 56025 },
      { periodo: "2026-03", montoFacturado: 128200, montoPagado: 0 },
    ]},
    { nombre: "AYSA", entries: [
      { periodo: "2025-03", montoFacturado: 45000, montoPagado: 20250 },
      { periodo: "2025-04", montoFacturado: 46800, montoPagado: 21060 },
      { periodo: "2025-05", montoFacturado: 48500, montoPagado: 21825 },
      { periodo: "2025-06", montoFacturado: 50200, montoPagado: 22590 },
      { periodo: "2025-07", montoFacturado: 52000, montoPagado: 23400 },
      { periodo: "2025-08", montoFacturado: 53800, montoPagado: 24210 },
      { periodo: "2025-09", montoFacturado: 55600, montoPagado: 25020 },
      { periodo: "2025-10", montoFacturado: 57500, montoPagado: 25875 },
      { periodo: "2025-11", montoFacturado: 59400, montoPagado: 26730 },
      { periodo: "2025-12", montoFacturado: 61200, montoPagado: 27540 },
      { periodo: "2026-01", montoFacturado: 63000, montoPagado: 28350 },
      { periodo: "2026-02", montoFacturado: 65000, montoPagado: 29250 },
      { periodo: "2026-03", montoFacturado: 67000, montoPagado: 0 },
    ]},
    { nombre: "Edenor", entries: [
      { periodo: "2025-03", montoFacturado: 120000, montoPagado: 54000 },
      { periodo: "2025-04", montoFacturado: 125000, montoPagado: 56250 },
      { periodo: "2025-05", montoFacturado: 130000, montoPagado: 58500 },
      { periodo: "2025-06", montoFacturado: 135000, montoPagado: 60750 },
      { periodo: "2025-07", montoFacturado: 140000, montoPagado: 63000 },
      { periodo: "2025-08", montoFacturado: 145000, montoPagado: 65250 },
      { periodo: "2025-09", montoFacturado: 150000, montoPagado: 67500 },
      { periodo: "2025-10", montoFacturado: 155000, montoPagado: 69750 },
      { periodo: "2025-11", montoFacturado: 160000, montoPagado: 72000 },
      { periodo: "2025-12", montoFacturado: 165000, montoPagado: 74250 },
      { periodo: "2026-01", montoFacturado: 170000, montoPagado: 76500 },
      { periodo: "2026-02", montoFacturado: 175000, montoPagado: 78750 },
      { periodo: "2026-03", montoFacturado: 180000, montoPagado: 0 },
    ]},
  ];

  for (let i = 0; i < sampleServicios.length; i++) {
    for (const entry of sampleServicios[i].entries) {
      const [anio, mes] = entry.periodo.split("-").map(Number);
      const ultimoDia = new Date(anio, mes, 0).getDate();
      const fechaPago = entry.montoPagado > 0 ? `${entry.periodo}-${String(ultimoDia).padStart(2, "0")}` : null;

      await db.insert(schema.gastosServicios).values({
        servicioId: i + 1,
        periodo: entry.periodo,
        montoFacturado: entry.montoFacturado,
        montoPagado: entry.montoPagado,
        fechaPago,
        notas: entry.montoPagado === 0 ? "Impago" : null,
      });
    }
  }

  console.log("Seed complete!");
  console.log(`  - 1 contrato`);
  console.log(`  - ${sortedMonths.length} índices IPC`);
  console.log(`  - ${ajustes.length} ajustes IPC`);
  console.log(`  - ${periodos.length} cuotas esperadas`);
  console.log(`  - ${periodos.length - 1} pagos asumidos (Mar 2026 impago)`);
  console.log(`  - ${serviciosData.length} servicios`);
  console.log(`  - ${sampleServicios.reduce((sum, s) => sum + s.entries.length, 0)} gastos de servicios`);

  console.log("\n=== RESUMEN DE AJUSTES ===");
  for (const a of ajustes) {
    console.log(`  ${a.fechaAjuste}: $${a.montoAnterior.toLocaleString()} → $${a.montoNuevo.toLocaleString()} (+${a.variacionPct.toFixed(2)}%)`);
  }
  console.log(`\n  Alquiler actual por IPC: $${ajustes[ajustes.length - 1]?.montoNuevo.toLocaleString()}`);
  console.log(`  Acuerdo verbal: $${ACUERDO_VERBAL.montoAcordado.toLocaleString()}`);

  await client.end();
}

seed().catch(console.error);
