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

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

  async getAccounts(params: { search?: string; page?: string; pageSize?: string } = {}) {
    const { search, page = '1', pageSize = '20' } = params;
    const skip = (parseInt(page) - 1) * parseInt(pageSize);
    const where: any = {};
    if (search) {
      where.passenger = {
        OR: [
          { user: { fullName: { contains: search, mode: 'insensitive' } } },
          { user: { email: { contains: search, mode: 'insensitive' } } },
        ],
      };
    }
    const [items, total] = await Promise.all([
      this.prisma.walletAccount.findMany({
        where,
        skip,
        take: parseInt(pageSize),
        orderBy: { balanceMinor: 'desc' },
        include: { passenger: { include: { user: true } } },
      }),
      this.prisma.walletAccount.count({ where }),
    ]);
    return {
      items: items.map(w => ({
        ...w,
        passenger: w.passenger ? {
          id: w.passenger.id,
          fullName: (w.passenger as any).user?.fullName ?? null,
          email: (w.passenger as any).user?.email ?? null,
          phone: (w.passenger as any).user?.phone ?? null,
        } : null,
      })),
      meta: { page: parseInt(page), pageSize: parseInt(pageSize), total, totalPages: Math.ceil(total / parseInt(pageSize)) },
    };
  }

  async getWallet(passengerId: string) {
    const wallet = await this.prisma.walletAccount.findUnique({ where: { passengerId }, include: { ledger: { orderBy: { createdAt: 'desc' }, take: 20 } } });
    if (!wallet) throw new NotFoundException('Wallet not found');
    return wallet;
  }

  async topUp(passengerId: string, amountMinor: number, description = 'Top-up') {
    const wallet = await this.prisma.walletAccount.findUnique({ where: { passengerId } });
    if (!wallet) throw new NotFoundException('Wallet not found');
    const newBalance = wallet.balanceMinor + amountMinor;
    await this.prisma.walletAccount.update({ where: { passengerId }, data: { balanceMinor: newBalance } });
    return this.prisma.walletLedgerEntry.create({ data: { walletId: wallet.id, type: 'CREDIT', amountMinor, balanceAfterMinor: newBalance, description } });
  }

  async deleteAccount(id: string) {
    const wallet = await this.prisma.walletAccount.findUnique({ where: { id } });
    if (!wallet) throw new NotFoundException('Wallet account not found');
    await this.prisma.$transaction([
      this.prisma.walletLedgerEntry.deleteMany({ where: { walletId: id } }),
      this.prisma.walletAccount.delete({ where: { id } }),
    ]);
    return { deleted: true, accountId: id };
  }
}
