import { useRefresh } from '@/utils';
import { create2DArray } from '@/utils/array';
import { useLocalStorage } from '@vueuse/core';
import { defineStore } from 'pinia';
import { readonly, watch } from 'vue';

export interface Tile {
  id: number;
  number: number;
  removed: boolean;
  fromOthers: boolean;
}

export type GameState = 'playing' | 'succeed' | 'failed';
export const useGame2048Store = defineStore('2048', () => {
  const { key: gameKey, refresh: refreshGame } = useRefresh();

  function create() {
    return create2DArray<Tile[]>(height.value, width.value, () => []);
  }

  function $reset() {
    gameStatus.value = 'playing';
    score.value = 0;
    maxNumber.value = 0;
    rawTileGrid.value = create();
    isInitial.value = true;
    refreshGame();
  }

  const width = useLocalStorage('2048-width', 4);
  const height = useLocalStorage('2048-height', 4);
  const gameStatus = useLocalStorage<GameState>('2048-game-state', 'playing');
  const score = useLocalStorage('2048-score', 0);
  const maxNumber = useLocalStorage('2048-max-number', 0);
  const successNumber = useLocalStorage('2048-success-number', 2048);
  width.value = 4;
  height.value = 4;
  successNumber.value = 2048;
  watch([width, height], $reset, { flush: 'sync' });
  const rawTileGrid = useLocalStorage<Pick<Tile, 'number' | 'removed'>[][][]>(
    '2048-tile-grid',
    create(),
  );
  watch(
    rawTileGrid,
    () => {
      isInitial.value = false;
    },
    { flush: 'sync' },
  );
  const isInitial = useLocalStorage('2048-is-initial', true);
  return {
    width,
    height,
    gameStatus,
    score,
    maxNumber,
    successNumber: readonly(successNumber),
    rawTileGrid,
    isInitial,
    gameKey,
    $reset,
  };
});
