import { Injectable } from '@nestjs/common';
import { Prisma } from '@prisma/client';
import { PrismaService } from '../../prisma/prisma.service';

export interface CompletitudTipoStatus {
  tipo_documento_id: string;
  codigo: string;
  nombre: string;
  es_obligatorio: boolean;
  admite_vencimiento: boolean;
  estado: 'PRESENTE' | 'FALTANTE' | 'VENCIDO';
  documento_id?: string;
  fecha_vencimiento?: Date | null;
}

export interface CompletitudReporte {
  empleado_id: string;
  tipos: CompletitudTipoStatus[];
  obligatorios_total: number;
  obligatorios_faltantes: number;
  obligatorios_vencidos: number;
  legajo_completo: boolean;
}

/**
 * Calcula la completitud del legajo de un funcionario:
 * cruza el catálogo de tipos activos (sistema + personalizados de la empresa)
 * contra los documentos ACTIVOS del empleado y devuelve un reporte por tipo.
 *
 * Lo usan:
 *  - GET /empleados/:id/completitud (UI del legajo)
 *  - Integración M14 (Desvinculación) — verificarBloquea()
 */
@Injectable()
export class LegajosCompletitudService {
  constructor(private readonly prisma: PrismaService) {}

  async generar(empresaId: string, empleadoId: string): Promise<CompletitudReporte> {
    const tipos = await this.prisma.rrhh_legajo_tipos_documento.findMany({
      where: {
        activo: true,
        OR: [{ empresa_id: null }, { empresa_id: empresaId }],
      },
      orderBy: [{ es_obligatorio: 'desc' }, { codigo: 'asc' }],
    });

    const documentosActivos = await this.prisma.rrhh_legajo_documentos.findMany({
      where: {
        empresa_id: empresaId,
        empleado_id: empleadoId,
        estado: 'ACTIVO',
      },
      orderBy: { subido_en: 'desc' },
    });

    // Indexa por tipo_documento_id quedándose con el más reciente.
    const docPorTipo = new Map<string, (typeof documentosActivos)[number]>();
    for (const doc of documentosActivos) {
      if (!docPorTipo.has(doc.tipo_documento_id)) {
        docPorTipo.set(doc.tipo_documento_id, doc);
      }
    }

    const tiposReporte: CompletitudTipoStatus[] = tipos.map((t) => {
      const doc = docPorTipo.get(t.id);
      let estado: CompletitudTipoStatus['estado'];
      if (!doc) estado = 'FALTANTE';
      else if (doc.estado_vencimiento === 'VENCIDO') estado = 'VENCIDO';
      else estado = 'PRESENTE';

      return {
        tipo_documento_id: t.id,
        codigo: t.codigo,
        nombre: t.nombre,
        es_obligatorio: t.es_obligatorio,
        admite_vencimiento: t.admite_vencimiento,
        estado,
        documento_id: doc?.id,
        fecha_vencimiento: doc?.fecha_vencimiento ?? null,
      };
    });

    const obligatorios = tiposReporte.filter((t) => t.es_obligatorio);
    const obligatoriosFaltantes = obligatorios.filter((t) => t.estado === 'FALTANTE');
    const obligatoriosVencidos = obligatorios.filter((t) => t.estado === 'VENCIDO');

    return {
      empleado_id: empleadoId,
      tipos: tiposReporte,
      obligatorios_total: obligatorios.length,
      obligatorios_faltantes: obligatoriosFaltantes.length,
      obligatorios_vencidos: obligatoriosVencidos.length,
      legajo_completo:
        obligatoriosFaltantes.length === 0 && obligatoriosVencidos.length === 0,
    };
  }

  /**
   * Verifica completitud para integración con M14 — Desvinculación.
   * Devuelve null si está completo; devuelve un detalle si tiene faltantes o vencidos.
   *
   * Quien decide bloquear es el caller (basado en el parámetro
   * `LEGAJO_COMPLETITUD_OBLIGATORIO_BLOQUEA`).
   */
  async verificarBloquea(empresaId: string, empleadoId: string) {
    const reporte = await this.generar(empresaId, empleadoId);
    if (reporte.legajo_completo) return null;

    const faltantes = reporte.tipos.filter(
      (t) => t.es_obligatorio && t.estado === 'FALTANTE',
    );
    const vencidos = reporte.tipos.filter(
      (t) => t.es_obligatorio && t.estado === 'VENCIDO',
    );

    return {
      empleado_id: empleadoId,
      faltantes: faltantes.map((t) => ({ codigo: t.codigo, nombre: t.nombre })),
      vencidos: vencidos.map((t) => ({
        codigo: t.codigo,
        nombre: t.nombre,
        fecha_vencimiento: t.fecha_vencimiento,
      })),
    };
  }
}
