import { Howler } from "howler";
import { type StateCreator } from "zustand";

import { type BannerData, Theme } from "@/types";

/**
 * Audio Slice
 * ===================================================================
 */

export interface AudioSlice {
  activeAudioEl: HTMLAudioElement | null;
  setActiveAudioEl: (audioEl: HTMLAudioElement | null) => void;
  isMuted: boolean;
  setIsMuted: (isMuted: boolean) => void;
  audioAllowed: boolean;
  setAudioAllowed: (audioAllowed: boolean) => void;
}

export const createAudioSlice: StateCreator<AudioSlice> = (set) => ({
  activeAudioEl: null,
  setActiveAudioEl: (audioEl: HTMLAudioElement | null) => {
    set((state) => {
      if (state.activeAudioEl?.id === audioEl?.id) return state;

      if (state.activeAudioEl && !state.activeAudioEl.paused) {
        state.activeAudioEl.pause();
      }

      return { activeAudioEl: audioEl };
    });
  },
  isMuted: true,
  setIsMuted: (isMuted) => {
    Howler.mute(isMuted);
    set({ isMuted });
  },
  audioAllowed: false,
  setAudioAllowed: (audioAllowed) => {
    if (!audioAllowed) Howler.stop();
    set({ audioAllowed });
  },
});

/**
 * Debug Slice
 * ===================================================================
 */

export interface DebugSlice {
  showDebugClass: boolean;
  setShowDebugClass: (showDebugClass: boolean) => void;
  showDebugMessage: boolean;
  setShowDebugMessage: (showDebugMessage: boolean) => void;
  showAxis: boolean;
  setShowAxis: (showAxis: boolean) => void;
  showStats: boolean;
  setShowStats: (showStats: boolean) => void;
}

export const createDebugSlice: StateCreator<DebugSlice> = (set) => ({
  showDebugClass: false,
  setShowDebugClass: (showDebugClass) => set({ showDebugClass }),
  showDebugMessage: false,
  setShowDebugMessage: (showDebugMessage) => set({ showDebugMessage }),
  showAxis: false,
  setShowAxis: (showAxis) => set({ showAxis }),
  showStats: false,
  setShowStats: (showStats) => set({ showStats }),
});

/**
 * Layout Slice
 * ===================================================================
 */

export interface LayoutSlice {
  currentTheme: Theme;
  setCurrentTheme: (currentTheme?: Theme) => void;
  currentSectionId: string | null;
  setCurrentSectionId: (currentSectionId: string | null) => void;
  sectionThemes: Map<string, Theme>;
  updateSectionThemes: (id: string, theme: Theme) => void;
  sectionHeights: Map<string, number>;
  updateSectionHeights: (id: string, element: number) => void;
  sectionRefs: Map<string, HTMLElement | null>;
  updateSectionRefs: (id: string, element: HTMLElement | null) => void;
  banner: BannerData | undefined;
  setBanner: (banners: BannerData | undefined) => void;
}

export const createLayoutSlice: StateCreator<LayoutSlice> = (set) => ({
  currentTheme: Theme.Dark,
  setCurrentTheme: (currentTheme: Theme = Theme.Dark) => set({ currentTheme }),
  currentSectionId: null,
  setCurrentSectionId: (currentSectionId) => set({ currentSectionId }),
  sectionThemes: new Map(),
  updateSectionThemes: (id, theme) =>
    set((state) => {
      const updatedMap = new Map(state.sectionThemes);
      updatedMap.set(id, theme);
      return { sectionThemes: updatedMap };
    }),
  sectionHeights: new Map(),
  updateSectionHeights: (id, progress = 0) =>
    set((state) => {
      const updatedMap = new Map(state.sectionHeights);
      updatedMap.set(id, progress);
      return {
        sectionHeights: updatedMap,
      };
    }),
  sectionRefs: new Map(),
  updateSectionRefs: (id, ref = null) =>
    set((state) => {
      const updatedMap = new Map(state.sectionRefs);
      updatedMap.set(id, ref);
      return { sectionRefs: updatedMap };
    }),
  banner: undefined,
  setBanner: (banner) => set({ banner }),
});
