import { Injectable, Logger } from '@nestjs/common';
import { PrismaService } from 'src/prisma/prisma.service';
import {
  CALENDARIO_DEFAULT,
  ETAPAS_DEFAULT,
  MOTIVOS_DEFAULT,
  ORIGENES_DEFAULT,
  PIPELINE_DEFAULT,
  SLA_DEFAULT,
} from './crm-config-default.seed';

export interface ResumenSeedCrm {
  pipeline: number;
  etapas: number;
  origenes: number;
  motivos: number;
  calendario: number;
  sla: number;
  parametros: number;
}

/**
 * Configuración por defecto del CRM para una empresa (ticket CRM-04).
 *
 * **Idempotente**: agrega lo que falta y nunca pisa lo que el cliente cambió.
 * Todos los `createMany` usan `skipDuplicates` contra los índices únicos, así
 * que correrlo dos veces no duplica nada ni falla.
 *
 * Se dispara solo la primera vez que alguien abre el CRM (ver
 * `CrmConfigService.findAllPipelines`) y también por endpoint, para re-sembrar
 * lo que falte después de agregar catálogos nuevos — mismo criterio que
 * `seedMapeoFaltantes` en contabilidad.
 */
@Injectable()
export class CrmSeedService {
  private readonly logger = new Logger(CrmSeedService.name);

  constructor(private readonly prisma: PrismaService) {}

  /** true si la empresa todavía no tiene ningún pipeline: nunca se configuró el CRM. */
  async necesitaSeed(empresa_id: string): Promise<boolean> {
    const pipeline = await this.prisma.crm_pipelines.findFirst({ where: { empresa_id }, select: { id: true } });
    return !pipeline;
  }

  async asegurarConfiguracion(empresa_id: string, user_id?: string): Promise<ResumenSeedCrm> {
    const resumen = await this.prisma.$transaction(async (tx) => {
      const creado = (r: { count: number }) => r.count;

      // 1. Calendario primero: lo referencian las políticas de SLA y los parámetros.
      let calendario = await tx.crm_calendarios.findFirst({
        where: { empresa_id, nombre: CALENDARIO_DEFAULT.nombre },
        select: { id: true },
      });
      let calendariosCreados = 0;
      if (!calendario) {
        calendario = await tx.crm_calendarios.create({
          data: {
            empresa_id,
            nombre: CALENDARIO_DEFAULT.nombre,
            zona_horaria: CALENDARIO_DEFAULT.zona_horaria,
            horario: CALENDARIO_DEFAULT.horario,
            feriados: CALENDARIO_DEFAULT.feriados,
            es_default: true,
            created_by: user_id ?? null,
          },
          select: { id: true },
        });
        calendariosCreados = 1;
      }

      // 2. Pipeline y sus etapas.
      let pipeline = await tx.crm_pipelines.findFirst({
        where: { empresa_id, nombre: PIPELINE_DEFAULT.nombre },
        select: { id: true },
      });
      let pipelinesCreados = 0;
      if (!pipeline) {
        pipeline = await tx.crm_pipelines.create({
          data: {
            empresa_id,
            nombre: PIPELINE_DEFAULT.nombre,
            descripcion: PIPELINE_DEFAULT.descripcion,
            es_default: true,
            created_by: user_id ?? null,
          },
          select: { id: true },
        });
        pipelinesCreados = 1;
      }

      const etapas = await tx.crm_etapas.createMany({
        data: ETAPAS_DEFAULT.map((e) => ({
          empresa_id,
          pipeline_id: pipeline!.id,
          nombre: e.nombre,
          orden: e.orden,
          probabilidad: e.probabilidad,
          campos_obligatorios: e.campos_obligatorios,
          dias_estancamiento: e.dias_estancamiento,
          es_ganada: e.es_ganada ?? false,
          es_perdida: e.es_perdida ?? false,
          created_by: user_id ?? null,
        })),
        skipDuplicates: true,
      });

      // 3. Catálogos.
      const origenes = await tx.crm_origenes.createMany({
        data: ORIGENES_DEFAULT.map((o) => ({ empresa_id, ...o, created_by: user_id ?? null })),
        skipDuplicates: true,
      });

      const motivos = await tx.crm_motivos.createMany({
        data: MOTIVOS_DEFAULT.map((m) => ({
          empresa_id,
          tipo: m.tipo,
          descripcion: m.descripcion,
          orden: m.orden,
          created_by: user_id ?? null,
        })),
        skipDuplicates: true,
      });

      // 4. Políticas de SLA sobre el calendario comercial.
      const sla = await tx.crm_sla_politicas.createMany({
        data: SLA_DEFAULT.map((s) => ({
          empresa_id,
          nombre: s.nombre,
          prioridad: s.prioridad,
          min_primera_respuesta: s.min_primera_respuesta,
          min_resolucion: s.min_resolucion,
          calendario_id: calendario!.id,
          created_by: user_id ?? null,
        })),
        skipDuplicates: true,
      });

      // 5. Parámetros: una fila por empresa, con los defaults de la columna.
      const parametros = await tx.crm_parametros.createMany({
        data: [{ empresa_id, calendario_id: calendario!.id, created_by: user_id ?? null }],
        skipDuplicates: true,
      });

      return {
        pipeline: pipelinesCreados,
        etapas: creado(etapas),
        origenes: creado(origenes),
        motivos: creado(motivos),
        calendario: calendariosCreados,
        sla: creado(sla),
        parametros: creado(parametros),
      };
    });

    const total = Object.values(resumen).reduce((a, b) => a + b, 0);
    if (total > 0) {
      this.logger.log(
        `Configuración CRM sembrada para empresa=${empresa_id}: ` +
          `${resumen.pipeline} pipeline, ${resumen.etapas} etapas, ${resumen.origenes} orígenes, ` +
          `${resumen.motivos} motivos, ${resumen.sla} políticas SLA`,
      );
    }
    return resumen;
  }
}
