import { makeAutoObservable } from 'mobx';
import { type ServiceCategory, type ServiceItem } from '../../api';

const parsePrice = (value: ServiceItem['priceFrom']) => {
  if (value === null || value === undefined) {
    return null;
  }

  const numericValue = typeof value === 'string' ? Number(value) : value;
  return Number.isFinite(numericValue) ? Number(numericValue) : null;
};

export class ServiceModel {
  readonly id: string;
  title = '';
  slug = '';
  description = '';
  priceFrom: number | null = null;
  imageUrl: string | null = null;
  status = '';
  category: ServiceCategory | null = null;
  createdAt = '';
  updatedAt = '';

  constructor(dto: ServiceItem) {
    this.id = String(dto.id);
    this.hydrate(dto);

    makeAutoObservable(this, { id: false }, { autoBind: true });
  }

  get href() {
    return this.slug ? `/services/${this.slug}` : `/services/${this.id}`;
  }

  update(dto: Partial<ServiceItem>) {
    this.hydrate(dto);
  }

  toJSON(): ServiceItem {
    return {
      id: this.id,
      title: this.title,
      slug: this.slug,
      description: this.description,
      priceFrom: this.priceFrom ?? undefined,
      imageUrl: this.imageUrl ?? undefined,
      status: this.status,
      category: this.category ?? undefined,
      createdAt: this.createdAt,
      updatedAt: this.updatedAt,
    };
  }

  private hydrate(dto: Partial<ServiceItem>) {
    if (dto.title !== undefined) {
      this.title = dto.title;
    }

    if (dto.slug !== undefined) {
      this.slug = dto.slug ?? '';
    }

    if (dto.description !== undefined) {
      this.description = dto.description ?? '';
    }

    if (dto.priceFrom !== undefined) {
      this.priceFrom = parsePrice(dto.priceFrom);
    }

    if (dto.imageUrl !== undefined) {
      this.imageUrl = dto.imageUrl ?? null;
    }

    if (dto.status !== undefined) {
      this.status = dto.status;
    }

    if (dto.category !== undefined) {
      this.category = dto.category ?? null;
    }

    if (dto.createdAt !== undefined) {
      this.createdAt = dto.createdAt ?? '';
    }

    if (dto.updatedAt !== undefined) {
      this.updatedAt = dto.updatedAt ?? '';
    }
  }
}
