import { type TransferCategory, type TransferListingStatus, type TransferPricingSource } from '@prisma/client';
import { AggregateRoot } from '@modules/shared';

export interface TransferListingProps {
  sellerId: string;
  category: TransferCategory;
  status: TransferListingStatus;
  title: string;
  description: string | null;
  address: string;
  ward: string | null;
  district: string;
  city: string;
  latitude: number;
  longitude: number;
  askingPriceVND: bigint;
  aiEstimatePriceVND: bigint | null;
  aiConfidence: number | null;
  pricingSource: TransferPricingSource;
  isNegotiable: boolean;
  areaM2: number | null;
  monthlyRentVND: bigint | null;
  depositMonths: number | null;
  remainingLeaseMo: number | null;
  businessType: string | null;
  footTraffic: string | null;
  media: Record<string, unknown>[] | null;
  moderationScore: number | null;
  moderationNotes: string | null;
  viewCount: number;
  saveCount: number;
  inquiryCount: number;
  contactPhone: string | null;
  contactName: string | null;
  featuredUntil: Date | null;
  expiresAt: Date | null;
  publishedAt: Date | null;
}

export class TransferListingEntity extends AggregateRoot<string> {
  private _sellerId: string;
  private _category: TransferCategory;
  private _status: TransferListingStatus;
  private _title: string;
  private _description: string | null;
  private _address: string;
  private _ward: string | null;
  private _district: string;
  private _city: string;
  private _latitude: number;
  private _longitude: number;
  private _askingPriceVND: bigint;
  private _aiEstimatePriceVND: bigint | null;
  private _aiConfidence: number | null;
  private _pricingSource: TransferPricingSource;
  private _isNegotiable: boolean;
  private _areaM2: number | null;
  private _monthlyRentVND: bigint | null;
  private _depositMonths: number | null;
  private _remainingLeaseMo: number | null;
  private _businessType: string | null;
  private _footTraffic: string | null;
  private _media: Record<string, unknown>[] | null;
  private _moderationScore: number | null;
  private _moderationNotes: string | null;
  private _viewCount: number;
  private _saveCount: number;
  private _inquiryCount: number;
  private _contactPhone: string | null;
  private _contactName: string | null;
  private _featuredUntil: Date | null;
  private _expiresAt: Date | null;
  private _publishedAt: Date | null;

  constructor(id: string, props: TransferListingProps, createdAt: Date, updatedAt: Date) {
    super(id, createdAt, updatedAt);
    this._sellerId = props.sellerId;
    this._category = props.category;
    this._status = props.status;
    this._title = props.title;
    this._description = props.description;
    this._address = props.address;
    this._ward = props.ward;
    this._district = props.district;
    this._city = props.city;
    this._latitude = props.latitude;
    this._longitude = props.longitude;
    this._askingPriceVND = props.askingPriceVND;
    this._aiEstimatePriceVND = props.aiEstimatePriceVND;
    this._aiConfidence = props.aiConfidence;
    this._pricingSource = props.pricingSource;
    this._isNegotiable = props.isNegotiable;
    this._areaM2 = props.areaM2;
    this._monthlyRentVND = props.monthlyRentVND;
    this._depositMonths = props.depositMonths;
    this._remainingLeaseMo = props.remainingLeaseMo;
    this._businessType = props.businessType;
    this._footTraffic = props.footTraffic;
    this._media = props.media;
    this._moderationScore = props.moderationScore;
    this._moderationNotes = props.moderationNotes;
    this._viewCount = props.viewCount;
    this._saveCount = props.saveCount;
    this._inquiryCount = props.inquiryCount;
    this._contactPhone = props.contactPhone;
    this._contactName = props.contactName;
    this._featuredUntil = props.featuredUntil;
    this._expiresAt = props.expiresAt;
    this._publishedAt = props.publishedAt;
  }

