import { invoke } from '@tauri-apps/api/core' import { useCallback, useEffect, useState } from 'react' import { trackEvent } from '../lib/telemetry' import { isTauri } from '../mock-tauri' type AccountPhase = 'checking' | 'signed-out' | 'code-sent' | 'authenticated' | 'busy' | 'error' type AccountState = { error: string | null expiresAt: number | null lastCommit: string | null phase: AccountPhase requestId: string | null } type NativeAccountStatus = { expires_at?: number state?: 'authenticated' | 'signed_out' } type NativeCodeRequest = { request_id?: string } type NativeKnowledgeReceipt = { commit?: string } const initialState: AccountState = { error: null, expiresAt: null, lastCommit: null, phase: 'checking', requestId: null, } function errorText(error: unknown): string { if (error instanceof Error) return error.message return String(error) } export function useHoloLakeAccount() { const [state, setState] = useState(initialState) const refresh = useCallback(async () => { if (!isTauri()) { setState((current) => ({ ...current, phase: 'signed-out' })) return } try { const status = await invoke('hololake_account_status') setState((current) => ({ ...current, error: null, expiresAt: status.expires_at ?? null, phase: status.state === 'authenticated' ? 'authenticated' : 'signed-out', })) } catch (error) { setState((current) => ({ ...current, error: errorText(error), phase: 'signed-out' })) } }, []) useEffect(() => { void refresh() }, [refresh]) const requestCode = useCallback(async (email: string) => { setState((current) => ({ ...current, error: null, phase: 'busy' })) trackEvent('hololake_account_code_requested', { surface: 'account-panel' }) try { const result = await invoke('hololake_account_request_email_code', { email }) if (!result.request_id) throw new Error('hololake_login_request_id_missing') setState((current) => ({ ...current, phase: 'code-sent', requestId: result.request_id ?? null, })) } catch (error) { setState((current) => ({ ...current, error: errorText(error), phase: 'error' })) } }, []) const verifyCode = useCallback(async (code: string) => { if (!state.requestId) return setState((current) => ({ ...current, error: null, phase: 'busy' })) try { const result = await invoke('hololake_account_verify_email_code', { requestId: state.requestId, code, }) trackEvent('hololake_account_login_completed', { result: 'authenticated' }) setState((current) => ({ ...current, expiresAt: result.expires_at ?? null, phase: 'authenticated', requestId: null, })) } catch (error) { trackEvent('hololake_account_login_completed', { result: 'error' }) setState((current) => ({ ...current, error: errorText(error), phase: 'code-sent' })) } }, [state.requestId]) const syncKnowledge = useCallback(async () => { setState((current) => ({ ...current, error: null, phase: 'busy' })) trackEvent('hololake_knowledge_sync_requested', { repository: 'hololake-knowledge-base' }) try { const result = await invoke('hololake_sync_knowledge') trackEvent('hololake_knowledge_sync_completed', { result: 'success' }) setState((current) => ({ ...current, lastCommit: result.commit ?? null, phase: 'authenticated', })) } catch (error) { trackEvent('hololake_knowledge_sync_completed', { result: 'error' }) setState((current) => ({ ...current, error: errorText(error), phase: 'authenticated' })) } }, []) const logout = useCallback(async () => { setState((current) => ({ ...current, error: null, phase: 'busy' })) try { await invoke('hololake_account_logout') trackEvent('hololake_account_logout_completed') setState(initialState) await refresh() } catch (error) { setState((current) => ({ ...current, error: errorText(error), phase: 'authenticated' })) } }, [refresh]) return { logout, requestCode, state, syncKnowledge, verifyCode, } }