import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { BaseTenantRepository, TenantContextService } from '@iconsulting/shared';
import { IOrderRepository } from '../../../domain/repositories/order.repository.interface';
import { OrderEntity } from '../../../domain/entities/order.entity';
import { OrderORM } from '../../../infrastructure/database/postgres/entities/order.orm';

@Injectable()
export class OrderPostgresRepository
  extends BaseTenantRepository<OrderEntity, OrderORM>
  implements IOrderRepository
{
  constructor(
    @InjectRepository(OrderORM) repo: Repository<OrderORM>,
    tenantContext: TenantContextService,
  ) {
    super(repo, tenantContext);
  }

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

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

  async findByUserId(userId: string): Promise<OrderEntity[]> {
    const orms = await this.createTenantQueryBuilder('order')
      .andWhere('order.user_id = :userId', { userId })
      .orderBy('order.created_at', 'DESC')
      .getMany();
    return orms.map((orm) => this.toEntity(orm));
  }

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

  private toORM(entity: OrderEntity): OrderORM {
    const orm = new OrderORM();
    orm.id = entity.id;
    orm.tenantId = this.getTenantId();
    orm.userId = entity.userId;
    orm.conversationId = entity.conversationId;
    orm.serviceType = entity.serviceType;
    orm.serviceCategory = entity.serviceCategory;
    orm.amount = entity.amount;
    orm.currency = entity.currency;
    orm.status = entity.status;
    orm.paymentMethod = entity.paymentMethod;
    orm.paymentId = entity.paymentId;
    orm.paidAt = entity.paidAt;
    orm.completedAt = entity.completedAt;
    orm.metadata = entity.metadata;
    orm.createdAt = entity.createdAt;
    orm.updatedAt = entity.updatedAt;
    return orm;
  }

  private toEntity(orm: OrderORM): OrderEntity {
    return OrderEntity.fromPersistence({
      id: orm.id,
      userId: orm.userId,
      conversationId: orm.conversationId,
      serviceType: orm.serviceType,
      serviceCategory: orm.serviceCategory,
      amount: Number(orm.amount),
      currency: orm.currency,
      status: orm.status,
      paymentMethod: orm.paymentMethod,
      paymentId: orm.paymentId,
      paidAt: orm.paidAt,
      completedAt: orm.completedAt,
      metadata: orm.metadata,
      createdAt: orm.createdAt,
      updatedAt: orm.updatedAt,
    });
  }
}
