import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { JournalEntry, JournalType } from '../../domain/entities/journal-entry.entity';
import { IJournalEntryRepository } from '../../domain/repositories/journal-entry.repository.interface';

@Injectable()
export class JournalEntryRepository implements IJournalEntryRepository {
  constructor(
    @InjectRepository(JournalEntry)
    private readonly repo: Repository<JournalEntry>,
  ) {}

  async save(entry: JournalEntry): Promise<JournalEntry> {
    return this.repo.save(entry);
  }

  create(data: Partial<JournalEntry>): JournalEntry {
    return this.repo.create(data);
  }

  async getSumByType(type: JournalType): Promise<string> {
    const result = await this.repo
      .createQueryBuilder('j')
      .select('COALESCE(SUM(j.amount::numeric), 0)', 'total')
      .where('j.entry_type = :type', { type })
      .getRawOne();

    return result?.total || '0';
  }

  async getMonthlyRevenueByType(
    type: JournalType,
  ): Promise<Array<{ month: string; revenue: string }>> {
    const results = await this.repo
      .createQueryBuilder('j')
      .select("TO_CHAR(j.created_at, 'YYYY-MM')", 'month')
      .addSelect('COALESCE(SUM(j.amount::numeric), 0)', 'revenue')
      .where('j.entry_type = :type', { type })
      .andWhere("j.created_at >= NOW() - INTERVAL '12 months'")
      .groupBy("TO_CHAR(j.created_at, 'YYYY-MM')")
      .orderBy('month', 'ASC')
      .getRawMany();

    return results.map((row) => ({
      month: row.month,
      revenue: row.revenue,
    }));
  }
}
