import type { ActiveOrganization, Organization, Invitation } from '~/composables/useAuth' import { useOrganizationApi } from '~/composables/organization/useOrganizationApi' import type { LegalRole } from '~/server/utils/permissions' export const useOrganizationStore = defineStore('Organization', () => { const activeOrganization = ref(null) const organizations = ref([]) const invitations = ref([]) const organizationApi = useOrganizationApi() const toast = useToast() async function createOrganization(name: string, slug: string, logo?: string) { try { const { data: slugCheck } = await organizationApi.checkSlugAvailability(slug) if (!slugCheck?.status) { toast.add({ title: 'Slug already taken', description: 'Please choose a different slug', color: 'error' }) return Promise.reject() } const { data: createdOrganization } = await organizationApi.createOrganization(name, slug, logo) if (createdOrganization) { organizations.value.push(createdOrganization) toast.add({ title: 'Organization created successfully', color: 'success' }) if (createdOrganization.id) { await setActiveOrganization(createdOrganization.id) } return createdOrganization } } catch (e) { toast.add({ title: 'Error creating organization', color: 'error' }) console.error('Error creating organization:', e) } } async function deleteOrganization(organizationId?: string) { try { const idToDelete = organizationId ?? activeOrganization.value?.id if (!idToDelete) { throw Error(`No organization is selected for deletion`) } await organizationApi.deleteOrganization(idToDelete) organizations.value = organizations.value.filter((org) => org.id !== organizationId) toast.add({ title: 'Organization deleted successfully', color: 'success' }) } catch (e) { toast.add({ title: 'Error deleting organization', color: 'error' }) console.error('Error deleting organization:', e) } } async function getInvitation(invitationId: string): Promise { try { const { data: invitation } = await organizationApi.getInvitation(invitationId) return invitation } catch (e) { console.error('Error getInvitation:', e) return null } } async function loadInvitations(organizationId?: string) { try { const { data: loadedInvitations } = await organizationApi.listInvitations(organizationId) if (loadedInvitations) { invitations.value = loadedInvitations } } catch (e) { toast.add({ title: 'Error loading invitations', color: 'error' }) console.error('Error loading invitations:', e) } } async function inviteMember(email: string, role: LegalRole) { try { await organizationApi.inviteMember(email, role) await loadInvitations() toast.add({ title: 'Member invited successfully', color: 'success' }) } catch (e) { toast.add({ title: 'Error inviting member', color: 'error' }) console.error('Error inviting member:', e) } } async function acceptInvitation(invitationId: string) { try { await organizationApi.acceptInvitation(invitationId) await navigateTo('/') await syncUserRoleToBackend() } catch (e) { toast.add({ title: 'Error accepting invitation', color: 'error' }) console.error('Error accepting invitation:', e) } } async function syncUserRoleToBackend() { try { const { updateUser } = useUser() const { user } = useAuth() if (!user.value?.id) { console.warn('No user ID available for role sync') return } // Call updateUser without userDto to trigger JWT-based sync await updateUser(user.value.id) console.log('Successfully synced user role to backend from JWT') } catch (error) { console.error('Failed to sync user role to backend from JWT:', error) // Don't throw - role sync failure shouldn't prevent invitation acceptance } } async function cancelSentInvitation(invitationId: string) { try { await organizationApi.cancelSentInvitation(invitationId) invitations.value = invitations.value.filter((invitation) => invitation.id !== invitationId) } catch (e) { toast.add({ title: 'Error rejecting invitation', color: 'error' }) console.error('Error rejecting invitation:', e) } } async function rejectInvitation(invitationId: string) { try { await organizationApi.rejectInvitation(invitationId) invitations.value = invitations.value.filter((invitation) => invitation.id !== invitationId) } catch (e) { toast.add({ title: 'Error rejecting invitation', color: 'error' }) console.error('Error rejecting invitation:', e) } } async function loadOrganizations() { try { const { data: loadedOrganizations } = await organizationApi.loadOrganizations() if (loadedOrganizations) { organizations.value = loadedOrganizations } } catch (e) { toast.add({ title: 'Error loading organizations', color: 'error' }) console.error('Error loading organizations:', e) } } async function setActiveOrganization(organizationId: string) { try { const { data: activeOrganizationToSet } = await organizationApi.setActiveOrganization(organizationId) activeOrganization.value = activeOrganizationToSet const { data: invitationsToSet } = await organizationApi.listInvitations(activeOrganizationToSet?.id) invitations.value = invitationsToSet ?? [] } catch (e) { toast.add({ title: 'Error setting active organizations', color: 'error' }) console.error('Error setting active organizations:', e) } } return { activeOrganization, organizations, createOrganization, deleteOrganization, invitations, getInvitation, loadInvitations, inviteMember, acceptInvitation, rejectInvitation, cancelSentInvitation, loadOrganizations, setActiveOrganization } })