import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Redemption } from '../../domain/entities/redemption.entity';
import {
  IRedemptionRepository,
  RedemptionListFilters,
} from '../../domain/repositories/redemption.repository.interface';

@Injectable()
export class RedemptionRepository implements IRedemptionRepository {
  constructor(
    @InjectRepository(Redemption)
    private readonly repo: Repository<Redemption>,
  ) {}

  async findById(id: string): Promise<Redemption | null> {
    return this.repo.findOne({ where: { id } });
  }

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

  async createMany(data: Partial<Redemption>[]): Promise<Redemption[]> {
    const entities = this.repo.create(data);
    return this.repo.save(entities);
  }

  async findAndCount(filters: RedemptionListFilters): Promise<[Redemption[], number]> {
    const { issuerId, startDate, endDate, page, limit } = filters;
    const qb = this.repo.createQueryBuilder('r');

    if (issuerId) qb.andWhere('r.issuer_id = :issuerId', { issuerId });
    if (startDate) qb.andWhere('r.created_at >= :startDate', { startDate });
    if (endDate) qb.andWhere('r.created_at <= :endDate', { endDate });

    qb.orderBy('r.created_at', 'DESC')
      .skip((page - 1) * limit)
      .take(limit);

    return qb.getManyAndCount();
  }

  async getTodayStats(issuerId: string): Promise<{ count: number; totalAmount: number }> {
    const result = await this.repo
      .createQueryBuilder('r')
      .select([
        'COUNT(r.id) as "count"',
        'COALESCE(SUM(CAST(r.amount AS numeric)), 0) as "totalAmount"',
      ])
      .where('r.issuer_id = :issuerId', { issuerId })
      .andWhere('r.created_at >= CURRENT_DATE')
      .getRawOne();

    return {
      count: Number(result.count) || 0,
      totalAmount: Number(result.totalAmount) || 0,
    };
  }
}
