import type { UsersRecord } from '~/types/pocketbase.types'

export const useUser = defineStore('user', {
  state: () => ({
    user: null as UsersRecord | null
  }),
  getters: {
    isAuthenticated() {
      const { authStore } = usePocketBase()
      return authStore.value.isValid && authStore.value.record !== null
    },
    userId() {
      const { authStore } = usePocketBase()
      return authStore.value.record?.id
    }
  },
  actions: {
    /**
     * Signs in a user with email (sends OTP)
     * @param email The email address of the user
     * @returns The OTP ID needed for authenticating with the received OTP
     */
    async signInWithEmail(email: string, language?: string) {
      const { pb } = usePocketBase()
      const req = await pb.collection('users').requestOTP(email, {
        headers: {
          language: language ?? 'en'
        }
      })
      return req.otpId
    },
    /**
     * Signs in a user with OTP
     * @param otpId The OTP ID from the email OTP request
     * @param otp The OTP code sent to the user's email
     */
    async signInWithOtp(otpId: string, otp: string) {
      const { pb } = usePocketBase()
      await pb.collection('users').authWithOTP(otpId, otp)
    },
    /**
     * Signs in a user with OAuth provider
     * @param provider The OAuth provider to use
     */
    async signInWithOAuth(provider: 'apple' | 'google') {
      const { pb } = usePocketBase()
      await pb.collection('users').authWithOAuth2({
        provider
      })
    },
    /**
     * Refreshes the auth store for the current user
     */
    async authRefresh() {
      try {
        const { pb } = usePocketBase()
        await pb.collection('users').authRefresh()
        await this.fetchUser()
      } catch (error) {
        console.debug('User not authenticated', error)
      }
    },
    /**
     * Signs out the current user
     */
    signOut() {
      const { pb } = usePocketBase()
      pb.authStore.clear()
      this.user = null
    },
    /**
     * Fetches all data of the currently authenticated user
     */
    async fetchUser() {
      if (this.isAuthenticated) {
        const { pb } = usePocketBase()
        this.user = await pb.collection('users').getOne(this.userId!)
      } else {
        console.warn('Fetch user failed: user is not authenticated')
      }
    },
    /**
     * Updates the given fields of the current user
     */
    async updateUser(data: Partial<UsersRecord>) {
      if (this.isAuthenticated) {
        const { pb } = usePocketBase()
        this.user = await pb.collection('users').update(this.userId!, data)
      } else {
        console.warn('Update user failed: user is not authenticated')
      }
    },
    /**
     * Deletes the current user's account
     */
    async deleteUser() {
      if (this.isAuthenticated) {
        const { pb } = usePocketBase()
        await pb.collection('users').delete(this.userId!)
        this.signOut()
      } else {
        console.warn('Delete user failed: user is not authenticated')
      }
    }
  }
})
