import { Injectable } from '@nestjs/common';
import { PrismaService } from '../../prisma/prisma.service';
import { CarteraConfigService } from '../config/cartera-config.service';
import { CarteraImportadaFuente } from '../fuentes/cartera-importada-fuente.service';
import { ErpNovasisFuente } from '../fuentes/erp-novasis-fuente.service';
import type { CuentaPendiente, IFuenteCartera, ModoOperativo } from '../fuentes/i-fuente-cartera.interface';
import { WorklistQueryDto } from '../dto/worklist-query.dto';

/**
 * Worklist agnóstica del origen. Elige la fuente apropiada según la config
 * del tenant (por ahora siempre ErpNovasisFuente; mes 3-4 entra
 * CarteraImportadaFuente y mes 7+ ApiExternaFuente).
 */
@Injectable()
export class WorklistService {
  constructor(
    private readonly prisma: PrismaService,
    private readonly configService: CarteraConfigService,
    private readonly erpNovasisFuente: ErpNovasisFuente,
    private readonly carteraImportadaFuente: CarteraImportadaFuente,
  ) {}

  async getPriorizada(empresa_id: string, usuario_id: string, query: WorklistQueryDto) {
    const config = await this.configService.getOrCreate(empresa_id);
    const fuente = this.resolverFuente(config.fuente_default);
    fuente.setModo(config.modo_operativo as ModoOperativo);

    // Si pidió "solo mis clientes", resolver el cobrador_id del usuario actual.
    // Si el usuario no es un cobrador asignado, devuelve null → no muestra nada.
    let cobradorIdEfectivo = query.cobrador_id ?? null;
    let usuarioNoEsCobrador = false;
    if (query.solo_mis_clientes && !query.cobrador_id) {
      const cobradorId = await this.resolverCobradorDeUsuario(empresa_id, usuario_id);
      if (!cobradorId) {
        usuarioNoEsCobrador = true;
      } else {
        cobradorIdEfectivo = cobradorId;
      }
    }

    const items = usuarioNoEsCobrador
      ? []
      : await fuente.listarCuentasPendientes({
          empresa_id,
          cliente_id: query.cliente_id,
          cobrador_id: cobradorIdEfectivo ?? undefined,
          con_saldo: true,
          page: query.page,
          page_size: query.page_size,
        });

    const filtrados = this.aplicarFiltrosCliente(items, query);

    return {
      items: filtrados,
      page: query.page ?? 1,
      page_size: query.page_size ?? 50,
      fuente: fuente.getOrigen(),
      modo: fuente.getModo(),
      filtrado_por_cobrador: !!cobradorIdEfectivo,
      usuario_no_es_cobrador: usuarioNoEsCobrador,
    };
  }

  /**
   * Resuelve el cobrador_id asignado al usuario actual (via vendedores_cobradores.usuario_id).
   * Devuelve null si el usuario no es un cobrador (ej. admin, vendedor sin rol de cobrador).
   */
  async resolverCobradorDeUsuario(empresa_id: string, usuario_id: string): Promise<string | null> {
    const cobrador = await this.prisma.vendedores_cobradores.findFirst({
      where: { empresa_id, usuario_id, active: true },
      select: { id: true },
    });
    return cobrador?.id ?? null;
  }

  private resolverFuente(fuenteDefault: string): IFuenteCartera & { setModo(m: ModoOperativo): void } {
    if (fuenteDefault === 'cartera-importada') return this.carteraImportadaFuente;
    return this.erpNovasisFuente;
  }

  private aplicarFiltrosCliente(items: CuentaPendiente[], query: WorklistQueryDto): CuentaPendiente[] {
    let out = items;
    if (query.min_dias_mora !== undefined) {
      out = out.filter((c) => c.dias_mora >= query.min_dias_mora!);
    }
    if (query.search) {
      const s = query.search.toLowerCase().trim();
      out = out.filter(
        (c) =>
          c.cliente_nombre.toLowerCase().includes(s) ||
          c.documento_numero.toLowerCase().includes(s),
      );
    }
    return out;
  }
}
