import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { ClsService } from 'nestjs-cls';
import { TenantAwareRepository } from '../../../common/repositories/tenant-aware.repository';
import { QueryEntity } from '../../../entities/query.entity';

@Injectable()
export class QueryRepository extends TenantAwareRepository<QueryEntity> {
  constructor(
    @InjectRepository(QueryEntity) repo: Repository<QueryEntity>,
    cls: ClsService,
  ) {
    super(repo, cls);
  }

  async findByIdWithRelations(id: string): Promise<QueryEntity | null> {
    const tenantId = this.getTenantId();
    return this.repo.findOne({
      where: { id, tenant_id: tenantId, is_deleted: false } as any,
      relations: ['destination', 'source', 'currency', 'quotes'],
    });
  }

  async getNextQueryNumber(): Promise<string> {
    const tenantId = this.getTenantId();
    const result = await this.repo
      .createQueryBuilder('q')
      .where('q.tenant_id = :tenantId', { tenantId })
      .getCount();
    const next = result + 1;
    return `QRY-${String(next).padStart(3, '0')}`;
  }

  async findAvailable(): Promise<QueryEntity[]> {
    const tenantId = this.getTenantId();
    return this.repo
      .createQueryBuilder('q')
      .leftJoin('quotations', 'qt', 'qt.query_id = q.id AND qt.tenant_id = q.tenant_id AND qt.is_deleted = false')
      .where('q.tenant_id = :tenantId', { tenantId })
      .andWhere('q.is_deleted = false')
      .andWhere('q.stage = :stage', { stage: 'new' })
      .andWhere('qt.id IS NULL')
      .leftJoinAndSelect('q.destination', 'dest')
      .orderBy('q.created_at', 'DESC')
      .getMany();
  }

  async countByStage(): Promise<Record<string, number>> {
    const tenantId = this.getTenantId();
    const result = await this.repo
      .createQueryBuilder('q')
      .select('q.stage', 'stage')
      .addSelect('COUNT(*)', 'count')
      .where('q.tenant_id = :tenantId', { tenantId })
      .andWhere('q.is_deleted = false')
      .groupBy('q.stage')
      .getRawMany();
    const counts: Record<string, number> = {};
    for (const row of result) {
      counts[row.stage] = parseInt(row.count, 10);
    }
    return counts;
  }
}
