import type { AuthState } from '@/contracts'
import type { UserState } from '@/contracts/state/auth.ts'
import { defineStore } from 'pinia'

export const useAuthStore = defineStore('user',
  {
    state: (): AuthState => ({
      user: null,
      token: null,
    }),
    getters: {
      isAuthenticated: state => !!state.token,
      getUser: state => state.user,
      getToken: state => state.token,
    },
    actions: {
      setAuth (auth: AuthState) {
        this.user = auth.user
        this.token = auth.token
        localStorage.setItem('token', auth.token || '')
        localStorage.setItem('user', JSON.stringify(auth.user))
      },
      setUser (user: UserState) {
        this.user = user
        localStorage.setItem('user', JSON.stringify(user))
      },
      restoreAuth () {
        const token = localStorage.getItem('token')
        const user = localStorage.getItem('user')
        if (token && user) {
          this.token = token
          this.user = JSON.parse(user)
        }
      },
      logout () {
        this.$reset()
        localStorage.removeItem('token')
        localStorage.removeItem('user')
      },
      can (permission: string): boolean {
        return this.user?.role.name === 'super_admin' || (this.user?.role.permissions || []).includes(permission)
      },
      canAny (permissions: string[]): boolean {
        if (this.user?.role.name === 'super_admin') {
          return true
        } else {
          let hasAccess = false
          const userPermissions: string[] = this.user?.role.permissions || []
          for (const permission of permissions) {
            if (userPermissions.includes(permission)) {
              hasAccess = true
              break
            }
          }
          return hasAccess
        }
      },
      hasPermission (permission?: string[] | string): boolean {
        if (typeof permission === 'string') {
          return this.can(permission)
        } else if (Array.isArray(permission)) {
          return this.canAny(permission)
        }
        return false
      },
      hasAnyRoles (roles: string[]): boolean {
        let hasAccess = false
        for (const role of roles) {
          if (this.user?.role.name === role) {
            hasAccess = true
            break
          }
        }
        return hasAccess
      },
      hasRole (role?: string[] | string): boolean {
        if (typeof role === 'string') {
          return this.user?.role.name === role
        } else if (Array.isArray(role)) {
          return this.hasAnyRoles(role)
        }
        return false
      },
    },
  })
