import { create } from 'zustand'
import { createJSONStorage, persist } from 'zustand/middleware'
import type {
  AppSettings,
  HomeShowSettings,
  DetailShowSettings,
  EpisodeShowSettings,
  EpisodeBehaviorSettings,
  EpisodeRecapSettings,
  EndVideoShowSettings,
} from '../api/types'
import { defaultSettings, migrateV1Preferences, migrateV2Preferences } from '../api/types'
import { sensitiveStorage } from '../lib/sensitive-storage'

interface PreferencesState extends AppSettings {
  setPreference: <K extends keyof AppSettings>(key: K, value: AppSettings[K]) => void
  setHomeShow: <K extends keyof HomeShowSettings>(key: K, value: boolean) => void
  setDetailShow: <K extends keyof DetailShowSettings>(key: K, value: boolean) => void
  setEpisodeShow: <K extends keyof EpisodeShowSettings>(key: K, value: boolean) => void
  setEpisodeBehavior: <K extends keyof EpisodeBehaviorSettings>(key: K, value: EpisodeBehaviorSettings[K]) => void
  setEpisodeRecap: <K extends keyof EpisodeRecapSettings>(key: K, value: EpisodeRecapSettings[K]) => void
  setEndVideoShow: <K extends keyof EndVideoShowSettings>(key: K, value: boolean) => void
  resetToDefaults: () => void
}

export const usePreferencesStore = create<PreferencesState>()(
  persist(
    set => ({
      ...defaultSettings,

      setPreference: (key, value) => set({ [key]: value } as Partial<AppSettings>),
      setHomeShow: (key, value) =>
        set(s => ({ home: { show: { ...s.home.show, [key]: value } } })),
      setDetailShow: (key, value) =>
        set(s => ({ detail: { show: { ...s.detail.show, [key]: value } } })),
      setEpisodeShow: (key, value) =>
        set(s => ({ episode: { ...s.episode, show: { ...s.episode.show, [key]: value } } })),
      setEpisodeBehavior: (key, value) =>
        set(s => ({ episode: { ...s.episode, behavior: { ...s.episode.behavior, [key]: value } } })),
      setEpisodeRecap: (key, value) =>
        set(s => ({ episode: { ...s.episode, recap: { ...s.episode.recap, [key]: value } } })),
      setEndVideoShow: (key, value) =>
        set(s => ({ endVideo: { show: { ...s.endVideo.show, [key]: value } } })),
      resetToDefaults: () => set({ ...defaultSettings }),
    }),
    {
      name: 'jf_prefs',
      version: 3,
      storage: createJSONStorage(() => sensitiveStorage),
      migrate: (persistedState, fromVersion) => {
        if (!persistedState || typeof persistedState !== 'object') {
          return persistedState as AppSettings
        }
        if (fromVersion < 2) {
          return migrateV2Preferences(
            migrateV1Preferences(persistedState as Record<string, unknown>) as unknown as Record<string, unknown>,
          )
        }
        if (fromVersion < 3) {
          return migrateV2Preferences(persistedState as Record<string, unknown>)
        }
        return persistedState as AppSettings
      },
    },
  ),
)
