import { BadRequestException, Injectable, NotFoundException } from '@nestjs/common';
import { Prisma } from '@prisma/client';
import { PrismaService } from '../../prisma/prisma.service';
import { CreateConceptoDto, QueryConceptosDto, UpdateConceptoDto } from '../dto/conceptos.dto';

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

  listar(empresaId: string, query: QueryConceptosDto) {
    const where: Prisma.rrhh_conceptos_liquidacionWhereInput = { empresa_id: empresaId };
    if (query.tipo) where.tipo = query.tipo;
    if (query.categoria) where.categoria = query.categoria;
    if (query.search?.trim()) {
      const term = query.search.trim();
      where.OR = [
        { codigo: { contains: term, mode: 'insensitive' } },
        { nombre: { contains: term, mode: 'insensitive' } },
      ];
    }

    return this.prisma.rrhh_conceptos_liquidacion.findMany({
      where,
      orderBy: [{ tipo: 'asc' }, { orden_visualizacion: 'asc' }, { nombre: 'asc' }],
    });
  }

  async crear(empresaId: string, dto: CreateConceptoDto) {
    const dup = await this.prisma.rrhh_conceptos_liquidacion.findFirst({
      where: { empresa_id: empresaId, codigo: dto.codigo },
    });
    if (dup) throw new BadRequestException(`Ya existe un concepto con código ${dto.codigo}`);

    return this.prisma.rrhh_conceptos_liquidacion.create({
      data: {
        ...dto,
        empresa_id: empresaId,
        afecta_base_ips: dto.afecta_base_ips ?? false,
        afecta_base_aguinaldo: dto.afecta_base_aguinaldo ?? false,
        es_fijo: dto.es_fijo ?? false,
        es_porcentaje: dto.es_porcentaje ?? false,
        aplica_a: dto.aplica_a ?? 'TODOS',
        orden_visualizacion: dto.orden_visualizacion ?? 0,
        activo: dto.activo ?? true,
      },
    });
  }

  async actualizar(id: string, empresaId: string, dto: UpdateConceptoDto) {
    const existe = await this.prisma.rrhh_conceptos_liquidacion.findFirst({
      where: { id, empresa_id: empresaId },
    });
    if (!existe) throw new NotFoundException('Concepto no encontrado');

    if (dto.codigo && dto.codigo !== existe.codigo) {
      const dup = await this.prisma.rrhh_conceptos_liquidacion.findFirst({
        where: { empresa_id: empresaId, codigo: dto.codigo, NOT: { id } },
      });
      if (dup) throw new BadRequestException(`Ya existe un concepto con código ${dto.codigo}`);
    }

    return this.prisma.rrhh_conceptos_liquidacion.update({
      where: { id },
      data: { ...dto, updated_at: new Date() },
    });
  }

  async eliminar(id: string, empresaId: string) {
    const existe = await this.prisma.rrhh_conceptos_liquidacion.findFirst({
      where: { id, empresa_id: empresaId },
    });
    if (!existe) throw new NotFoundException('Concepto no encontrado');
    if (existe.es_del_sistema) {
      throw new BadRequestException('Los conceptos del sistema no se pueden eliminar (sólo desactivar)');
    }

    return this.prisma.rrhh_conceptos_liquidacion.delete({ where: { id } });
  }
}
