import { BadRequestException, Injectable, NotFoundException } from '@nestjs/common';
import { PrismaService } from '../../prisma/prisma.service';

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

  async listar(empresaId: string, moneda?: string) {
    return this.prisma.cont_tipo_cambio.findMany({
      where: { empresa_id: empresaId, ...(moneda ? { moneda } : {}) },
      orderBy: [{ moneda: 'asc' }, { fecha: 'desc' }],
      take: 90,
    });
  }

  async registrar(empresaId: string, data: { moneda: string; fecha: string; tasa: number }) {
    if (data.tasa <= 0) throw new BadRequestException('La tasa debe ser mayor a 0');

    return this.prisma.cont_tipo_cambio.upsert({
      where: { empresa_id_moneda_fecha: { empresa_id: empresaId, moneda: data.moneda, fecha: new Date(data.fecha) } },
      update: { tasa: data.tasa },
      create: { empresa_id: empresaId, moneda: data.moneda, fecha: new Date(data.fecha), tasa: data.tasa },
    });
  }

  async getVigente(empresaId: string, moneda: string, fecha: Date) {
    if (moneda === 'PYG') return { moneda: 'PYG', tasa: 1, fecha: null };
    const tc = await this.prisma.cont_tipo_cambio.findFirst({
      where: { empresa_id: empresaId, moneda, fecha: { lte: fecha } },
      orderBy: { fecha: 'desc' },
    });
    if (!tc) return null;
    return { moneda: tc.moneda, tasa: Number(tc.tasa), fecha: tc.fecha };
  }

  async getTasa(empresaId: string, moneda: string, fecha: Date): Promise<number> {
    if (moneda === 'PYG') return 1;

    const tc = await this.prisma.cont_tipo_cambio.findFirst({
      where: { empresa_id: empresaId, moneda, fecha: { lte: fecha } },
      orderBy: { fecha: 'desc' },
    });
    if (!tc) throw new NotFoundException(`No hay tipo de cambio registrado para ${moneda} en la fecha ${fecha.toISOString().substring(0, 10)}`);
    return Number(tc.tasa);
  }

  async convertirAPYG(empresaId: string, monto: number, moneda: string, fecha: Date): Promise<number> {
    if (moneda === 'PYG') return monto;
    const tasa = await this.getTasa(empresaId, moneda, fecha);
    return Math.round(monto * tasa);
  }
}
