import { Injectable } from '@nestjs/common';
import { PrismaService } from 'src/prisma/prisma.service';
import { RedisService } from 'src/redis/redis.service';

@Injectable()
export class ReferencialesService {
  constructor(
    private readonly prisma: PrismaService,
    private readonly redis: RedisService,
  ) {}

  async findAll() {
    const cacheKey = 'referenciales:all';
    const ttlMs = 60 * 60 * 1000;
    return this.redis.wrap(cacheKey, () => this.loadAll(), ttlMs);
  }

  private async loadAll() {
    const [
      paises,
      ciudades,
      barrios,
      distritos,
      departamentos,
      actividad_economicas_sifen,
      afectacion_iva,
      condicion_negociacion,
      condicion_operacion,
      condicion_operacion_credito,
      forma_procesamiento_pago,
      motivos_autofactura,
      moneda,
      indicador_presencia,
      unidades_de_medida,
      modalidad_transporte,
      marca_tarjetas,
      motivo_emision_nota_credito_y_debito,
      motivo_emision_remision,
      naturaleza_receptor,
      responsable_emision,
      tarjeta,
      tipo_anticipo,
      tipo_constancia,
      tipo_credito,
      tipo_contribuyente,
      tipo_doc_asoc,
      tipo_documento,
      tipo_documento_identidad,
      tipo_documento_impreso,
      tipo_identificacion,
      tipo_impuesto,
      tipo_movimiento_cajas,
      tipo_obligacion,
      tipo_operacion,
      tipo_pago,
      tipo_transaccion,
      tipo_transporte,
      tipo_movimiento_inventario,
      estado_empresa,
      perfiles,
    ] = await Promise.all([
      this.prisma.paises.findMany(),
      this.prisma.ciudades.findMany(),
      this.prisma.barrios.findMany(),
      this.prisma.distritos.findMany(),
      this.prisma.departamentos.findMany(),
      this.prisma.actividad_economicas_sifen.findMany(),
      this.prisma.afectacion_iva.findMany(),
      this.prisma.condicion_negociacion.findMany(),
      this.prisma.condicion_operacion.findMany(),
      this.prisma.condicion_operacion_credito.findMany(),
      this.prisma.forma_procesamiento_pago.findMany(),
      this.prisma.motivos_autofactura.findMany(),
      this.prisma.moneda.findMany(),
      this.prisma.indicador_presencia.findMany(),
      this.prisma.unidades_de_medida.findMany(),
      this.prisma.modalidad_transporte.findMany(),
      this.prisma.marca_tarjetas.findMany(),
      this.prisma.motivo_emision_nota_credito_y_debito.findMany(),
      this.prisma.motivo_emision_remision.findMany(),
      this.prisma.naturaleza_receptor.findMany(),
      this.prisma.responsable_emision.findMany(),
      this.prisma.tarjeta.findMany(),
      this.prisma.tipo_anticipo.findMany(),
      this.prisma.tipo_constancia.findMany(),
      this.prisma.tipo_credito.findMany(),
      this.prisma.tipo_contribuyente.findMany(),
      this.prisma.tipo_doc_asoc.findMany(),
      this.prisma.tipo_documento.findMany(),
      this.prisma.tipo_documento_identidad.findMany(),
      this.prisma.tipo_documento_impreso.findMany(),
      this.prisma.tipo_identificacion.findMany(),
      this.prisma.tipo_impuesto.findMany(),
      this.prisma.tipo_movimiento_cajas.findMany(),
      this.prisma.tipo_obligacion.findMany(),
      this.prisma.tipo_operacion.findMany(),
      this.prisma.tipo_pago.findMany(),
      this.prisma.tipo_transaccion.findMany(),
      this.prisma.tipo_transporte.findMany(),
      this.prisma.tipo_movimiento_inventario.findMany(),
      this.prisma.estado_empresa.findMany({ where: { activo: true } }),
      this.prisma.perfiles.findMany(),
    ]);
    return {
      message: 'Referenciales obtenidos exitosamente',
      data: {
        geografica: { paises, ciudades, barrios, distritos, departamentos },
        actividad_economicas_sifen: actividad_economicas_sifen.map((a) => ({
          ...a,
          id: Number(a.id),
        })),
        afectacion_iva,
        condicion_negociacion,
        condicion_operacion,
        condicion_operacion_credito,
        forma_procesamiento_pago,
        forma_pago: [],
        motivos_autofactura,
        monedas: moneda,
        indicador_presencia,
        unidades_de_medida,
        modalidad_transporte,
        marca_tarjetas,
        motivo_emision_nota_credito_y_debito,
        motivo_emision_remision,
        naturaleza_receptor,
        responsable_emision,
        tarjeta,
        tipo_anticipo,
        tipo_constancia,
        tipo_credito,
        tipo_contribuyente,
        tipo_doc_asoc,
        tipo_documento,
        tipo_documento_identidad,
        tipo_documento_impreso,
        tipo_identificacion,
        tipo_impuesto,
        tipo_movimiento_cajas,
        tipo_obligacion,
        tipo_operacion,
        tipo_pago,
        tipo_transaccion,
        tipo_transporte,
        tipo_movimiento_inventario,
        estado_empresa,
        perfiles,
      },
    };
  }
}