  get sellerId() { return this._sellerId; }
  get category() { return this._category; }
  get status() { return this._status; }
  get title() { return this._title; }
  get description() { return this._description; }
  get address() { return this._address; }
  get ward() { return this._ward; }
  get district() { return this._district; }
  get city() { return this._city; }
  get latitude() { return this._latitude; }
  get longitude() { return this._longitude; }
  get askingPriceVND() { return this._askingPriceVND; }
  get aiEstimatePriceVND() { return this._aiEstimatePriceVND; }
  get aiConfidence() { return this._aiConfidence; }
  get pricingSource() { return this._pricingSource; }
  get isNegotiable() { return this._isNegotiable; }
  get areaM2() { return this._areaM2; }
  get monthlyRentVND() { return this._monthlyRentVND; }
  get depositMonths() { return this._depositMonths; }
  get remainingLeaseMo() { return this._remainingLeaseMo; }
  get businessType() { return this._businessType; }
  get footTraffic() { return this._footTraffic; }
  get media() { return this._media; }
  get moderationScore() { return this._moderationScore; }
  get moderationNotes() { return this._moderationNotes; }
  get viewCount() { return this._viewCount; }
  get saveCount() { return this._saveCount; }
  get inquiryCount() { return this._inquiryCount; }
  get contactPhone() { return this._contactPhone; }
  get contactName() { return this._contactName; }
  get featuredUntil() { return this._featuredUntil; }
  get expiresAt() { return this._expiresAt; }
  get publishedAt() { return this._publishedAt; }

  approve(moderationScore?: number, notes?: string): void {
    this._status = 'ACTIVE';
    this._moderationScore = moderationScore ?? null;
    this._moderationNotes = notes ?? null;
    this._publishedAt = new Date();
    this.updatedAt = new Date();
  }

  reject(moderationScore?: number, notes?: string): void {
    this._status = 'REJECTED';
    this._moderationScore = moderationScore ?? null;
    this._moderationNotes = notes ?? null;
    this.updatedAt = new Date();
  }

  updateDetails(props: Partial<TransferListingProps>): void {
    if (props.sellerId !== undefined) this._sellerId = props.sellerId;
    if (props.category !== undefined) this._category = props.category;
    if (props.status !== undefined) this._status = props.status;
    if (props.title !== undefined) this._title = props.title;
    if (props.description !== undefined) this._description = props.description;
    if (props.address !== undefined) this._address = props.address;
    if (props.ward !== undefined) this._ward = props.ward;
    if (props.district !== undefined) this._district = props.district;
    if (props.city !== undefined) this._city = props.city;
    if (props.latitude !== undefined) this._latitude = props.latitude;
    if (props.longitude !== undefined) this._longitude = props.longitude;
    if (props.askingPriceVND !== undefined) this._askingPriceVND = props.askingPriceVND;
    if (props.aiEstimatePriceVND !== undefined) this._aiEstimatePriceVND = props.aiEstimatePriceVND;
    if (props.aiConfidence !== undefined) this._aiConfidence = props.aiConfidence;
    if (props.pricingSource !== undefined) this._pricingSource = props.pricingSource;
    if (props.isNegotiable !== undefined) this._isNegotiable = props.isNegotiable;
    if (props.areaM2 !== undefined) this._areaM2 = props.areaM2;
    if (props.monthlyRentVND !== undefined) this._monthlyRentVND = props.monthlyRentVND;
    if (props.depositMonths !== undefined) this._depositMonths = props.depositMonths;
    if (props.remainingLeaseMo !== undefined) this._remainingLeaseMo = props.remainingLeaseMo;
    if (props.businessType !== undefined) this._businessType = props.businessType;
    if (props.footTraffic !== undefined) this._footTraffic = props.footTraffic;
    if (props.media !== undefined) this._media = props.media;
    if (props.moderationScore !== undefined) this._moderationScore = props.moderationScore;
    if (props.moderationNotes !== undefined) this._moderationNotes = props.moderationNotes;
    if (props.viewCount !== undefined) this._viewCount = props.viewCount;
    if (props.saveCount !== undefined) this._saveCount = props.saveCount;
    if (props.inquiryCount !== undefined) this._inquiryCount = props.inquiryCount;
    if (props.contactPhone !== undefined) this._contactPhone = props.contactPhone;
    if (props.contactName !== undefined) this._contactName = props.contactName;
    if (props.featuredUntil !== undefined) this._featuredUntil = props.featuredUntil;
    if (props.expiresAt !== undefined) this._expiresAt = props.expiresAt;
    if (props.publishedAt !== undefined) this._publishedAt = props.publishedAt;
    this.updatedAt = new Date();
  }
}
