import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
import { post, get } from '../api/client'
import type { User, LoginRequest, LoginResponse, UserProfileResponse } from '../types'
import router from '../router'

export function getDefaultRouteForRole(role: string): string {
  switch (role) {
    case 'INTAKE_CLERK':
      return '/intake'
    case 'DATA_ENTRY_CLERK':
      return '/entry'
    case 'VERIFIER':
      return '/verification'
    case 'CLINICAL_APPROVER':
      return '/approval'
    case 'CLINICIAN':
      return '/live-capture'
    case 'ADMINISTRATOR':
      return '/dashboard'
    default:
      return '/login'
  }
}

export const useAuthStore = defineStore('auth', () => {
  const token = ref<string | null>(localStorage.getItem('vigilcare_token'))
  const refreshToken = ref<string | null>(localStorage.getItem('vigilcare_refresh_token'))
  const user = ref<User | null>(
    JSON.parse(localStorage.getItem('vigilcare_user') || 'null')
  )

  const isAuthenticated = computed(() => !!token.value)
  const userRole = computed(() => user.value?.role ?? '')
  const userId = computed(() => user.value?.id ?? '')
  const userFullName = computed(() => user.value?.fullName ?? '')

  // Role-based view access
  const canIntake = computed(() =>
    ['INTAKE_CLERK', 'ADMINISTRATOR'].includes(userRole.value)
  )
  const canEntry = computed(() =>
    ['DATA_ENTRY_CLERK', 'ADMINISTRATOR'].includes(userRole.value)
  )
  const canVerify = computed(() =>
    ['VERIFIER', 'CLINICAL_APPROVER', 'ADMINISTRATOR'].includes(userRole.value)
  )
  const canApprove = computed(() =>
    ['CLINICAL_APPROVER', 'ADMINISTRATOR'].includes(userRole.value)
  )
  const canLiveCapture = computed(() =>
    ['CLINICIAN', 'ADMINISTRATOR'].includes(userRole.value)
  )
  const canSupervise = computed(() =>
    ['ADMINISTRATOR'].includes(userRole.value)
  )

  async function login(credentials: LoginRequest): Promise<void> {
    const response = await post<LoginResponse>('auth/login', credentials)

    if (!response.success || !response.data) {
      throw new Error(response.error?.message ?? 'Login failed')
    }

    const loginData = response.data

    token.value = loginData.token
    refreshToken.value = loginData.refreshToken
    user.value = {
      id: loginData.userId,
      username: loginData.username,
      fullName: loginData.fullName,
      role: loginData.role,
    }

    localStorage.setItem('vigilcare_token', loginData.token)
    localStorage.setItem('vigilcare_refresh_token', loginData.refreshToken)
    localStorage.setItem('vigilcare_user', JSON.stringify(user.value))

    router.push(getDefaultRouteForRole(loginData.role))
  }

  async function fetchCurrentUser(): Promise<void> {
    const response = await get<UserProfileResponse>('auth/me')
    if (response.success && response.data) {
      user.value = {
        id: response.data.id,
        username: response.data.username,
        fullName: response.data.fullName,
        role: response.data.role,
      }
      localStorage.setItem('vigilcare_user', JSON.stringify(user.value))
    }
  }

  async function logout(): Promise<void> {
    if (refreshToken.value) {
      try {
        await post<void>('auth/logout', { refreshToken: refreshToken.value })
      } catch {
        // Still clear local session if server revoke fails
      }
    }

    token.value = null
    refreshToken.value = null
    user.value = null
    localStorage.removeItem('vigilcare_token')
    localStorage.removeItem('vigilcare_refresh_token')
    localStorage.removeItem('vigilcare_user')
    router.push('/login')
  }

  return {
    token,
    refreshToken,
    user,
    isAuthenticated,
    userRole,
    userId,
    userFullName,
    canIntake,
    canEntry,
    canVerify,
    canApprove,
    canLiveCapture,
    canSupervise,
    login,
    fetchCurrentUser,
    logout,
  }
})