import { ConflictException, Injectable, NotFoundException } from '@nestjs/common';
import { PrismaService } from 'src/prisma/prisma.service';
import { CreateCondicionPagoDto } from './dto/create-condicion-pago.dto';
import { UpdateCondicionPagoDto } from './dto/update-condicion-pago.dto';

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

  async create(dto: CreateCondicionPagoDto, empresa_id: string) {
    // Verificar si ya existe la misma descripción para esta empresa
    const existing = await this.prisma.condiciones_pago.findFirst({
      where: {
        empresa_id,
        descripcion: dto.descripcion,
      },
    });

    if (existing) {
      throw new ConflictException('Ya existe una condición de pago con esta descripción');
    }

    // Solo puede existir UNA condición de tipo Contado (cod_condicion_venta=1) por empresa
    if (dto.cod_condicion_venta === 1) {
      const existingContado = await this.prisma.condiciones_pago.findFirst({
        where: {
          empresa_id,
          cod_condicion_venta: 1,
        },
      });

      if (existingContado) {
        throw new ConflictException('Ya existe una condición de pago tipo Contado. Solo puede haber una.');
      }
    }

    // Si es_default es true, quitar el default de las demás
    if (dto.es_default) {
      await this.prisma.condiciones_pago.updateMany({
        where: { empresa_id, es_default: true },
        data: { es_default: false },
      });
    }

    return this.prisma.condiciones_pago.create({
      data: {
        ...dto,
        empresa_id,
        cod_condicion_venta: 2, // Siempre Crédito al crear desde UI
        es_sistema: false,
        created_at: new Date(),
        updated_at: new Date(),
      },
    });
  }

  async findAll(empresa_id: string) {
    return this.prisma.condiciones_pago.findMany({
      where: { empresa_id },
      orderBy: [{ es_default: 'desc' }, { descripcion: 'asc' }],
    });
  }
  async findAllCondicionPagoActivas(empresa_id: string) {
    return this.prisma.condiciones_pago.findMany({
      where: { empresa_id ,activo:true},
      orderBy: [{ es_default: 'desc' }, { descripcion: 'asc' }],
    });
  }

  async findOne(id: string) {
    const condicion = await this.prisma.condiciones_pago.findUnique({
      where: { id },
    });
    if (!condicion) throw new NotFoundException('Condición de pago no encontrada');
    return condicion;
  }

  async update(id: string, dto: UpdateCondicionPagoDto, empresa_id: string) {
    const condicion = await this.findOne(id);

    // Verificar que pertenece a la empresa
    if (condicion.empresa_id !== empresa_id) {
      throw new ConflictException('No tiene permisos para modificar esta condición');
    }

    // Para condiciones de sistema, solo permitir cambiar es_default
    if (condicion.es_sistema) {
      // Si es_default es true, quitar el default de las demás
      if (dto.es_default) {
        await this.prisma.condiciones_pago.updateMany({
          where: { empresa_id, es_default: true, id: { not: id } },
          data: { es_default: false },
        });
      }

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

    // Si cambia la descripción, verificar que no exista
    if (dto.descripcion && dto.descripcion !== condicion.descripcion) {
      const existing = await this.prisma.condiciones_pago.findFirst({
        where: {
          empresa_id,
          descripcion: dto.descripcion,
          id: { not: id },
        },
      });
      if (existing) {
        throw new ConflictException('Ya existe una condición de pago con esta descripción');
      }
    }

    // Si es_default es true, quitar el default de las demás
    if (dto.es_default) {
      await this.prisma.condiciones_pago.updateMany({
        where: { empresa_id, es_default: true, id: { not: id } },
        data: { es_default: false },
      });
    }

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

  async remove(id: string, empresa_id: string) {
    const condicion = await this.findOne(id);

    // No permitir eliminar condiciones de sistema
    if (condicion.es_sistema) {
      throw new ConflictException('No se puede eliminar una condición de pago del sistema');
    }

    // Verificar que pertenece a la empresa
    if (condicion.empresa_id !== empresa_id) {
      throw new ConflictException('No tiene permisos para eliminar esta condición');
    }

    // Verificar si está en uso
    const enUso = await this.prisma.cuentas_cobrar.count({
      where: { condicion_pago_id: id },
    });

    if (enUso > 0) {
      throw new ConflictException('No se puede eliminar, la condición está en uso');
    }

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

  // Crear condición Contado por defecto para una empresa
  async createDefaultContado(empresa_id: string) {
    const exists = await this.prisma.condiciones_pago.findFirst({
      where: { empresa_id, cod_condicion_venta: 1 },
    });

    if (!exists) {
      return this.prisma.condiciones_pago.create({
        data: {
          empresa_id,
          descripcion: 'Contado',
          dias_plazo: 0,
          cuotas: 1,
          cuota_inicial: false,
          cod_condicion_venta: 1, // 1 = Contado
          cod_tipo_credito: 1,
          es_default: true,
          es_sistema: true,
          activo: true,
        },
      });
    }
    return exists;
  }
}
