import { Injectable } from '@nestjs/common';
import { type Prisma, type Valuation as PrismaValuation } from '@prisma/client';
import { PrismaService } from '@modules/shared';
import { ValuationEntity, type ValuationProps } from '../../domain/entities/valuation.entity';
import { type IValuationRepository } from '../../domain/repositories/valuation.repository';

@Injectable()
export class PrismaValuationRepository implements IValuationRepository {
  constructor(private readonly prisma: PrismaService) {}

  async findById(id: string): Promise<ValuationEntity | null> {
    const record = await this.prisma.valuation.findUnique({ where: { id } });
    return record ? this.toDomain(record) : null;
  }

  async findByPropertyId(propertyId: string): Promise<ValuationEntity[]> {
    const records = await this.prisma.valuation.findMany({
      where: { propertyId },
      orderBy: { createdAt: 'desc' },
      take: 50,
    });
    return records.map((r) => this.toDomain(r));
  }

  async findLatestByPropertyId(propertyId: string): Promise<ValuationEntity | null> {
    const record = await this.prisma.valuation.findFirst({
      where: { propertyId },
      orderBy: { createdAt: 'desc' },
    });
    return record ? this.toDomain(record) : null;
  }

  async save(entity: ValuationEntity): Promise<void> {
    await this.prisma.valuation.create({
      data: {
        id: entity.id,
        propertyId: entity.propertyId,
        estimatedPrice: entity.estimatedPrice,
        confidence: entity.confidence,
        pricePerM2: entity.pricePerM2,
        comparables: entity.comparables as Prisma.InputJsonValue,
        features: entity.features as Prisma.InputJsonValue,
        modelVersion: entity.modelVersion,
      },
    });
  }

  private toDomain(raw: PrismaValuation): ValuationEntity {
    const props: ValuationProps = {
      propertyId: raw.propertyId,
      estimatedPrice: raw.estimatedPrice,
      confidence: raw.confidence,
      pricePerM2: raw.pricePerM2,
      comparables: raw.comparables,
      features: raw.features,
      modelVersion: raw.modelVersion,
    };

    return new ValuationEntity(raw.id, props, raw.createdAt);
  }
}
