import { ref, computed } from 'vue'
import { useAuthStore } from '~/stores/auth'

// Types
export interface User {
  id: number
  email: string
  role: 'superadmin' | 'admin' | 'moderator' | 'sales_agent'
  scope_level: 'Global' | 'Country' | 'Region' | 'City' | 'District'
  status: 'active' | 'inactive'
  created_at: string
  updated_at?: string
  last_login?: string
  organization_id?: number
  region_code?: string
  country_code?: string
}

export interface UpdateUserRoleRequest {
  role: User['role']
  scope_level: User['scope_level']
  scope_id?: number
  region_code?: string
  country_code?: string
}

export interface UserManagementState {
  users: User[]
  loading: boolean
  error: string | null
}

// Geographical scope definitions for mock data
const geographicalScopes = [
  // Hungary hierarchy
  { level: 'Country' as const, code: 'HU', name: 'Hungary', region_code: null },
  { level: 'Region' as const, code: 'HU-PE', name: 'Pest County', country_code: 'HU' },
  { level: 'City' as const, code: 'HU-BU', name: 'Budapest', country_code: 'HU', region_code: 'HU-PE' },
  { level: 'District' as const, code: 'HU-BU-05', name: 'District V', country_code: 'HU', region_code: 'HU-BU' },
  // Germany hierarchy
  { level: 'Country' as const, code: 'DE', name: 'Germany', region_code: null },
  { level: 'Region' as const, code: 'DE-BE', name: 'Berlin', country_code: 'DE' },
  { level: 'City' as const, code: 'DE-BER', name: 'Berlin', country_code: 'DE', region_code: 'DE-BE' },
  // UK hierarchy
  { level: 'Country' as const, code: 'GB', name: 'United Kingdom', region_code: null },
  { level: 'Region' as const, code: 'GB-LON', name: 'London', country_code: 'GB' },
  { level: 'City' as const, code: 'GB-LND', name: 'London', country_code: 'GB', region_code: 'GB-LON' },
]

// Mock data generator with consistent geographical scopes
const generateMockUsers = (count: number = 25): User[] => {
  const roles: User['role'][] = ['superadmin', 'admin', 'moderator', 'sales_agent']
  const statuses: User['status'][] = ['active', 'inactive']
  
  const domains = ['servicefinder.com', 'example.com', 'partner.com', 'customer.org']
  const firstNames = ['John', 'Jane', 'Robert', 'Emily', 'Michael', 'Sarah', 'David', 'Lisa', 'James', 'Maria']
  const lastNames = ['Smith', 'Johnson', 'Williams', 'Brown', 'Jones', 'Garcia', 'Miller', 'Davis', 'Rodriguez', 'Martinez']
  
  const users: User[] = []
  
  // Predefined users with specific geographical scopes for testing
  const predefinedUsers: Partial<User>[] = [
    // Global superadmin
    { email: 'superadmin@servicefinder.com', role: 'superadmin', scope_level: 'Global', country_code: undefined, region_code: undefined },
    // Hungary admin
    { email: 'admin.hu@servicefinder.com', role: 'admin', scope_level: 'Country', country_code: 'HU', region_code: undefined },
    // Pest County moderator
    { email: 'moderator.pest@servicefinder.com', role: 'moderator', scope_level: 'Region', country_code: 'HU', region_code: 'HU-PE' },
    // Budapest sales agent
    { email: 'sales.budapest@servicefinder.com', role: 'sales_agent', scope_level: 'City', country_code: 'HU', region_code: 'HU-BU' },
    // District V sales agent
    { email: 'agent.district5@servicefinder.com', role: 'sales_agent', scope_level: 'District', country_code: 'HU', region_code: 'HU-BU-05' },
    // Germany admin
    { email: 'admin.de@servicefinder.com', role: 'admin', scope_level: 'Country', country_code: 'DE', region_code: undefined },
    // Berlin moderator
    { email: 'moderator.berlin@servicefinder.com', role: 'moderator', scope_level: 'City', country_code: 'DE', region_code: 'DE-BE' },
    // UK admin
    { email: 'admin.uk@servicefinder.com', role: 'admin', scope_level: 'Country', country_code: 'GB', region_code: undefined },
    // London sales agent
    { email: 'sales.london@servicefinder.com', role: 'sales_agent', scope_level: 'City', country_code: 'GB', region_code: 'GB-LON' },
  ]
  
  // Add predefined users
  predefinedUsers.forEach((userData, index) => {
    users.push({
      id: index + 1,
      email: userData.email!,
      role: userData.role!,
      scope_level: userData.scope_level!,
      status: 'active',
      created_at: `2026-${String(Math.floor(Math.random() * 12) + 1).padStart(2, '0')}-${String(Math.floor(Math.random() * 28) + 1).padStart(2, '0')}`,
      updated_at: `2026-${String(Math.floor(Math.random() * 12) + 1).padStart(2, '0')}-${String(Math.floor(Math.random() * 28) + 1).padStart(2, '0')}`,
      last_login: `2026-${String(Math.floor(Math.random() * 12) + 1).padStart(2, '0')}-${String(Math.floor(Math.random() * 28) + 1).padStart(2, '0')}`,
      organization_id: Math.floor(Math.random() * 10) + 1,
      country_code: userData.country_code,
      region_code: userData.region_code,
    })
  })
  
  // Generate remaining random users
  for (let i = users.length + 1; i <= count; i++) {
    const firstName = firstNames[Math.floor(Math.random() * firstNames.length)]
    const lastName = lastNames[Math.floor(Math.random() * lastNames.length)]
    const domain = domains[Math.floor(Math.random() * domains.length)]
    const role = roles[Math.floor(Math.random() * roles.length)]
    const status = statuses[Math.floor(Math.random() * statuses.length)]
    
    // Select a random geographical scope
    const scope = geographicalScopes[Math.floor(Math.random() * geographicalScopes.length)]
    
    users.push({
      id: i,
      email: `${firstName.toLowerCase()}.${lastName.toLowerCase()}@${domain}`,
      role,
      scope_level: scope.level,
      status,
      created_at: `2026-${String(Math.floor(Math.random() * 12) + 1).padStart(2, '0')}-${String(Math.floor(Math.random() * 28) + 1).padStart(2, '0')}`,
      updated_at: `2026-${String(Math.floor(Math.random() * 12) + 1).padStart(2, '0')}-${String(Math.floor(Math.random() * 28) + 1).padStart(2, '0')}`,
      last_login: `2026-${String(Math.floor(Math.random() * 12) + 1).padStart(2, '0')}-${String(Math.floor(Math.random() * 28) + 1).padStart(2, '0')}`,
      organization_id: Math.floor(Math.random() * 10) + 1,
      country_code: scope.country_code || undefined,
      region_code: scope.region_code || undefined,
    })
  }
  
  return users
}

