import { ConflictException, Injectable, NotFoundException, Logger } from '@nestjs/common';
import { AuditService } from 'src/audit/audit.service';
import { PrismaService } from '../prisma/prisma.service';
import { CreatePosConfigDto } from './dto/create-pos-config.dto';
import { UpdatePosConfigDto } from './dto/update-pos-config.dto';

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

  async create(dto: CreatePosConfigDto, empresa_id?: string, user_id?: string) {
    // Verificar que no exista configuración para esta caja
    const existing = await this.prisma.pos_config.findUnique({
      where: { caja_id: dto.caja_id },
    });

    if (existing) {
      throw new ConflictException('Ya existe una configuración de POS para esta caja');
    }

    const config = await this.prisma.pos_config.create({
      data: {
        ...dto,
        created_at: new Date(),
        updated_at: new Date(),
      },
    });
    this.logger.log(`POS config creada (${config.id}) caja ${dto.caja_id}`, 'PosConfigService');
    await this.auditService.log({
      empresa_id,
      user_id,
      action: 'CREATE',
      entity_type: 'pos_config',
      entity_id: config.id,
      descripcion: `Configuración POS creada para caja: ${dto.caja_id}`,
      new_value: { caja_id: dto.caja_id, tipo_pos: dto.tipo_pos },
    });
    return config;
  }

  async findByCaja(caja_id: string) {
    const config = await this.prisma.pos_config.findUnique({
      where: { caja_id },
    });

    // Si no existe, retornar configuración por defecto
    if (!config) {
      return this.getDefaultConfig(caja_id);
    }

    return config;
  }

  async findOne(id: string) {
    const config = await this.prisma.pos_config.findUnique({
      where: { id },
    });
    if (!config) throw new NotFoundException('Configuración de POS no encontrada');
    return config;
  }

  async update(caja_id: string, dto: UpdatePosConfigDto, empresa_id?: string, user_id?: string) {
    // Usar upsert para evitar condiciones de carrera
    const config = await this.prisma.pos_config.upsert({
      where: { caja_id },
      update: {
        ...dto,
        updated_at: new Date(),
      },
      create: {
        caja_id,
        ...dto,
        created_at: new Date(),
        updated_at: new Date(),
      },
    });
    this.logger.log(`POS config actualizada (${config.id}) caja ${caja_id}`, 'PosConfigService');
    await this.auditService.log({
      empresa_id,
      user_id,
      action: 'UPDATE',
      entity_type: 'pos_config',
      entity_id: config.id,
      descripcion: `Configuración POS actualizada para caja: ${caja_id}`,
      new_value: dto as Record<string, unknown>,
    });
    return config;
  }

  async remove(id: string, empresa_id?: string, user_id?: string) {
    const existing = await this.findOne(id);
    await this.prisma.pos_config.delete({
      where: { id },
    });
    this.logger.log(`POS config eliminada (${id}) caja ${existing.caja_id}`, 'PosConfigService');
    await this.auditService.log({
      empresa_id,
      user_id,
      action: 'DELETE',
      entity_type: 'pos_config',
      entity_id: id,
      descripcion: `Configuración POS eliminada para caja: ${existing.caja_id}`,
      old_value: { caja_id: existing.caja_id, tipo_pos: existing.tipo_pos },
    });
    return existing;
  }

  private getDefaultConfig(caja_id: string) {
    return {
      id: null,
      caja_id,
      tipo_pos: 'admin',
      fullscreen: true,
      layout: 'grid',
      show_product_image: true,
      show_product_price: true,
      show_product_stock: true,
      card_size: 'medium',
      categories_position: 'left',
      numpad_position: 'right',
      enable_tables: false,
      enable_delivery: false,
      enable_quick_sale: true,
      default_view: 'products',
      permitir_venta_sin_stock: true,
      cliente_default_id: null,
      deposito_default_id: null,
      retail_tile_size: 'medium',
      retail_grid_columns: 0,
      moneda_default_id: null,
      printer_name: null,
      printer_paper_width: 80,
      auto_print_ticket: false,
      print_mobile_enabled: false,
      requiere_autorizacion_apertura: false,
      requiere_autorizacion_cierre: false,
      requiere_arqueo_cierre: true,
      permitir_venta_credito: false,
      fondo_fijo: null,
      diferencia_arqueo_permitida: 0,
      created_at: null,
      updated_at: null,
    };
  }
}
