import { Injectable } from '@nestjs/common';
import { PrismaService } from '../prisma/prisma.service';
import { TransferOrderMapper } from '../mappers/transfer-order.mapper';
import { TransferOrder } from '../../../domain/aggregates/transfer-order.aggregate';
import { ITransferOrderRepository } from '../../../domain/repositories/transfer-order.repository.interface';

@Injectable()
export class TransferOrderRepositoryImpl implements ITransferOrderRepository {
  constructor(private readonly prisma: PrismaService) {}

  async findById(id: bigint): Promise<TransferOrder | null> {
    const record = await this.prisma.transferOrder.findUnique({
      where: { id },
    });
    return record ? TransferOrderMapper.toDomain(record) : null;
  }

  async findByTransferOrderNo(transferOrderNo: string): Promise<TransferOrder | null> {
    const record = await this.prisma.transferOrder.findUnique({
      where: { transferOrderNo },
    });
    return record ? TransferOrderMapper.toDomain(record) : null;
  }

  async findBySellerUserId(
    userId: bigint,
    options?: { limit?: number; offset?: number },
  ): Promise<TransferOrder[]> {
    const records = await this.prisma.transferOrder.findMany({
      where: { sellerUserId: userId },
      orderBy: { createdAt: 'desc' },
      take: options?.limit ?? 20,
      skip: options?.offset ?? 0,
    });
    return records.map(TransferOrderMapper.toDomain);
  }

  async findByBuyerUserId(
    userId: bigint,
    options?: { limit?: number; offset?: number },
  ): Promise<TransferOrder[]> {
    const records = await this.prisma.transferOrder.findMany({
      where: { buyerUserId: userId },
      orderBy: { createdAt: 'desc' },
      take: options?.limit ?? 20,
      skip: options?.offset ?? 0,
    });
    return records.map(TransferOrderMapper.toDomain);
  }

  async findBySourceOrderNo(sourceOrderNo: string): Promise<TransferOrder[]> {
    const records = await this.prisma.transferOrder.findMany({
      where: { sourceOrderNo },
      orderBy: { createdAt: 'desc' },
    });
    return records.map(TransferOrderMapper.toDomain);
  }

  async findByStatus(status: string, limit: number = 100): Promise<TransferOrder[]> {
    const records = await this.prisma.transferOrder.findMany({
      where: { status },
      orderBy: { createdAt: 'asc' },
      take: limit,
    });
    return records.map(TransferOrderMapper.toDomain);
  }

  async countByUserAsSellerOrBuyer(userId: bigint): Promise<number> {
    return this.prisma.transferOrder.count({
      where: {
        OR: [
          { sellerUserId: userId },
          { buyerUserId: userId },
        ],
      },
    });
  }
}
