import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
import { userService, type UserApproval, type UserRoleUpdate, type UserUpdate } from '@/services/user'
import type { User } from '@/types/auth'

export const useUserStore = defineStore('user', () => {
  // State
  const users = ref<User[]>([])
  const pendingUsers = ref<User[]>([])
  const isLoading = ref(false)
  const error = ref<string | null>(null)

  // Getters
  const approvedUsers = computed(() => users.value.filter(user => user.is_approved))
  const totalUsers = computed(() => users.value.length)
  const pendingCount = computed(() => pendingUsers.value.length)

  // Actions
  const fetchAllUsers = async () => {
    try {
      isLoading.value = true
      error.value = null
      users.value = await userService.getAllUsers()
    } catch (err: any) {
      error.value = err.response?.data?.detail || 'Failed to fetch users'
      throw err
    } finally {
      isLoading.value = false
    }
  }

  const fetchPendingUsers = async () => {
    try {
      isLoading.value = true
      error.value = null
      pendingUsers.value = await userService.getPendingUsers()
    } catch (err: any) {
      error.value = err.response?.data?.detail || 'Failed to fetch pending users'
      throw err
    } finally {
      isLoading.value = false
    }
  }

  const approveUser = async (userId: number, isApproved: boolean) => {
    try {
      error.value = null
      const approval: UserApproval = { is_approved: isApproved }
      await userService.approveUser(userId, approval)
      
      // Update local state
      const userIndex = pendingUsers.value.findIndex(user => user.id === userId)
      if (userIndex !== -1) {
        const user = pendingUsers.value[userIndex]
        user.is_approved = isApproved
        
        if (isApproved) {
          // Move from pending to approved users
          pendingUsers.value.splice(userIndex, 1)
          users.value.push(user)
        }
      }
      
      // Also update in main users array if it exists
      const mainUserIndex = users.value.findIndex(user => user.id === userId)
      if (mainUserIndex !== -1) {
        users.value[mainUserIndex].is_approved = isApproved
      }
    } catch (err: any) {
      error.value = err.response?.data?.detail || 'Failed to approve user'
      throw err
    }
  }

  const updateUserRole = async (userId: number, role: UserRoleUpdate['role']) => {
    try {
      error.value = null
      const roleUpdate: UserRoleUpdate = { role }
      await userService.updateUserRole(userId, roleUpdate)
      
      // Update local state
      const userIndex = users.value.findIndex(user => user.id === userId)
      if (userIndex !== -1) {
        users.value[userIndex].role = role
      }
    } catch (err: any) {
      error.value = err.response?.data?.detail || 'Failed to update user role'
      throw err
    }
  }

  const updateUserAdminPermission = async (userId: number, isAdmin: boolean) => {
    try {
      error.value = null
      await userService.updateUserAdminPermission(userId, isAdmin)
      
      // Update local state
      const userIndex = users.value.findIndex(user => user.id === userId)
      if (userIndex !== -1) {
        users.value[userIndex].is_admin = isAdmin
      }
    } catch (err: any) {
      error.value = err.response?.data?.detail || 'Failed to update admin permission'
      throw err
    }
  }

  const updateCurrentUserProfile = async (userUpdate: UserUpdate) => {
    try {
      error.value = null
      const updatedUser = await userService.updateCurrentUser(userUpdate)
      
      // Update local state if the user exists in our arrays
      const userIndex = users.value.findIndex(user => user.id === updatedUser.id)
      if (userIndex !== -1) {
        users.value[userIndex] = updatedUser
      }
      
      return updatedUser
    } catch (err: any) {
      error.value = err.response?.data?.detail || 'Failed to update profile'
      throw err
    }
  }

  const createUser = async (userData: {
    email: string
    password: string
    first_name: string
    last_name: string
    role: 'artist' | 'coordinator' | 'director' | 'developer'
    is_approved: boolean
    is_admin: boolean
  }) => {
    try {
      error.value = null
      const newUser = await userService.createUser(userData)
      
      // Add to appropriate list
      if (newUser.is_approved) {
        users.value.push(newUser)
      } else {
        pendingUsers.value.push(newUser)
      }
      
      return newUser
    } catch (err: any) {
      error.value = err.response?.data?.detail || 'Failed to create user'
      throw err
    }
  }

  const editUser = async (userId: number, userData: {
    first_name?: string
    last_name?: string
    email?: string
    role?: 'artist' | 'coordinator' | 'director' | 'developer'
    is_approved?: boolean
    is_admin?: boolean
  }) => {
    try {
      error.value = null
      const updatedUser = await userService.editUser(userId, userData)
      
      // Update local state with proper reactivity
      const userIndex = users.value.findIndex(user => user.id === userId)
      if (userIndex !== -1) {
        // Create a new array to trigger reactivity
        users.value = [
          ...users.value.slice(0, userIndex),
          updatedUser,
          ...users.value.slice(userIndex + 1)
        ]
      }
      
      const pendingIndex = pendingUsers.value.findIndex(user => user.id === userId)
      if (pendingIndex !== -1) {
        if (updatedUser.is_approved) {
          // Move from pending to approved
          pendingUsers.value = pendingUsers.value.filter(u => u.id !== userId)
          users.value = [...users.value, updatedUser]
        } else {
          // Update in pending list
          pendingUsers.value = [
            ...pendingUsers.value.slice(0, pendingIndex),
            updatedUser,
            ...pendingUsers.value.slice(pendingIndex + 1)
          ]
        }
      }
      
      return updatedUser
    } catch (err: any) {
      error.value = err.response?.data?.detail || 'Failed to edit user'
      throw err
    }
  }

  const resetUserPassword = async (userId: number, newPassword: string) => {
    try {
      error.value = null
      await userService.resetUserPassword(userId, newPassword)
    } catch (err: any) {
      error.value = err.response?.data?.detail || 'Failed to reset password'
      throw err
    }
  }

  const deleteUser = async (userId: number) => {
    try {
      error.value = null
      await userService.deleteUser(userId)
      
      // Remove from local state
      const userIndex = users.value.findIndex(user => user.id === userId)
      if (userIndex !== -1) {
        users.value.splice(userIndex, 1)
      }
      
      const pendingIndex = pendingUsers.value.findIndex(user => user.id === userId)
      if (pendingIndex !== -1) {
        pendingUsers.value.splice(pendingIndex, 1)
      }
    } catch (err: any) {
      error.value = err.response?.data?.detail || 'Failed to delete user'
      throw err
    }
  }

  const clearError = () => {
    error.value = null
  }

  return {
    // State
    users,
    pendingUsers,
    isLoading,
    error,
    
    // Getters
    approvedUsers,
    totalUsers,
    pendingCount,
    
    // Actions
    fetchAllUsers,
    fetchPendingUsers,
    approveUser,
    updateUserRole,
    updateUserAdminPermission,
    updateCurrentUserProfile,
    createUser,
    editUser,
    resetUserPassword,
    deleteUser,
    clearError
  }
})