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

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

  async getAccount(passengerId: string) {
    const account = await this.prisma.loyaltyAccount.findUnique({ where: { passengerId }, include: { ledger: { orderBy: { createdAt: 'desc' }, take: 20 } } });
    if (!account) throw new NotFoundException('Loyalty account not found');
    const tiers = ['BRONZE', 'SILVER', 'GOLD', 'PLATINUM'];
    const thresholds: Record<string, number> = { BRONZE: 0, SILVER: 2000, GOLD: 5000, PLATINUM: 10000 };
    const idx = tiers.indexOf(account.tier);
    const nextTier = tiers[idx + 1] ?? null;
    const nextThreshold = nextTier ? thresholds[nextTier] : null;
    return {
      ...account, nextTier,
      points: account.pointsBalance,
      nextTierPoints: nextThreshold ?? account.pointsBalance,
      pointsToNextTier: nextThreshold ? nextThreshold - account.pointsBalance : 0,
      tierProgressPercent: nextThreshold ? +((account.pointsBalance - thresholds[account.tier]) / (nextThreshold - thresholds[account.tier]) * 100).toFixed(2) : 100,
    };
  }

  async getRewards(passengerId: string) {
    const account = await this.prisma.loyaltyAccount.findUnique({ where: { passengerId } });
    if (!account) throw new NotFoundException('Loyalty account not found');
    return this.prisma.loyaltyReward.findMany({ where: { accountId: account.id, available: true } });
  }

  async redeemReward(passengerId: string, rewardId: string) {
    const account = await this.prisma.loyaltyAccount.findUnique({ where: { passengerId } });
    if (!account) throw new NotFoundException('Loyalty account not found');
    const reward = await this.prisma.loyaltyReward.findUnique({ where: { id: rewardId } });
    if (!reward?.available) throw new NotFoundException('Reward not available');
    if (account.pointsBalance < reward.costPoints) throw new BadRequestException('Insufficient points');
    const newBalance = account.pointsBalance - reward.costPoints;
    await this.prisma.loyaltyAccount.update({ where: { passengerId }, data: { pointsBalance: newBalance } });
    await this.prisma.loyaltyLedgerEntry.create({ data: { accountId: account.id, delta: -reward.costPoints, reason: 'REWARD_REDEEMED', balanceAfter: newBalance } });
    await this.prisma.loyaltyReward.update({ where: { id: rewardId }, data: { available: false } });
    return { redeemed: true, pointsUsed: reward.costPoints, balanceAfter: newBalance };
  }
}
