/**
 * useActiveRole Composable
 *
 * Client-side state management for user's active role (RoleSwitcher)
 *
 * Features:
 * - Reactive active role state
 * - List of all roles with approval status
 * - Switch role function with server validation
 * - Admin change notification flag
 *
 * Usage:
 * ```vue
 * const { activeRole, roles, roleChangedByAdmin, switchRole, fetchRoleStatus } = useActiveRole()
 *
 * // Fetch current status (validates server-side)
 * await fetchRoleStatus()
 *
 * // Switch role
 * await switchRole('educator')
 * ```
 */

export interface RoleWithStatus {
  code: string
  displayName: string
  description: string
  hasRole: boolean
  requiresApproval: boolean
}

export function useActiveRole() {
  // Use useState for shared state across the app
  const activeRole = useState<string>('activeRole', () => 'private')
  const roles = useState<RoleWithStatus[]>('roles', () => [])
  const roleChangedByAdmin = useState<boolean>('roleChangedByAdmin', () => false)
  const loading = useState<boolean>('roleLoading', () => false)
  const error = useState<string | null>('roleError', () => null)

  /**
   * Fetch current role status from server
   * - Validates active role (TTL-based)
   * - Fetches all roles with approval status
   * - Detects if admin changed user's roles
   */
  async function fetchRoleStatus() {
    loading.value = true
    error.value = null

    try {
      const data = await $fetch('/api/user/role-status')

      activeRole.value = data.activeRoleCode
      roles.value = data.roles
      roleChangedByAdmin.value = data.roleChangedByAdmin

      return data
    } catch (err: any) {
      // 401 during session initialization is normal - watch() will retry successfully
      if (err.statusCode === 401) {
        console.debug('Role status fetch: Session not ready yet, will retry via watch()')
        return null
      }

      // Other errors are real problems
      console.error('Failed to fetch role status:', err)
      error.value = 'Fehler beim Laden der Rollen'
      throw err
    } finally {
      loading.value = false
    }
  }

  /**
   * Switch to a different role
   * - Validates server-side that user has the role
   * - Updates session + database
   * - Refreshes products list if on products page
   *
   * @param roleCode - Role to switch to ('private', 'educator', 'company')
   * @throws Error if user doesn't have the role or if switch fails
   */
  async function switchRole(roleCode: string) {
    loading.value = true
    error.value = null

    try {
      await $fetch('/api/user/active-role', {
        method: 'PATCH',
        body: { roleCode },
      })

      // Update local state
      activeRole.value = roleCode
      roleChangedByAdmin.value = false

      // Refresh all product list pages (role-based visibility)
      // Note: Product detail pages will handle visibility via API 404 check
      await Promise.all([
        refreshNuxtData('products-list'), // Main products page
        refreshNuxtData('educator-products'), // Educator products page
        refreshNuxtData('experimenta-products'), // Experimenta products page
      ])

      return true
    } catch (err: any) {
      console.error('Failed to switch role:', err)
      error.value = err.data?.message || 'Fehler beim Wechseln der Rolle'
      throw err
    } finally {
      loading.value = false
    }
  }

  /**
   * Reset all role state (called on logout)
   */
  function resetRoles() {
    activeRole.value = 'private'
    roles.value = []
    roleChangedByAdmin.value = false
    loading.value = false
    error.value = null
  }

  /**
   * Get roles that user actually has (approved only)
   */
  const approvedRoles = computed(() => roles.value.filter((r) => r.hasRole))

  /**
   * Check if user has multiple roles
   */
  const hasMultipleRoles = computed(() => approvedRoles.value.length > 1)

  /**
   * Auto-fetch roles when user logs in
   * This ensures the role button shows the correct role immediately after login
   */
  const { loggedIn } = useUserSession()

  // Initial fetch if already logged in
  if (loggedIn.value) {
    callOnce('init-roles', () => fetchRoleStatus())
  }

  // Watch for login changes - fetch roles when user logs in
  watch(loggedIn, (newLoggedIn) => {
    if (newLoggedIn) {
      fetchRoleStatus()
    }
  })

  return {
    // State (useState already returns writable refs)
    activeRole,
    roles,
    approvedRoles,
    hasMultipleRoles,
    roleChangedByAdmin,
    loading,
    error,

    // Actions
    fetchRoleStatus,
    switchRole,
    resetRoles,
  }
}
