import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Transaction } from '../../domain/entities/transaction.entity';
import { Wallet } from '../../domain/entities/wallet.entity';
import { ITransactionRepository, VolumeMetrics } from '../../domain/repositories/transaction.repository.interface';

@Injectable()
export class TransactionRepository implements ITransactionRepository {
  constructor(@InjectRepository(Transaction) private readonly repo: Repository<Transaction>) {}

  async create(data: Partial<Transaction>): Promise<Transaction> {
    const tx = this.repo.create(data);
    return this.repo.save(tx);
  }

  async findByWalletId(walletId: string, page: number, limit: number): Promise<[Transaction[], number]> {
    return this.repo.findAndCount({
      where: { walletId },
      skip: (page - 1) * limit,
      take: limit,
      order: { createdAt: 'DESC' },
    });
  }

  // ── Admin Queries ─────────────────────────────────────────────────────────

  async getVolumeMetrics(): Promise<VolumeMetrics> {
    const result = await this.repo
      .createQueryBuilder('tx')
      .select('COUNT(*)', 'totalVolume')
      .addSelect('COALESCE(SUM(CAST(tx.amount AS DECIMAL)), 0)', 'totalAmount')
      .getRawOne();

    return {
      totalVolume: parseInt(result?.totalVolume || '0', 10),
      totalAmount: result?.totalAmount || '0',
    };
  }

  async findPaginated(page: number, limit: number): Promise<[Transaction[], number]> {
    return this.repo.findAndCount({
      order: { createdAt: 'DESC' },
      skip: (page - 1) * limit,
      take: limit,
    });
  }

  async getDailyActiveUsers(date: Date): Promise<number> {
    const result = await this.repo
      .createQueryBuilder('tx')
      .innerJoin(Wallet, 'w', 'w.id = tx.wallet_id')
      .select('COUNT(DISTINCT w.user_id)', 'dau')
      .where('tx.created_at >= :date', { date })
      .getRawOne();

    return parseInt(result?.dau || '0', 10);
  }

  async getMonthlyActiveUsers(monthStart: Date): Promise<number> {
    const result = await this.repo
      .createQueryBuilder('tx')
      .innerJoin(Wallet, 'w', 'w.id = tx.wallet_id')
      .select('COUNT(DISTINCT w.user_id)', 'mau')
      .where('tx.created_at >= :monthStart', { monthStart })
      .getRawOne();

    return parseInt(result?.mau || '0', 10);
  }
}
