import { makeAutoObservable } from "mobx";

export interface ModelLoadingState {
  isLoading: boolean;
  progress: number;
  modelId: string | null;
  error?: string;
  startTime?: number;
}

class ModelLoadingStore {
  private loadingStates: Map<string, ModelLoadingState> = new Map();

  constructor() {
    makeAutoObservable(this);
  }

  startLoading(modelId: string) {
    this.loadingStates.set(modelId, {
      isLoading: true,
      progress: 0,
      modelId,
      startTime: Date.now(),
    });
  }

  updateProgress(modelId: string, progress: number) {
    const state = this.loadingStates.get(modelId);
    if (state) {
      state.progress = Math.min(100, Math.max(0, progress));
    }
  }

  finishLoading(modelId: string) {
    const state = this.loadingStates.get(modelId);
    if (state) {
      state.isLoading = false;
      state.progress = 100;
    }
  }

  stopLoading(modelId: string) {
    this.loadingStates.delete(modelId);
  }

  handleError(modelId: string, error?: string) {
    const state = this.loadingStates.get(modelId);
    if (state) {
      state.isLoading = false;
      state.error = error || "Ошибка загрузки модели";
    }
  }

  getLoadingState(modelId: string): ModelLoadingState | undefined {
    return this.loadingStates.get(modelId);
  }

  get isAnyModelLoading(): boolean {
    return Array.from(this.loadingStates.values()).some(
      (state) => state.isLoading
    );
  }

  get loadingModels(): ModelLoadingState[] {
    return Array.from(this.loadingStates.values()).filter(
      (state) => state.isLoading
    );
  }

  get overallProgress(): number {
    const loadingModels = this.loadingModels;
    if (loadingModels.length === 0) return 100;

    const totalProgress = loadingModels.reduce(
      (sum, model) => sum + model.progress,
      0
    );
    return Math.round(totalProgress / loadingModels.length);
  }

  get isSaveBlocked(): boolean {
    return this.isAnyModelLoading;
  }

  clearAll() {
    this.loadingStates.clear();
  }
}

export const modelLoadingStore = new ModelLoadingStore();
