import { defineStore, getActivePinia } from 'pinia'
import type { MiniUserProfile } from '@/types/auth'

export const MINI_AUTH_STORAGE_KEY = 'miniAuth'

export interface MiniAuthState {
  token: string
  profile: MiniUserProfile | null
}

function createInitialState(): MiniAuthState {
  return {
    token: '',
    profile: null,
  }
}

function isValidProfile(value: unknown): value is MiniUserProfile {
  if (!value || typeof value !== 'object') {
    return false
  }
  return typeof (value as MiniUserProfile).mpUserId === 'number'
}

export function getPersistedAuthState(): MiniAuthState {
  const state = uni.getStorageSync(MINI_AUTH_STORAGE_KEY) as Partial<MiniAuthState> | undefined
  return {
    token: typeof state?.token === 'string' ? state.token : '',
    profile: isValidProfile(state?.profile) ? state.profile : null,
  }
}

export function getPersistedToken(): string {
  return getPersistedAuthState().token
}

function writePersistedAuthState(state: MiniAuthState) {
  uni.setStorageSync(MINI_AUTH_STORAGE_KEY, state)
}

function patchActiveStore(state: MiniAuthState) {
  const pinia = getActivePinia()
  if (!pinia) {
    return
  }
  const store = useMiniAuthStore(pinia)
  store.$patch(state)
}

export function clearMiniAuthSession() {
  const state = createInitialState()
  uni.removeStorageSync(MINI_AUTH_STORAGE_KEY)
  patchActiveStore(state)
}

export function updateMiniAuthProfile(profile: MiniUserProfile) {
  const state = {
    ...getPersistedAuthState(),
    profile,
  }
  writePersistedAuthState(state)
  patchActiveStore(state)
}

export const useMiniAuthStore = defineStore('miniAuth', {
  state: (): MiniAuthState => createInitialState(),
  getters: {
    isLoggedIn: state => Boolean(state.token),
  },
  actions: {
    setSession(payload: MiniAuthState) {
      this.token = payload.token
      this.profile = payload.profile
      writePersistedAuthState({
        token: payload.token,
        profile: payload.profile,
      })
    },
    setProfile(profile: MiniUserProfile) {
      this.profile = profile
      writePersistedAuthState({
        token: this.token,
        profile,
      })
    },
    clearSession() {
      this.token = ''
      this.profile = null
      uni.removeStorageSync(MINI_AUTH_STORAGE_KEY)
    },
    restoreSession() {
      const state = getPersistedAuthState()
      this.token = state.token
      this.profile = state.profile
      return state
    },
  },
})
