import { type ListingStatus, type TransactionType, type PropertyType } from '@prisma/client';
import { type ListingEntity } from '../entities/listing.entity';
import { type ListingDetailData, type ListingSearchItem, type ListingSellerItem, type ListingSimilarItem } from './listing-read.dto';

export const LISTING_REPOSITORY = Symbol('LISTING_REPOSITORY');

export type ListingSortBy = 'publishedAt' | 'priceAsc' | 'priceDesc' | 'createdAt';
export type ListingSortOrder = 'asc' | 'desc';

export interface ListingSearchParams {
  status?: ListingStatus;
  transactionType?: TransactionType;
  propertyType?: PropertyType;
  city?: string;
  district?: string;
  minPrice?: bigint;
  maxPrice?: bigint;
  minArea?: number;
  maxArea?: number;
  bedrooms?: number;
  page?: number;
  limit?: number;
  /** Sort field. Defaults to publishedAt with featured listings first. */
  sortBy?: ListingSortBy;
  /** Sort direction (asc | desc). Defaults to desc. */
  order?: ListingSortOrder;
  /** Return only listings with publishedAt > newSince (delta pull for FE ticker). */
  newSince?: Date;
}

export interface PaginatedResult<T> {
  data: T[];
  total: number;
  page: number;
  limit: number;
  totalPages: number;
}

export interface IListingRepository {
  findById(id: string): Promise<ListingEntity | null>;
  findByIdWithProperty(id: string): Promise<ListingDetailData | null>;
  findSimilar(id: string, limit: number): Promise<ListingSimilarItem[]>;
  save(listing: ListingEntity): Promise<void>;
  update(listing: ListingEntity): Promise<void>;
  delete(id: string): Promise<void>;
  search(params: ListingSearchParams): Promise<PaginatedResult<ListingSearchItem>>;
  findByStatus(status: ListingStatus, page: number, limit: number): Promise<PaginatedResult<ListingSearchItem>>;
  findBySellerId(sellerId: string, page: number, limit: number): Promise<PaginatedResult<ListingSellerItem>>;
}
