import type { SceneDarknessEvent, SceneDarknessRevealStroke, SceneDarknessState } from '../../shared/types';

function emptyState(): SceneDarknessState {
  return {
    revision: 1,
    enabled: false,
    cacheKey: null,
    strokes: [],
    draft: null,
  };
}

export class SceneDarknessStore {
  private state: SceneDarknessState = emptyState();
  /** Кэш раскрытых областей по ключу (graphNodeId или sceneId) на время сессии показа. */
  private cache = new Map<string, SceneDarknessRevealStroke[]>();
  private currentKey: string | null = null;

  getState(): SceneDarknessState {
    return { ...this.state, strokes: [...this.state.strokes] };
  }

  /** Сброс кэша при новом запуске показа (кнопка «Запустить»). */
  resetSession(): void {
    this.cache.clear();
    this.currentKey = null;
    this.state = emptyState();
  }

  /**
   * Переключение сцены: сохраняем текущие штрихи в кэш и загружаем состояние новой сцены.
   */
  switchScene(cacheKey: string | null, enabled: boolean): SceneDarknessState {
    if (this.currentKey !== null) {
      this.cache.set(this.currentKey, [...this.state.strokes]);
    }
    this.currentKey = cacheKey;
    const strokes =
      cacheKey && enabled ? [...(this.cache.get(cacheKey) ?? [])] : [];
    this.state = {
      revision: this.state.revision + 1,
      enabled,
      cacheKey,
      strokes,
      draft: null,
    };
    return this.getState();
  }

  dispatch(event: SceneDarknessEvent): SceneDarknessState {
    if (!this.state.enabled) return this.getState();
    switch (event.kind) {
      case 'draft.set':
        this.state = {
          ...this.state,
          revision: this.state.revision + 1,
          draft: event.draft,
        };
        return this.getState();
      case 'stroke.add': {
        const strokes = [...this.state.strokes, event.stroke];
        if (this.currentKey) {
          this.cache.set(this.currentKey, strokes);
        }
        this.state = {
          ...this.state,
          revision: this.state.revision + 1,
          strokes,
          draft: null,
        };
        return this.getState();
      }
      default: {
        // eslint-disable-next-line @typescript-eslint/no-unused-vars
        const _x: never = event;
        return this.getState();
      }
    }
  }
}
