import { Injectable, NotFoundException, BadRequestException } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { GiftCard, GiftCardStatus } from './entities/gift-card.entity';
import { v4 as uuidv4 } from 'uuid';
@Injectable()
export class GiftCardService {
constructor(@InjectRepository(GiftCard) private readonly giftCardRepo: Repository<GiftCard>) {}
async createGiftCard(dto: { amount: number; type: string; senderId?: string; recipientEmail?: string; message?: string }): Promise<GiftCard> {
const code = this.generateUniqueCode();
const giftCard = this.giftCardRepo.create({
code, balance: dto.amount, initialAmount: dto.amount,
currency: 'USD', type: dto.type, status: GiftCardStatus.ACTIVE,
senderId: dto.senderId, recipientEmail: dto.recipientEmail, message: dto.message,
expiresAt: new Date(Date.now() + 365 * 24 * 60 * 60 * 1000),
});
return this.giftCardRepo.save(giftCard);
}
async validateAndRedeem(code: string, userId: string): Promise<GiftCard> {
const giftCard = await this.giftCardRepo.findOne({ where: { code, status: GiftCardStatus.ACTIVE } });
if (!giftCard) throw new NotFoundException('Gift card not found');
if (giftCard.balance <= 0) throw new BadRequestException('Gift card has no balance');
if (giftCard.expiresAt < new Date()) throw new BadRequestException('Gift card expired');
if (giftCard.recipientId && giftCard.recipientId !== userId) throw new BadRequestException('Not assigned to you');
return giftCard;
}
async deductBalance(code: string, amount: number): Promise<GiftCard> {
const giftCard = await this.giftCardRepo.findOne({ where: { code } });
if (giftCard.balance < amount) throw new BadRequestException('Insufficient balance');
giftCard.balance -= amount;
if (giftCard.balance === 0) giftCard.status = GiftCardStatus.REDEEMED;
return this.giftCardRepo.save(giftCard);
}
private generateUniqueCode(): string {
return `GLM-${uuidv4().slice(0, 8).toUpperCase()}-${Math.random().toString(36).slice(2, 6).toUpperCase()}`;
}
}