import { createHash } from 'crypto';
import type { PrismaService } from '../../prisma/prisma.service';

export interface LegajosFotoMigrationResult {
  empresa_id: string;
  empleados_con_foto: number;
  creados: number;
  omitidos: number;
  errores: Array<{ empleado_id: string; motivo: string }>;
}

function extensionFromUrl(url: string): string {
  const clean = (url || '').split('?')[0].split('#')[0];
  const ext = clean.includes('.') ? clean.slice(clean.lastIndexOf('.') + 1).toLowerCase() : '';
  if (['jpg', 'jpeg', 'png', 'webp', 'gif', 'bmp'].includes(ext)) return ext;
  return 'jpg';
}

function mimeFromExtension(ext: string): string {
  if (ext === 'png') return 'image/png';
  if (ext === 'webp') return 'image/webp';
  if (ext === 'gif') return 'image/gif';
  if (ext === 'bmp') return 'image/bmp';
  return 'image/jpeg';
}

/**
 * Migra `rrhh_empleados.foto_url` al legajo digital como documento tipo FOTO_PERFIL.
 *
 * Reglas:
 * - Idempotente: si el empleado ya tiene un FOTO_PERFIL ACTIVO, se omite.
 * - No re-sube el binario: guarda la URL original en nombre_storage por compatibilidad.
 * - No modifica `foto_url`: se mantiene como espejo para módulos legacy.
 */
export async function seedLegajosFotoMigration(
  prisma: PrismaService,
  empresaId: string,
  actorUserId: string,
): Promise<LegajosFotoMigrationResult> {
  const result: LegajosFotoMigrationResult = {
    empresa_id: empresaId,
    empleados_con_foto: 0,
    creados: 0,
    omitidos: 0,
    errores: [],
  };

  const tipo = await prisma.rrhh_legajo_tipos_documento.findFirst({
    where: {
      codigo: 'FOTO_PERFIL',
      activo: true,
      OR: [{ empresa_id: null }, { empresa_id: empresaId }],
    },
    orderBy: { empresa_id: 'desc' },
    select: { id: true, codigo: true },
  });

  if (!tipo) {
    throw new Error('No se encontró el tipo FOTO_PERFIL. Ejecutá primero migraciones/seed de legajos.');
  }

  const empleados = await prisma.rrhh_empleados.findMany({
    where: {
      empresa_id: empresaId,
      foto_url: { not: null },
      NOT: [{ foto_url: '' }],
    },
    select: {
      id: true,
      numero_empleado: true,
      foto_url: true,
    },
  });

  result.empleados_con_foto = empleados.length;

  for (const emp of empleados) {
    try {
      const fotoUrl = String(emp.foto_url || '').trim();
      if (!fotoUrl) {
        result.omitidos++;
        continue;
      }

      const existenteActivo = await prisma.rrhh_legajo_documentos.findFirst({
        where: {
          empresa_id: empresaId,
          empleado_id: emp.id,
          tipo_documento_id: tipo.id,
          estado: 'ACTIVO',
        },
        select: { id: true },
      });

      if (existenteActivo) {
        result.omitidos++;
        continue;
      }

      const lastVersion = await prisma.rrhh_legajo_documentos.findFirst({
        where: {
          empresa_id: empresaId,
          empleado_id: emp.id,
          tipo_documento_id: tipo.id,
        },
        orderBy: [{ version: 'desc' }, { subido_en: 'desc' }],
        select: { id: true, version: true },
      });

      const ext = extensionFromUrl(fotoUrl);
      const mime = mimeFromExtension(ext);
      const hash = createHash('sha256').update(`foto_url:${fotoUrl}`).digest('hex');
      const nombre = `foto_perfil_${emp.numero_empleado || emp.id.slice(0, 8)}.${ext}`;

      await prisma.rrhh_legajo_documentos.create({
        data: {
          empresa_id: empresaId,
          empleado_id: emp.id,
          tipo_documento_id: tipo.id,
          nombre_original: nombre,
          nombre_storage: fotoUrl,
          mime_type: mime,
          extension: ext,
          tamanio_bytes: BigInt(0),
          hash_sha256: hash,
          fecha_documento: null,
          fecha_vencimiento: null,
          estado_vencimiento: 'SIN_VENCIMIENTO',
          descripcion: 'Migración automática desde rrhh_empleados.foto_url',
          version: (lastVersion?.version || 0) + 1,
          documento_previo_id: lastVersion?.id || null,
          estado: 'ACTIVO',
          subido_por: actorUserId,
          subido_en: new Date(),
        },
      });

      result.creados++;
    } catch (err) {
      result.errores.push({
        empleado_id: emp.id,
        motivo: err instanceof Error ? err.message : String(err),
      });
    }
  }

  return result;
}
