import { z } from "zod/mini";
import type * as THREE from "three";

export const LOGICAL_WIDTH = 256;
export const LOGICAL_HEIGHT = 192;

export const SCREEN_SCALE = 2;

export const SCREEN_WIDTH = LOGICAL_WIDTH * SCREEN_SCALE;
export const SCREEN_HEIGHT = LOGICAL_HEIGHT * SCREEN_SCALE;

export const APP_COLORS = [
  ["#61829a", "#ba4900", "#fb0018", "#fb8afb"],
  ["#fb9200", "#f3e300", "#aafb00", "#00fb00"],
  ["#00a238", "#49db8a", "#30baf3", "#0059f3"],
  ["#000092", "#8a00d3", "#d300eb", "#fb0092"],
];

const STORAGE_ID = "app_settings";

const settingsSchema = z.object({
  color: z.object({
    col: z.number(),
    row: z.number(),
  }),
  renderingMode: z.enum(["3d", "2d"]),
});

type Settings = z.infer<typeof settingsSchema>;

const defaultSettings = (): Settings => ({
  color: { col: 0, row: 0 },
  renderingMode: "3d",
});

export const useAppStore = defineStore("app", {
  state: () => {
    let settings: Settings;
    const stored = localStorage.getItem(STORAGE_ID);
    try {
      settings = settingsSchema.parse(JSON.parse(stored ?? ""));
    } catch {
      settings = defaultSettings();
    }

    return {
      ready: false,
      booted: true,
      settings,
      previousScreen: "home" as AppScreen,
      screen: "home" as AppScreen,
      camera: null as THREE.Camera | null,
    };
  },

  actions: {
    setColor(col: number, row: number) {
      this.settings.color = { col, row };
    },

    setRenderingMode(mode: Settings["renderingMode"]) {
      this.ready = mode === "2d";
      this.settings.renderingMode = mode;
      this.save();
    },

    navigateTo(screen: AppScreen) {
      this.previousScreen = this.screen;
      this.screen = screen;

      const achievements = useAchievementsStore();

      switch (screen) {
        case "projects":
          achievements.unlock("projects_visit");
          break;

        case "gallery":
          achievements.unlock("gallery_visit");
          break;

        case "contact":
          achievements.unlock("contact_visit");
          break;
      }
    },

    setCamera(camera: THREE.Camera) {
      this.camera = camera;
    },

    save() {
      localStorage.setItem(STORAGE_ID, JSON.stringify(this.settings));
    },
  },

  getters: {
    color: (state) => ({
      col: state.settings.color.col,
      row: state.settings.color.row,
      hex: APP_COLORS[state.settings.color.row]![state.settings.color.col]!,
    }),
  },
});