// API Service (Mock implementation)
class UserManagementApiService {
  private mockUsers: User[] = generateMockUsers(15)
  private delay = (ms: number) => new Promise(resolve => setTimeout(resolve, ms))
  
  // Get all users (with optional filtering)
  async getUsers(options?: {
    role?: User['role']
    scope_level?: User['scope_level']
    status?: User['status']
    search?: string
    country_code?: string
    region_code?: string
    geographical_scope?: 'Global' | 'Hungary' | 'Pest County' | 'Budapest' | 'District V'
  }): Promise<User[]> {
    await this.delay(500) // Simulate network delay
    
    let filteredUsers = [...this.mockUsers]
    
    if (options?.role) {
      filteredUsers = filteredUsers.filter(user => user.role === options.role)
    }
    
    if (options?.scope_level) {
      filteredUsers = filteredUsers.filter(user => user.scope_level === options.scope_level)
    }
    
    if (options?.status) {
      filteredUsers = filteredUsers.filter(user => user.status === options.status)
    }
    
    if (options?.country_code) {
      filteredUsers = filteredUsers.filter(user =>
        user.country_code === options.country_code || user.scope_level === 'Global'
      )
    }
    
    if (options?.region_code) {
      filteredUsers = filteredUsers.filter(user =>
        user.region_code === options.region_code ||
        user.scope_level === 'Global' ||
        (user.scope_level === 'Country' && user.country_code === options.country_code)
      )
    }
    
    // Geographical scope filtering (simplified for demo)
    if (options?.geographical_scope) {
      switch (options.geographical_scope) {
        case 'Global':
          // All users
          break
        case 'Hungary':
          filteredUsers = filteredUsers.filter(user =>
            user.country_code === 'HU' || user.scope_level === 'Global'
          )
          break
        case 'Pest County':
          filteredUsers = filteredUsers.filter(user =>
            user.region_code === 'HU-PE' ||
            user.country_code === 'HU' ||
            user.scope_level === 'Global'
          )
          break
        case 'Budapest':
          filteredUsers = filteredUsers.filter(user =>
            user.region_code === 'HU-BU' ||
            user.region_code === 'HU-PE' ||
            user.country_code === 'HU' ||
            user.scope_level === 'Global'
          )
          break
        case 'District V':
          filteredUsers = filteredUsers.filter(user =>
            user.region_code === 'HU-BU-05' ||
            user.region_code === 'HU-BU' ||
            user.region_code === 'HU-PE' ||
            user.country_code === 'HU' ||
            user.scope_level === 'Global'
          )
          break
      }
    }
    
    if (options?.search) {
      const searchLower = options.search.toLowerCase()
      filteredUsers = filteredUsers.filter(user =>
        user.email.toLowerCase().includes(searchLower) ||
        user.role.toLowerCase().includes(searchLower) ||
        user.scope_level.toLowerCase().includes(searchLower) ||
        (user.country_code && user.country_code.toLowerCase().includes(searchLower)) ||
        (user.region_code && user.region_code.toLowerCase().includes(searchLower))
      )
    }
    
    return filteredUsers
  }
  
