import { Injectable } from '@nestjs/common';
import { PrismaService } from 'src/prisma/prisma.service';
import { ToggleMedioPagoDto } from './dto/toggle-medio-pago.dto';

@Injectable()
export class MedioPagoService {
  constructor(private readonly prisma: PrismaService) {}

  // Obtener todos los medios de pago (catálogo SIFEN)
  async findAllMediosPago() {
    return this.prisma.medio_pago.findMany({
      orderBy: { codigo: 'asc' },
    });
  }

  // Obtener medios de pago habilitados para una empresa
  async findByEmpresa(empresa_id: string) {
    // Obtener todos los medios de pago con su estado para la empresa
    const mediosPago = await this.prisma.medio_pago.findMany({
      orderBy: { codigo: 'asc' },
    });

    const empresaMedios = await this.prisma.empresa_medio_pago.findMany({
      where: { empresa_id },
    });

    // Mapear para incluir el estado de activación por empresa
    return mediosPago.map((mp) => {
      const empresaMedio = empresaMedios.find((em) => em.medio_pago_id === mp.id);
      return {
        ...mp,
        activo: empresaMedio?.activo ?? false,
        orden: empresaMedio?.orden ?? 0,
        empresa_medio_pago_id: empresaMedio?.id ?? null,
      };
    });
  }

  // Activar/desactivar un medio de pago para una empresa
  async toggle(dto: ToggleMedioPagoDto, empresa_id: string) {
    const existing = await this.prisma.empresa_medio_pago.findFirst({
      where: {
        empresa_id,
        medio_pago_id: dto.medio_pago_id,
      },
    });

    if (existing) {
      return this.prisma.empresa_medio_pago.update({
        where: { id: existing.id },
        data: {
          activo: dto.activo,
          orden: dto.orden ?? existing.orden,
          updated_at: new Date(),
        },
      });
    } else {
      return this.prisma.empresa_medio_pago.create({
        data: {
          empresa_id,
          medio_pago_id: dto.medio_pago_id,
          activo: dto.activo,
          orden: dto.orden ?? 0,
        },
      });
    }
  }

  // Actualizar múltiples medios de pago a la vez
  async bulkToggle(medios: ToggleMedioPagoDto[], empresa_id: string) {
    const results: any[] = [];
    for (const medio of medios) {
      const result = await this.toggle(medio, empresa_id);
      results.push(result);
    }
    return results;
  }

  // Obtener solo los medios de pago activos para una empresa (para usar en POS)
  async findActiveByEmpresa(empresa_id: string) {
    const empresaMedios = await this.prisma.empresa_medio_pago.findMany({
      where: { empresa_id, activo: true },
      include: { medio_pago: true },
      orderBy: { orden: 'asc' },
    });

    return empresaMedios.map((em) => ({
      id: em.medio_pago.id,
      codigo: em.medio_pago.codigo,
      descripcion: em.medio_pago.descripcion,
      orden: em.orden,
    }));
  }

  // Inicializar medios de pago por defecto para una empresa (Efectivo activo)
  async initDefaultMediosPago(empresa_id: string) {
    // Buscar el medio de pago "Efectivo" (código 1)
    const efectivo = await this.prisma.medio_pago.findFirst({
      where: { codigo: 1 },
    });

    if (efectivo) {
      const exists = await this.prisma.empresa_medio_pago.findFirst({
        where: { empresa_id, medio_pago_id: efectivo.id },
      });

      if (!exists) {
        await this.prisma.empresa_medio_pago.create({
          data: {
            empresa_id,
            medio_pago_id: efectivo.id,
            activo: true,
            orden: 1,
          },
        });
      }
    }
  }
}
