import { makeAutoObservable, runInAction } from 'mobx';

import { adminApi, type AdminServiceCategory } from '../../api';
import { ServiceCategoryModel } from './serviceCategory.model.ts';

export class ServiceCategoryCollectionModel {
  readonly items = new Map<string, ServiceCategoryModel>();
  private readonly client = adminApi;
  isLoading = false;
  error: string | null = null;

  constructor(client = adminApi) {
    this.client = client;
    // @ts-expect-error Skip
    makeAutoObservable(this, { client: false }, { autoBind: true });
  }

  get list() {
    return Array.from(this.items.values());
  }

  get isEmpty() {
    return this.items.size === 0;
  }

  getById(id: string | number) {
    return this.items.get(String(id));
  }

  async fetch() {
    this.isLoading = true;
    this.error = null;

    try {
      const payload = await this.client.listServiceCategories();
      runInAction(() => {
        this.hydrate(payload);
        this.isLoading = false;
      });
    } catch (error) {
      runInAction(() => {
        this.error = error instanceof Error ? error.message : 'Failed to load service categories';
        this.isLoading = false;
      });
      throw error;
    }
  }

  private hydrate(payload: AdminServiceCategory[]) {
    payload.forEach((item) => {
      this.upsert(item);
    });
  }

  private upsert(item: AdminServiceCategory) {
    const key = String(item.id);
    const existing = this.items.get(key);

    if (existing) {
      existing.update(item);
      return;
    }

    this.items.set(key, new ServiceCategoryModel(item));
  }
}