  // Get single user by ID
  async getUserById(id: number): Promise<User | null> {
    await this.delay(300)
    return this.mockUsers.find(user => user.id === id) || null
  }
  
  // Update user role and scope
  async updateUserRole(id: number, data: UpdateUserRoleRequest): Promise<User> {
    await this.delay(800) // Simulate slower update
    
    const userIndex = this.mockUsers.findIndex(user => user.id === id)
    
    if (userIndex === -1) {
      throw new Error(`User with ID ${id} not found`)
    }
    
    // Check permissions (in a real app, this would be server-side)
    const authStore = useAuthStore()
    const currentUserRole = authStore.getUserRole
    
    // Superadmin can update anyone
    // Admin cannot update superadmin or other admins
    if (currentUserRole === 'admin') {
      const targetUser = this.mockUsers[userIndex]
      if (targetUser.role === 'superadmin' || (targetUser.role === 'admin' && targetUser.id !== authStore.getUserId)) {
        throw new Error('Admin cannot update superadmin or other admin users')
      }
    }
    
    // Update the user
    const updatedUser: User = {
      ...this.mockUsers[userIndex],
      ...data,
      updated_at: new Date().toISOString().split('T')[0],
    }
    
    this.mockUsers[userIndex] = updatedUser
    return updatedUser
  }
  
  // Toggle user status
  async toggleUserStatus(id: number): Promise<User> {
    await this.delay(500)
    
    const userIndex = this.mockUsers.findIndex(user => user.id === id)
    
    if (userIndex === -1) {
      throw new Error(`User with ID ${id} not found`)
    }
    
    const currentStatus = this.mockUsers[userIndex].status
    const newStatus: User['status'] = currentStatus === 'active' ? 'inactive' : 'active'
    
    this.mockUsers[userIndex] = {
      ...this.mockUsers[userIndex],
      status: newStatus,
      updated_at: new Date().toISOString().split('T')[0],
    }
    
    return this.mockUsers[userIndex]
  }
  
  // Create new user (mock)
  async createUser(email: string, role: User['role'], scope_level: User['scope_level']): Promise<User> {
    await this.delay(1000)
    
    const newUser: User = {
      id: Math.max(...this.mockUsers.map(u => u.id)) + 1,
      email,
      role,
      scope_level,
      status: 'active',
      created_at: new Date().toISOString().split('T')[0],
      updated_at: new Date().toISOString().split('T')[0],
    }
    
    this.mockUsers.push(newUser)
    return newUser
  }
  
  // Delete user (mock - just deactivate)
  async deleteUser(id: number): Promise<void> {
    await this.delay(700)
    
    const userIndex = this.mockUsers.findIndex(user => user.id === id)
    
    if (userIndex === -1) {
      throw new Error(`User with ID ${id} not found`)
    }
    
    // Instead of deleting, mark as inactive
    this.mockUsers[userIndex] = {
      ...this.mockUsers[userIndex],
      status: 'inactive',
      updated_at: new Date().toISOString().split('T')[0],
    }
  }
}

