import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
import { jwtDecode } from 'jwt-decode'

export interface JwtPayload {
  sub: string
  role: string
  rank: number
  scope_level: string
  region_code?: string
  scope_id?: number
  exp: number
  iat: number
}

export interface User {
  id: string
  email: string
  role: string
  rank: number
  scope_level: string
  region_code?: string
  scope_id?: number
  permissions: string[]
}

export const useAuthStore = defineStore('auth', () => {
  // State
  const token = ref<string | null>(null)
  const user = ref<User | null>(null)
  const isAuthenticated = computed(() => !!token.value && !isTokenExpired())
  const isLoading = ref(false)
  const error = ref<string | null>(null)

  // Initialize token from localStorage only on client side
  if (typeof window !== 'undefined') {
    token.value = localStorage.getItem('admin_token')
  }

  // Getters
  const getUserRole = computed(() => user.value?.role || '')
  const getUserRank = computed(() => user.value?.rank || 0)
  const getScopeLevel = computed(() => user.value?.scope_level || '')
  const getRegionCode = computed(() => user.value?.region_code || '')
  const getScopeId = computed(() => user.value?.scope_id || 0)
  const getPermissions = computed(() => user.value?.permissions || [])

  // Check if token is expired
  function isTokenExpired(): boolean {
    if (!token.value) return true
    try {
      const decoded = jwtDecode<JwtPayload>(token.value)
      return Date.now() >= decoded.exp * 1000
    } catch {
      return true
    }
  }

  // Parse token and set user
  function parseToken(): void {
    if (!token.value) {
      user.value = null
      return
    }

    try {
      const decoded = jwtDecode<JwtPayload>(token.value)
      
      // Map JWT claims to user object
      user.value = {
        id: decoded.sub,
        email: decoded.sub, // Assuming sub is email
        role: decoded.role,
        rank: decoded.rank,
        scope_level: decoded.scope_level,
        region_code: decoded.region_code,
        scope_id: decoded.scope_id,
        permissions: generatePermissions(decoded.role, decoded.rank)
      }
      
      error.value = null
    } catch (err) {
      console.error('Failed to parse token:', err)
      error.value = 'Invalid token format'
      user.value = null
      // Clear invalid token from storage
      token.value = null
      if (typeof window !== 'undefined') {
        localStorage.removeItem('admin_token')
      }
    }
  }

  // Generate permissions based on role and rank
  function generatePermissions(role: string, rank: number): string[] {
    const permissions: string[] = []
    
    // Base permissions based on role
    switch (role) {
      case 'superadmin':
        permissions.push('*')
        break
      case 'admin':
        permissions.push('view:dashboard', 'manage:users', 'manage:services', 'view:finance')
        if (rank >= 5) permissions.push('manage:settings')
        break
      case 'moderator':
        permissions.push('view:dashboard', 'moderate:services', 'view:users')
        break
      case 'salesperson':
        permissions.push('view:dashboard', 'view:sales', 'manage:leads')
        break
    }
    
    // Add geographical scope permissions
    permissions.push(`scope:${role}`)
    
    return permissions
  }

  // Check if user has permission
  function hasPermission(permission: string): boolean {
    if (!user.value) return false
    if (user.value.permissions.includes('*')) return true
    return user.value.permissions.includes(permission)
  }

  // Check if user has required role rank
  function hasRank(minRank: number): boolean {
    return user.value?.rank >= minRank
  }

  // Check if user can access scope
  function canAccessScope(requestedScopeId: number, requestedRegionCode?: string): boolean {
    if (!user.value) return false
    
    // Superadmin can access everything
    if (user.value.role === 'superadmin') return true
    
    // Check scope_id match
    if (user.value.scope_id && user.value.scope_id === requestedScopeId) return true
    
    // Check region_code match
    if (user.value.region_code && requestedRegionCode) {
      return user.value.region_code === requestedRegionCode
    }
    
    return false
  }

  // Login action - REAL API AUTHENTICATION ONLY
  async function login(email: string, password: string): Promise<boolean> {
    isLoading.value = true
    error.value = null
    
    try {
      // Debug: Log what we're sending
      console.log('Auth store: Attempting login for', email)
      console.log('Auth store: Password length', password.length)
      
      // Prepare URL-encoded form data for OAuth2 password grant (as per FastAPI auth endpoint)
      // FastAPI's OAuth2PasswordRequestForm expects application/x-www-form-urlencoded
      // Use explicit string encoding to guarantee FastAPI accepts it (Nuxt's $fetch messes up URLSearchParams)
      const bodyString = `username=${encodeURIComponent(email)}&password=${encodeURIComponent(password)}`;
      
      console.log('Auth store: Body string created', bodyString)
      
      // Call real backend login endpoint using $fetch (Nuxt's fetch)
      // $fetch automatically throws on non-2xx responses, so we just need to catch
      const data = await $fetch('/api/v1/auth/login', {
        method: 'POST',
        headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
        body: bodyString
      })
      
      console.log('Auth login API response:', data)
      
      // Extract token
      const accessToken = data.access_token
      if (!accessToken) {
        throw new Error('No access token in response')
      }
      
      // Store token safely (SSR-safe)
      if (typeof window !== 'undefined') {
        localStorage.setItem('admin_token', accessToken)
      }
      token.value = accessToken
      parseToken()
      
      return true
    } catch (err) {
      console.error('Auth store: Login catch block error:', err)
      error.value = err instanceof Error ? err.message : 'Login failed'
      return false
    } finally {
      isLoading.value = false
    }
  }

  // Logout action
  function logout(): void {
    token.value = null
    user.value = null
    if (typeof window !== 'undefined') {
      localStorage.removeItem('admin_token')
    }
  }

  // Initialize store
  if (token.value) {
    parseToken()
  }

  return {
    // State
    token,
    user,
    isAuthenticated,
    isLoading,
    error,
    
    // Getters
    getUserRole,
    getUserRank,
    getScopeLevel,
    getRegionCode,
    getScopeId,
    getPermissions,
    
    // Actions
    login,
    logout,
    hasPermission,
    hasRank,
    canAccessScope,
    parseToken
  }
})