import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { BaseTenantRepository, TenantContextService } from '@iconsulting/shared';
import { MessageORM } from '../../../infrastructure/database/postgres/entities/message.orm';
import { IMessageRepository } from '../../../domain/repositories/message.repository.interface';
import { MessageEntity } from '../../../domain/entities/message.entity';

@Injectable()
export class MessagePostgresRepository
  extends BaseTenantRepository<MessageEntity, MessageORM>
  implements IMessageRepository
{
  constructor(
    @InjectRepository(MessageORM) repo: Repository<MessageORM>,
    tenantContext: TenantContextService,
  ) {
    super(repo, tenantContext);
  }

  async save(message: MessageEntity): Promise<MessageEntity> {
    const orm = this.toORM(message);
    orm.tenantId = this.getTenantId();
    const saved = await this.repo.save(orm);
    return this.toEntity(saved);
  }

  async findById(id: string): Promise<MessageEntity | null> {
    const orm = await this.findOneWithTenant({ id } as any);
    return orm ? this.toEntity(orm) : null;
  }

  async findByConversationId(conversationId: string): Promise<MessageEntity[]> {
    const orms = await this.createTenantQueryBuilder('message')
      .andWhere('message.conversation_id = :conversationId', { conversationId })
      .orderBy('message.created_at', 'ASC')
      .getMany();
    return orms.map((orm) => this.toEntity(orm));
  }

  async countByConversationId(conversationId: string): Promise<number> {
    return this.createTenantQueryBuilder('message')
      .andWhere('message.conversation_id = :conversationId', { conversationId })
      .getCount();
  }

  private toORM(entity: MessageEntity): MessageORM {
    const orm = new MessageORM();
    orm.id = entity.id;
    orm.tenantId = this.getTenantId();
    orm.conversationId = entity.conversationId;
    orm.role = entity.role;
    orm.type = entity.type;
    orm.content = entity.content;
    orm.metadata = entity.metadata;
    orm.inputTokens = entity.inputTokens;
    orm.outputTokens = entity.outputTokens;
    orm.createdAt = entity.createdAt;
    return orm;
  }

  private toEntity(orm: MessageORM): MessageEntity {
    return MessageEntity.fromPersistence({
      id: orm.id,
      conversationId: orm.conversationId,
      role: orm.role,
      type: orm.type,
      content: orm.content,
      metadata: orm.metadata,
      inputTokens: orm.inputTokens,
      outputTokens: orm.outputTokens,
      createdAt: orm.createdAt,
    });
  }
}