// Composable
export const useUserManagement = () => {
  const state = ref<UserManagementState>({
    users: [],
    loading: false,
    error: null,
  })
  
  const apiService = new UserManagementApiService()
  
  // Computed
  const activeUsers = computed(() => state.value.users.filter(user => user.status === 'active'))
  const inactiveUsers = computed(() => state.value.users.filter(user => user.status === 'inactive'))
  const superadminUsers = computed(() => state.value.users.filter(user => user.role === 'superadmin'))
  const adminUsers = computed(() => state.value.users.filter(user => user.role === 'admin'))
  
  // Actions
  const fetchUsers = async (options?: {
    role?: User['role']
    scope_level?: User['scope_level']
    status?: User['status']
    search?: string
    country_code?: string
    region_code?: string
    geographical_scope?: 'Global' | 'Hungary' | 'Pest County' | 'Budapest' | 'District V'
  }) => {
    state.value.loading = true
    state.value.error = null
    
    try {
      const users = await apiService.getUsers(options)
      state.value.users = users
    } catch (error) {
      state.value.error = error instanceof Error ? error.message : 'Failed to fetch users'
      console.error('Error fetching users:', error)
    } finally {
      state.value.loading = false
    }
  }
  
  const updateUserRole = async (id: number, data: UpdateUserRoleRequest) => {
    state.value.loading = true
    state.value.error = null
    
    try {
      const updatedUser = await apiService.updateUserRole(id, data)
      
      // Update local state
      const userIndex = state.value.users.findIndex(user => user.id === id)
      if (userIndex !== -1) {
        state.value.users[userIndex] = updatedUser
      }
      
      return updatedUser
    } catch (error) {
      state.value.error = error instanceof Error ? error.message : 'Failed to update user role'
      console.error('Error updating user role:', error)
      throw error
    } finally {
      state.value.loading = false
    }
  }
  
  const toggleUserStatus = async (id: number) => {
    state.value.loading = true
    state.value.error = null
    
    try {
      const updatedUser = await apiService.toggleUserStatus(id)
      
      // Update local state
      const userIndex = state.value.users.findIndex(user => user.id === id)
      if (userIndex !== -1) {
        state.value.users[userIndex] = updatedUser
      }
      
      return updatedUser
    } catch (error) {
      state.value.error = error instanceof Error ? error.message : 'Failed to toggle user status'
      console.error('Error toggling user status:', error)
      throw error
    } finally {
      state.value.loading = false
    }
  }
  
  const createUser = async (email: string, role: User['role'], scope_level: User['scope_level']) => {
    state.value.loading = true
    state.value.error = null
    
    try {
      const newUser = await apiService.createUser(email, role, scope_level)
      state.value.users.push(newUser)
      return newUser
    } catch (error) {
      state.value.error = error instanceof Error ? error.message : 'Failed to create user'
      console.error('Error creating user:', error)
      throw error
    } finally {
      state.value.loading = false
    }
  }
  
  const deleteUser = async (id: number) => {
    state.value.loading = true
    state.value.error = null
    
    try {
      await apiService.deleteUser(id)
      
      // Update local state (mark as inactive)
      const userIndex = state.value.users.findIndex(user => user.id === id)
      if (userIndex !== -1) {
        state.value.users[userIndex] = {
          ...state.value.users[userIndex],
          status: 'inactive',
          updated_at: new Date().toISOString().split('T')[0],
        }
      }
    } catch (error) {
      state.value.error = error instanceof Error ? error.message : 'Failed to delete user'
      console.error('Error deleting user:', error)
      throw error
    } finally {
      state.value.loading = false
    }
  }
  
  // Initialize with some data
  const initialize = () => {
    fetchUsers()
  }
  
  // Helper function to get geographical scopes for UI
  const getGeographicalScopes = () => {
    return [
      { value: 'Global', label: 'Global', icon: 'mdi-earth', description: 'All users worldwide' },
      { value: 'Hungary', label: 'Hungary', icon: 'mdi-flag', description: 'Users in Hungary' },
      { value: 'Pest County', label: 'Pest County', icon: 'mdi-map-marker-radius', description: 'Users in Pest County' },
      { value: 'Budapest', label: 'Budapest', icon: 'mdi-city', description: 'Users in Budapest' },
      { value: 'District V', label: 'District V', icon: 'mdi-map-marker', description: 'Users in District V' },
    ]
  }

  return {
    // State
    state: computed(() => state.value),
    users: computed(() => state.value.users),
    loading: computed(() => state.value.loading),
    error: computed(() => state.value.error),
    
    // Computed
    activeUsers,
    inactiveUsers,
    superadminUsers,
    adminUsers,
    
    // Actions
    fetchUsers,
    updateUserRole,
    toggleUserStatus,
    createUser,
    deleteUser,
    initialize,
    
    // Helper functions
    getUserById: (id: number) => state.value.users.find(user => user.id === id),
    filterByRole: (role: User['role']) => state.value.users.filter(user => user.role === role),
    filterByScope: (scope_level: User['scope_level']) => state.value.users.filter(user => user.scope_level === scope_level),
    getGeographicalScopes,
  }
}

export default useUserManagement