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

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

  async getAllCurrencies() {
    const rates = await this.prisma.currencyExchangeRate.findMany({
      distinct: ['toCurrency'],
      orderBy: { toCurrency: 'asc' },
    });

    return rates.map(rate => ({
      id: rate.id,
      code: rate.toCurrency,
      name: this.getCurrencyName(rate.toCurrency),
      symbol: this.getCurrencySymbol(rate.toCurrency),
      baseCurrencyCode: rate.fromCurrency,
      exchangeRate: Number(rate.rate),
      isActive: true,
      createdAt: rate.createdAt,
      updatedAt: rate.createdAt,
    }));
  }

  async createCurrency(dto: CreateCurrencyDto) {
    const { code, name, symbol, baseCurrencyCode = 'ETB', exchangeRate } = dto;

    if (!['ETB', 'USD', 'DJF'].includes(code.toUpperCase())) {
      throw new BadRequestException('Unsupported currency code');
    }

    if (exchangeRate <= 0) {
      throw new BadRequestException('Exchange rate must be positive');
    }

    const rate = await this.prisma.currencyExchangeRate.create({
      data: {
        fromCurrency: baseCurrencyCode as any,
        toCurrency: code.toUpperCase() as any,
        rate: exchangeRate,
        source: 'MANUAL',
      },
    });

    return {
      id: rate.id,
      code: rate.toCurrency,
      name,
      symbol,
      baseCurrencyCode: rate.fromCurrency,
      exchangeRate: Number(rate.rate),
      isActive: true,
      createdAt: rate.createdAt,
      updatedAt: rate.createdAt,
    };
  }

  async updateCurrency(id: string, dto: UpdateCurrencyDto) {
    const existing = await this.prisma.currencyExchangeRate.findUnique({
      where: { id },
    });

    if (!existing) {
      throw new NotFoundException('Currency not found');
    }

    if (dto.exchangeRate !== undefined && dto.exchangeRate <= 0) {
      throw new BadRequestException('Exchange rate must be positive');
    }

    const updated = await this.prisma.currencyExchangeRate.update({
      where: { id },
      data: {
        rate: dto.exchangeRate,
      },
    });

    return {
      id: updated.id,
      code: updated.toCurrency,
      name: dto.name || this.getCurrencyName(updated.toCurrency),
      symbol: dto.symbol || this.getCurrencySymbol(updated.toCurrency),
      baseCurrencyCode: updated.fromCurrency,
      exchangeRate: Number(updated.rate),
      isActive: true,
      createdAt: updated.createdAt,
      updatedAt: updated.createdAt,
    };
  }

  async deleteCurrency(id: string) {
    const existing = await this.prisma.currencyExchangeRate.findUnique({
      where: { id },
    });

    if (!existing) {
      throw new NotFoundException('Currency not found');
    }

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

    return { message: 'Currency deleted successfully' };
  }

  async syncExchangeRates() {
    return { message: 'Exchange rates synced successfully', synced: 0 };
  }

  private getCurrencyName(code: string): string {
    const names: Record<string, string> = {
      ETB: 'Ethiopian Birr',
      USD: 'US Dollar',
      DJF: 'Djiboutian Franc',
    };
    return names[code] || code;
  }

  private getCurrencySymbol(code: string): string {
    const symbols: Record<string, string> = {
      ETB: 'Br',
      USD: '$',
      DJF: 'Fdj',
    };
    return symbols[code] || code;
  }
}
