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 { QueryQuoteEntity } from '../../../entities/query-quote.entity';

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

  async findByQueryId(queryId: string): Promise<QueryQuoteEntity[]> {
    const tenantId = this.getTenantId();
    const quotes = await this.repo.find({
      where: { query_id: queryId, tenant_id: tenantId, is_deleted: false } as any,
      relations: [
        'hotel_items', 'hotel_items.hotel',
        'transport_items', 'transport_items.transport_service',
        'activity_items', 'activity_items.activity', 'activity_items.ticket',
        'special_items',
        'selling_currency',
      ],
      order: { quote_number: 'ASC' },
    });

    // Sort child items by sort_order and filter soft-deleted
    for (const q of quotes) {
      if (q.hotel_items) q.hotel_items = q.hotel_items.filter(i => !i.is_deleted).sort((a, b) => (a.check_in_date || '').localeCompare(b.check_in_date || ''));
      if (q.transport_items) q.transport_items = q.transport_items.filter(i => !i.is_deleted).sort((a, b) => (a.sort_order ?? 0) - (b.sort_order ?? 0));
      if (q.activity_items) q.activity_items = q.activity_items.filter(i => !i.is_deleted).sort((a, b) => (a.sort_order ?? 0) - (b.sort_order ?? 0));
      if (q.special_items) q.special_items = q.special_items.filter(i => !i.is_deleted).sort((a, b) => (a.sort_order ?? 0) - (b.sort_order ?? 0));
    }

    return quotes;
  }

  async findByIdWithRelations(id: string): Promise<QueryQuoteEntity | null> {
    const tenantId = this.getTenantId();
    return this.repo.findOne({
      where: { id, tenant_id: tenantId, is_deleted: false } as any,
      relations: [
        'hotel_items', 'hotel_items.hotel',
        'transport_items', 'transport_items.transport_service',
        'activity_items', 'activity_items.activity', 'activity_items.ticket',
        'special_items',
        'selling_currency',
      ],
    });
  }

  async unselectAllForQuery(queryId: string): Promise<void> {
    const tenantId = this.getTenantId();
    await this.repo.update(
      { query_id: queryId, tenant_id: tenantId } as any,
      { is_selected: false } as any,
    );
  }

  async markSelected(quoteId: string): Promise<void> {
    await this.repo.update(quoteId, { is_selected: true } as any);
  }

  async findSummariesByQueryId(queryId: string): Promise<any[]> {
    const tenantId = this.getTenantId();
    return this.repo.find({
      where: { query_id: queryId, tenant_id: tenantId, is_deleted: false } as any,
      select: ['id', 'query_id', 'label', 'quote_number', 'is_selected',
               'hotel_total', 'transport_total', 'activity_total', 'special_total', 'grand_total',
               'pricing_strategy', 'selling_currency_id', 'selling_total'],
      relations: ['selling_currency'],
      order: { quote_number: 'ASC' },
    });
  }

  async getNextQuoteNumber(queryId: string): Promise<number> {
    const tenantId = this.getTenantId();
    const result = await this.repo
      .createQueryBuilder('q')
      .select('MAX(q.quote_number)', 'max')
      .where('q.query_id = :queryId', { queryId })
      .andWhere('q.tenant_id = :tenantId', { tenantId })
      .getRawOne();
    return (result?.max || 0) + 1;
  }
}
