import { Clip } from '@/state/clipStore';

import { RootStore, Substore } from './rootStore';
import { makeAutoObservableSubstore } from './utils';

export class TrashStore implements Substore {
  clipIds: string[] = [];
  numTotalClips = 0;
  isLoaded = false;

  filters = {
    liked: false,
    public: false,
    page: 0,
  };

  trashedClipIndices = new Map();

  readonly root: RootStore;
  get apiClient() {
    return this.root.apiClient;
  }
  // DO NOT ADD INIT LOGIC IN constructor. this will run on every page! considering adding any it in the component init logic instead
  constructor(root: RootStore) {
    this.root = root;
    makeAutoObservableSubstore(this);
  }

  setInitialClips = (clips: Clip[]) => {
    this.clipIds = clips.map((clip) => clip.id);
    this.root.clips.updateClips(clips);
    this.isLoaded = true;

    this.updateFilters({});
  };

  updateFilters = (filters: any) => {
    if (typeof filters.page === 'undefined') {
      this.filters.page = 0;
    }

    this.filters = { ...this.filters, ...filters };
    this.loadClips();
  };

  incrementPage = (offset: number) => {
    this.updateFilters({ page: Math.max(0, this.filters.page + offset) });
  };

  setPageNumber = (newPageNumber: number) => {
    this.updateFilters({ page: newPageNumber });
  };

  loadClips = async (num_pages?: number) => {
    const filtersKey = JSON.stringify(this.filters);
    const { data } = await this.apiClient.GET('/api/clips/trashed_v2', {
      params: {
        query: {
          ...(this.filters.liked ? { is_liked: true } : {}),
          ...(this.filters.public ? { is_public: true } : {}),
          page: this.filters.page,
          page_size: num_pages,
        },
      },
    });

    if (!data) return;

    this.root.clips.updateClips(data.clips);
    this.isLoaded = true;
    this.numTotalClips = data.num_total_results;

    if (filtersKey !== JSON.stringify(this.filters)) return;
    this.clipIds = data.clips.map((clip) => clip.id);
  };

  get currentClips() {
    if (!this.isLoaded) return null;
    return this.clipIds.map((id) => this.root.clips.clipById[id]);
  }

  removeFromTrash = (clipId: string) => {
    const index = this.clipIds.indexOf(clipId);
    if (index !== -1) {
      this.trashedClipIndices.set(clipId, index);
      this.clipIds.splice(index, 1);
    }
  };

  addToTrash = (clipId: string) => {
    if (!this.clipIds.includes(clipId)) {
      const index = this.trashedClipIndices.get(clipId);
      if (typeof index === 'number') {
        this.clipIds.splice(index, 0, clipId);
        this.trashedClipIndices.delete(clipId);
      } else {
        this.clipIds.push(clipId);
      }
    }
  };
}
