import * as fs from "fs";
import * as path from "path";
import { DataSource } from "typeorm";
import { CredentialsCryptoService } from "../src/control-plane/credentials-crypto.service";
import { TallerParametro } from "../src/taller-parametros/entities/taller-parametro.entity";

// Siembra la config de WhatsApp de ESTE sitio (TENANT_CLI_DB_* -- el mismo
// tenant que migration:run:prod usa, ver typeorm.config.ts) desde las
// variables WHATSAPP_* actuales, una sola vez. Se corre en CADA despliegue
// (ver deploy.sh) porque es idempotente: no-op si ya existe la fila de
// whatsapp_phone_number_id (no pisa un valor ya editado desde la pantalla
// nueva) o si el sitio no tiene WHATSAPP_* configuradas.
//
// SUPUESTO, no garantia permanente: "un tenant por sitio" -- cierto hoy
// (typeorm.config.ts: "CLI config para migraciones de UN tenant a la vez"),
// pero RUNBOOK-DEPLOY.md:463-468 ya advierte que ese modelo no escala mas
// alla de un punado de tenants. El dia que un sitio sirva 2+ tenants
// activos, esto solo alcanza al que apunte TENANT_CLI_DB_DATABASE -- por eso
// loguea host+base destino en los tres casos (no-op, siembra, error), nunca
// credenciales.
function loadRootEnv(): void {
  const envPath = path.join(__dirname, "..", "..", ".env");
  if (!fs.existsSync(envPath)) return;
  for (const line of fs.readFileSync(envPath, "utf8").split(/\r?\n/)) {
    const m = line.match(/^([A-Z0-9_]+)=(.*)$/);
    if (m && !process.env[m[1]]) process.env[m[1]] = m[2];
  }
}

// Leidos a nivel de modulo (no dentro de seed()) para que el .catch() de
// seed() de mas abajo -- que corre FUERA del scope de la funcion -- tambien
// pueda loguear host+base destino en el caso de error, no solo en los casos
// de no-op y siembra. Sin esto, un fallo de conexion o de llave de cifrado
// en un sitio queda indistinguible en el log de un fallo en cualquier otro
// sitio (este script corre en CADA despliegue, en muchos sitios de un
// tenant cada uno).
loadRootEnv();
const host = process.env.TENANT_CLI_DB_HOST;
const database = process.env.TENANT_CLI_DB_DATABASE;

function buildCryptoService(): CredentialsCryptoService {
  const fakeConfigService = { get: (key: string) => process.env[key] };
  const crypto = new CredentialsCryptoService(fakeConfigService as any);
  crypto.onModuleInit();
  return crypto;
}

function buildTenantDataSource(): DataSource {
  return new DataSource({
    type: "mysql",
    host: process.env.TENANT_CLI_DB_HOST,
    port: parseInt(process.env.TENANT_CLI_DB_PORT || "3306", 10),
    username: process.env.TENANT_CLI_DB_USERNAME,
    password: process.env.TENANT_CLI_DB_PASSWORD,
    database: process.env.TENANT_CLI_DB_DATABASE,
    entities: [TallerParametro],
    synchronize: false,
  });
}

const CAMPOS: Array<{ clave: string; env: string; sensible: boolean; default?: string }> = [
  { clave: "notificaciones.whatsapp_phone_number_id", env: "WHATSAPP_PHONE_NUMBER_ID", sensible: false },
  { clave: "notificaciones.whatsapp_access_token", env: "WHATSAPP_ACCESS_TOKEN", sensible: true },
  { clave: "notificaciones.whatsapp_api_version", env: "WHATSAPP_API_VERSION", sensible: false, default: "v25.0" },
  {
    clave: "notificaciones.whatsapp_default_country_code",
    env: "WHATSAPP_DEFAULT_COUNTRY_CODE",
    sensible: false,
    default: "502",
  },
  { clave: "notificaciones.whatsapp_template_cotizacion", env: "WHATSAPP_TEMPLATE_COTIZACION", sensible: false },
  { clave: "notificaciones.whatsapp_template_estado", env: "WHATSAPP_TEMPLATE_ESTADO", sensible: false },
  {
    clave: "notificaciones.whatsapp_template_language",
    env: "WHATSAPP_TEMPLATE_LANGUAGE",
    sensible: false,
    default: "es_GT",
  },
];

async function seed(): Promise<void> {
  if (!process.env.WHATSAPP_ACCESS_TOKEN || !process.env.WHATSAPP_PHONE_NUMBER_ID) {
    console.log(`[seed-whatsapp-desde-env] ${host}/${database}: sin WHATSAPP_* en el entorno, no-op.`);
    return;
  }

  const crypto = buildCryptoService();
  const ds = buildTenantDataSource();
  await ds.initialize();

  try {
    const repo = ds.getRepository(TallerParametro);
    const yaExiste = await repo.findOne({
      where: { clave: "notificaciones.whatsapp_phone_number_id", tiendaId: 0, destino: "" },
    });
    if (yaExiste) {
      console.log(`[seed-whatsapp-desde-env] ${host}/${database}: ya tiene config de WhatsApp, no-op.`);
      return;
    }

    for (const campo of CAMPOS) {
      const valor = process.env[campo.env] ?? campo.default ?? "";
      if (!valor) continue;
      await repo.save(
        repo.create({
          clave: campo.clave,
          ambito: "tenant",
          tiendaId: 0,
          destino: "",
          tipoDato: "string",
          valor: campo.sensible ? null : valor,
          valorCifrado: campo.sensible ? crypto.encrypt(valor) : null,
        }),
      );
    }

    // El toggle en si: si este sitio tenia WHATSAPP_* funcionando, el
    // comportamiento equivalente post-migracion es usa_whatsapp=true --
    // "los clientes que ya operan se comportan igual" (spec, criterio de
    // listo).
    await repo.save(
      repo.create({
        clave: "notificaciones.usa_whatsapp",
        ambito: "tenant",
        tiendaId: 0,
        destino: "",
        tipoDato: "boolean",
        valor: "true",
        valorCifrado: null,
      }),
    );

    console.log(`[seed-whatsapp-desde-env] ${host}/${database}: sembrado desde variables de entorno.`);
  } finally {
    await ds.destroy();
  }
}

seed().catch((e) => {
  console.error(`[seed-whatsapp-desde-env] ${host}/${database}: error: ${e?.message ?? e}`);
  process.exit(1);
});
