import { Injectable, NotFoundException } from '@nestjs/common';
import { PrismaService } from '../../prisma/prisma.service';
import { CarteraConfigService } from '../config/cartera-config.service';
import { ErpNovasisFuente } from '../fuentes/erp-novasis-fuente.service';
import { CarteraImportadaFuente } from '../fuentes/cartera-importada-fuente.service';

/**
 * Detalle unificado de cliente: info básica + cuentas pendientes + timeline
 * de gestiones. Dispatch transparente según `fuente_default`.
 */
@Injectable()
export class ClientesCarteraService {
  constructor(
    private readonly prisma: PrismaService,
    private readonly configService: CarteraConfigService,
    private readonly erpNovasisFuente: ErpNovasisFuente,
    private readonly carteraImportadaFuente: CarteraImportadaFuente,
  ) {}

  async detalle(empresa_id: string, clienteId: string) {
    const config = await this.configService.getOrCreate(empresa_id);
    if (config.fuente_default === 'cartera-importada') {
      return this.detalleImportada(empresa_id, clienteId);
    }
    return this.detalleErp(empresa_id, clienteId);
  }

  // ─── ERP Novasis ─────────────────────────────────────────────────────────
  private async detalleErp(empresa_id: string, clienteId: string) {
    const cliente = await this.prisma.clientes.findUnique({
      where: { id: clienteId },
      include: { personas: true },
    });
    if (!cliente) throw new NotFoundException('Cliente no encontrado');

    const tieneFactura = await this.prisma.factura_cab.count({
      where: { cliente_id: clienteId, empresa_id },
    });
    if (tieneFactura === 0) {
      throw new NotFoundException('Cliente sin movimientos en esta empresa');
    }

    const cuentas = await this.erpNovasisFuente.listarCuentasPendientes({
      empresa_id,
      cliente_id: clienteId,
      page: 1,
      page_size: 100,
    });

    const gestiones = await this.prisma.cob_gestion.findMany({
      where: { empresa_id, cliente_id: clienteId, anulada: false },
      orderBy: { fecha: 'desc' },
      take: 100,
      select: {
        id: true,
        fecha: true,
        tipo_gestion: true,
        resultado: true,
        observacion: true,
        proxima_accion: true,
        proxima_fecha: true,
        factura_cab_id: true,
        usuario_id: true,
      },
    });

    return {
      cliente: {
        id: cliente.id,
        nombre: cliente.nombre_fantasia ?? cliente.personas?.razon_social ?? '',
        documento: cliente.personas?.ruc ?? cliente.personas?.nro_documento ?? null,
        telefono: cliente.personas?.telefono ?? null,
        email: cliente.personas?.email ?? null,
        fuente: 'erp-novasis' as const,
      },
      cuentas,
      gestiones: gestiones.map((g) => ({
        ...g,
        cuenta_id: g.factura_cab_id,
      })),
      totales: {
        cuentas_pendientes: cuentas.length,
        saldo_total: cuentas.reduce((sum, c) => sum + c.saldo_pendiente, 0),
        gestiones_total: gestiones.length,
      },
    };
  }

  // ─── Cartera importada ───────────────────────────────────────────────────
  private async detalleImportada(empresa_id: string, clienteExternoId: string) {
    const docs = await this.prisma.cartera_importada_documentos.findMany({
      where: { empresa_id, cliente_externo_id: clienteExternoId, active: true },
      orderBy: { fecha_vencimiento: 'asc' },
      take: 100,
    });
    if (docs.length === 0) throw new NotFoundException('Cliente no encontrado en cartera importada');

    const muestra = docs[0];
    const cuentas = await this.carteraImportadaFuente.listarCuentasPendientes({
      empresa_id,
      cliente_id: clienteExternoId,
      page: 1,
      page_size: 100,
    });

    const gestiones = await this.prisma.cob_gestion_cartera.findMany({
      where: { empresa_id, cliente_externo_id: clienteExternoId, anulada: false },
      orderBy: { fecha: 'desc' },
      take: 100,
      select: {
        id: true,
        fecha: true,
        tipo_gestion: true,
        resultado: true,
        observacion: true,
        proxima_accion: true,
        proxima_fecha: true,
        cartera_importada_documento_id: true,
        usuario_id: true,
      },
    });

    return {
      cliente: {
        id: clienteExternoId,
        nombre: muestra.cliente_nombre,
        documento: muestra.cliente_documento ?? null,
        telefono: muestra.cliente_telefono ?? null,
        email: muestra.cliente_email ?? null,
        fuente: 'cartera-importada' as const,
      },
      cuentas,
      gestiones: gestiones.map((g) => ({
        id: g.id,
        fecha: g.fecha,
        tipo_gestion: g.tipo_gestion,
        resultado: g.resultado,
        observacion: g.observacion,
        proxima_accion: g.proxima_accion,
        proxima_fecha: g.proxima_fecha,
        cuenta_id: g.cartera_importada_documento_id,
        usuario_id: g.usuario_id,
      })),
      totales: {
        cuentas_pendientes: cuentas.length,
        saldo_total: cuentas.reduce((sum, c) => sum + c.saldo_pendiente, 0),
        gestiones_total: gestiones.length,
      },
    };
  }
}
