import { BadRequestException, Injectable, NotFoundException, Logger } from '@nestjs/common';
import { AuditService } from 'src/audit/audit.service';
import { PrismaService } from '../prisma/prisma.service';
import { CreateMarcaDto } from './dto/create-marca.dto';
import { UpdateMarcaDto } from './dto/update-marca.dto';

@Injectable()
export class MarcasService {
  private readonly logger = new Logger(MarcasService.name);
  constructor(
    private readonly prisma: PrismaService,
    private readonly auditService: AuditService,
  ) {}

  async create(dto: CreateMarcaDto, empresa_id: string, user_id?: string) {
    const marca = await this.prisma.marcas.create({
      data: {
        empresa_id,
        codigo: dto.codigo,
        descripcion: dto.descripcion,
      },
    });
    this.logger.log(`Marca creada: ${marca.descripcion} (${marca.id})`, 'MarcasService');
    await this.auditService.log({
      empresa_id,
      user_id,
      action: 'CREATE',
      entity_type: 'marca',
      entity_id: marca.id,
      descripcion: `Marca creada: ${marca.descripcion} | Código: ${marca.codigo}`,
      new_value: { descripcion: marca.descripcion, codigo: marca.codigo },
    });
    return { message: 'Marca creada exitosamente', data: marca };
  }

  async findAll(empresa_id: string) {
    const marcas = await this.prisma.marcas.findMany({
      where: { empresa_id },
      orderBy: { descripcion: 'asc' },
    });
    return marcas;
  }

  async findOne(id: string) {
    const marca = await this.prisma.marcas.findUnique({
      where: { id },
    });
    if (!marca) throw new NotFoundException('Marca no encontrada');
    return marca;
  }

  async update(id: string, dto: UpdateMarcaDto, empresa_id?: string, user_id?: string) {
    const existing = await this.prisma.marcas.findUnique({ where: { id } });
    if (!existing) throw new NotFoundException('Marca no encontrada');

    const marca = await this.prisma.marcas.update({
      where: { id },
      data: {
        codigo: dto.codigo,
        descripcion: dto.descripcion,
        updated_at: new Date(),
      },
    });
    this.logger.log(`Marca actualizada: ${marca.descripcion} (${id})`, 'MarcasService');
    await this.auditService.log({
      empresa_id: empresa_id ?? existing.empresa_id,
      user_id,
      action: 'UPDATE',
      entity_type: 'marca',
      entity_id: id,
      descripcion: `Marca actualizada: ${marca.descripcion}`,
      old_value: { descripcion: existing.descripcion, codigo: existing.codigo },
      new_value: { descripcion: marca.descripcion, codigo: marca.codigo },
    });
    return { message: 'Marca actualizada exitosamente', data: marca };
  }

  async toggleActive(id: string, empresa_id?: string, user_id?: string) {
    const existing = await this.prisma.marcas.findUnique({ where: { id } });
    if (!existing) throw new NotFoundException('Marca no encontrada');

    const marca = await this.prisma.marcas.update({
      where: { id },
      data: { active: !existing.active, updated_at: new Date() },
    });
    const action = marca.active ? 'ACTIVATE' : 'DEACTIVATE';
    this.logger.log(`Marca (${id}) ${marca.active ? 'activada' : 'desactivada'}`, 'MarcasService');
    await this.auditService.log({
      empresa_id: empresa_id ?? existing.empresa_id,
      user_id,
      action,
      entity_type: 'marca',
      entity_id: id,
      descripcion: `Marca ${marca.active ? 'activada' : 'desactivada'}: ${existing.descripcion}`,
      old_value: { active: existing.active },
      new_value: { active: marca.active },
    });
    return { message: 'Estado de la marca actualizado', data: marca };
  }

  async remove(id: string, empresa_id?: string, user_id?: string) {
    const existing = await this.prisma.marcas.findUnique({ where: { id } });
    if (!existing) throw new NotFoundException('Marca no encontrada');

    // Verificar si tiene productos asociados
    const productosCount = await this.prisma.productos.count({
      where: { marca_id: id },
    });

    if (productosCount > 0) {
      throw new BadRequestException(
        `No se puede eliminar la marca porque tiene ${productosCount} producto(s) asociado(s)`,
      );
    }

    await this.prisma.marcas.delete({ where: { id } });
    this.logger.log(`Marca eliminada: ${existing.descripcion} (${id})`, 'MarcasService');
    await this.auditService.log({
      empresa_id: empresa_id ?? existing.empresa_id,
      user_id,
      action: 'DELETE',
      entity_type: 'marca',
      entity_id: id,
      descripcion: `Marca eliminada: ${existing.descripcion} | Código: ${existing.codigo}`,
      old_value: { descripcion: existing.descripcion, codigo: existing.codigo },
    });
    return { message: 'Marca eliminada exitosamente' };
  }
}
