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<ActiveOrganization | null>(null)
  const organizations = ref<Organization[]>([])
  const invitations = ref<Invitation[]>([])

  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<CustomInvitation> {
    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
  }
})
