import { Injectable, NotFoundException, Logger } from '@nestjs/common';
import { AuditService } from 'src/audit/audit.service';
import { PrismaService } from '../prisma/prisma.service';

export interface CreateCajaDto {
  sucursal_id: string;
  empresa_id: string;
  descripcion: string;
}

export interface UpdateCajaDto {
  descripcion?: string;
}

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

  async create(createCajaDto: CreateCajaDto, user_id?: string) {
    const sucursal = await this.prisma.empresas_sucursales.findUnique({
      where: { id: createCajaDto.sucursal_id },
    });

    if (!sucursal) throw new NotFoundException('Sucursal no encontrada');

    const caja = await this.prisma.cajas.create({
      data: createCajaDto,
    });

    this.logger.log(`Caja creada: ${caja.descripcion} (${caja.id})`, 'CajasService');
    await this.auditService.log({
      empresa_id: createCajaDto.empresa_id,
      user_id,
      action: 'CREATE',
      entity_type: 'caja',
      entity_id: caja.id,
      descripcion: `Caja creada: ${caja.descripcion} | Sucursal: ${createCajaDto.sucursal_id}`,
      new_value: { descripcion: caja.descripcion, sucursal_id: caja.sucursal_id },
    });
    return { message: 'Caja creada exitosamente', data: caja };
  }

  async findAllBySucursal(sucursal_id: string) {
    const cajas = await this.prisma.cajas.findMany({
      where: { sucursal_id },
      include: {
        puntos_expedicion: {
          include: {
            numeraciones_documento: {
              include: {
                tipo_documento: true,
              },
            },
          },
        },
      },
      orderBy: { created_at: 'asc' },
    });

    return { message: 'Cajas obtenidas exitosamente', data: cajas };
  }

  async findOne(id: string) {
    const caja = await this.prisma.cajas.findUnique({
      where: { id },
      include: {
        puntos_expedicion: {
          include: {
            numeraciones_documento: {
              include: {
                tipo_documento: true,
                timbrado: true,
              },
            },
          },
        },
      },
    });

    if (!caja) throw new NotFoundException('Caja no encontrada');

    return { message: 'Caja encontrada exitosamente', data: caja };
  }

  async update(id: string, updateCajaDto: UpdateCajaDto, empresa_id?: string, user_id?: string) {
    const cajaExists = await this.prisma.cajas.findUnique({ where: { id } });
    if (!cajaExists) throw new NotFoundException('Caja no encontrada');

    const caja = await this.prisma.cajas.update({
      where: { id },
      data: updateCajaDto,
    });

    this.logger.log(`Caja actualizada: ${caja.descripcion} (${id})`, 'CajasService');
    await this.auditService.log({
      empresa_id,
      user_id,
      action: 'UPDATE',
      entity_type: 'caja',
      entity_id: id,
      descripcion: `Caja actualizada: ${caja.descripcion}`,
      old_value: { descripcion: cajaExists.descripcion },
      new_value: { descripcion: caja.descripcion },
    });
    return { message: 'Caja actualizada exitosamente', data: caja };
  }

  async toggleStatus(id: string, empresa_id?: string, user_id?: string) {
    const caja = await this.prisma.cajas.findUnique({ where: { id } });
    if (!caja) throw new NotFoundException('Caja no encontrada');

    const updated = await this.prisma.cajas.update({
      where: { id },
      data: { estado: !caja.estado },
    });

    const action = updated.estado ? 'ACTIVATE' : 'DEACTIVATE';
    this.logger.log(`Caja (${id}) ${updated.estado ? 'activada' : 'desactivada'}`, 'CajasService');
    await this.auditService.log({
      empresa_id,
      user_id,
      action,
      entity_type: 'caja',
      entity_id: id,
      descripcion: `Caja ${updated.estado ? 'activada' : 'desactivada'}: ${caja.descripcion}`,
      old_value: { estado: caja.estado },
      new_value: { estado: updated.estado },
    });
    return { message: 'Estado de caja actualizado', data: updated };
  }

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

    await this.prisma.cajas.delete({ where: { id } });

    this.logger.log(`Caja eliminada: ${caja.descripcion} (${id})`, 'CajasService');
    await this.auditService.log({
      empresa_id,
      user_id,
      action: 'DELETE',
      entity_type: 'caja',
      entity_id: id,
      descripcion: `Caja eliminada: ${caja.descripcion}`,
      old_value: { descripcion: caja.descripcion, sucursal_id: caja.sucursal_id, estado: caja.estado },
    });
    return { message: 'Caja eliminada exitosamente' };
  }
}
