import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
import { useAuthStore } from './auth'
import { useRBAC, type TilePermission } from '~/composables/useRBAC'

export interface UserTilePreference {
  tileId: string
  visible: boolean
  position: number
  size: 'small' | 'medium' | 'large'
}

export const useTileStore = defineStore('tiles', () => {
  const authStore = useAuthStore()
  const rbac = useRBAC()
  
  // State
  const userPreferences = ref<Record<string, UserTilePreference>>({})
  const isLoading = ref(false)
  
  // Initialize from localStorage
  function loadPreferences() {
    if (typeof window === 'undefined') return
    
    const userId = authStore.user?.id
    if (!userId) return
    
    const stored = localStorage.getItem(`tile_preferences_${userId}`)
    if (stored) {
      try {
        userPreferences.value = JSON.parse(stored)
      } catch (err) {
        console.error('Failed to parse tile preferences:', err)
        userPreferences.value = {}
      }
    }
  }
  
  // Save to localStorage
  function savePreferences() {
    if (typeof window === 'undefined') return
    
    const userId = authStore.user?.id
    if (!userId) return
    
    localStorage.setItem(`tile_preferences_${userId}`, JSON.stringify(userPreferences.value))
  }
  
  // Get default layout (sorted by tile ID for consistency)
  const defaultLayout = computed(() => {
    const filtered = rbac.getFilteredTiles()
    return filtered.map((tile, index) => ({
      tileId: tile.id,
      visible: true,
      position: index,
      size: 'medium' as const
    }))
  })

  // Check if layout has been modified from default
  const isLayoutModified = computed(() => {
    const currentPrefs = Object.values(userPreferences.value)
    const defaultPrefs = defaultLayout.value
    
    if (currentPrefs.length !== defaultPrefs.length) return true
    
    // Check if any preference differs from default
    for (const defaultPref of defaultPrefs) {
      const currentPref = userPreferences.value[defaultPref.tileId]
      if (!currentPref) return true
      
      if (currentPref.visible !== defaultPref.visible ||
          currentPref.position !== defaultPref.position ||
          currentPref.size !== defaultPref.size) {
        return true
      }
    }
    
    return false
  })

  // Get user's accessible tiles with preferences
  const accessibleTiles = computed(() => {
    const filtered = rbac.getFilteredTiles()
    
    return filtered.map(tile => {
      const pref = userPreferences.value[tile.id] || {
        tileId: tile.id,
        visible: true,
        position: 0,
        size: 'medium' as const
      }
      
      return {
        ...tile,
        preference: pref
      }
    }).sort((a, b) => a.preference.position - b.preference.position)
  })
  
  // Get visible tiles only
  const visibleTiles = computed(() => {
    return accessibleTiles.value.filter(tile => tile.preference.visible)
  })
  
  // Update tile preference
  function updateTilePreference(tileId: string, updates: Partial<UserTilePreference>) {
    const current = userPreferences.value[tileId] || {
      tileId,
      visible: true,
      position: Object.keys(userPreferences.value).length,
      size: 'medium'
    }
    
    userPreferences.value[tileId] = {
      ...current,
      ...updates
    }
    
    savePreferences()
  }
  
  // Toggle tile visibility
  function toggleTileVisibility(tileId: string) {
    const current = userPreferences.value[tileId]
    updateTilePreference(tileId, {
      visible: !(current?.visible ?? true)
    })
  }
  
  // Update tile positions (for drag and drop)
  function updateTilePositions(tileIds: string[]) {
    tileIds.forEach((tileId, index) => {
      updateTilePreference(tileId, { position: index })
    })
  }
  
  // Reset to default preferences
  function resetPreferences() {
    const userId = authStore.user?.id
    if (userId) {
      localStorage.removeItem(`tile_preferences_${userId}`)
    }
    userPreferences.value = {}
    
    // Reinitialize with default positions
    const tiles = rbac.getFilteredTiles()
    tiles.forEach((tile, index) => {
      userPreferences.value[tile.id] = {
        tileId: tile.id,
        visible: true,
        position: index,
        size: 'medium'
      }
    })
    
    savePreferences()
  }
  
  // Get tile size class for grid
  function getTileSizeClass(size: 'small' | 'medium' | 'large'): string {
    switch (size) {
      case 'small': return 'cols-12 sm-6 md-4 lg-3'
      case 'medium': return 'cols-12 sm-6 md-6 lg-4'
      case 'large': return 'cols-12 md-12 lg-8'
      default: return 'cols-12 sm-6 md-4 lg-3'
    }
  }
  
  // Initialize when auth changes
  authStore.$subscribe(() => {
    if (authStore.isAuthenticated) {
      loadPreferences()
    } else {
      userPreferences.value = {}
    }
  })
  
  // Initial load
  if (authStore.isAuthenticated) {
    loadPreferences()
  }
  
  return {
    // State
    userPreferences,
    isLoading,
    
    // Getters
    accessibleTiles,
    visibleTiles,
    defaultLayout,
    isLayoutModified,
    
    // Actions
    updateTilePreference,
    toggleTileVisibility,
    updateTilePositions,
    resetPreferences,
    getTileSizeClass,
    loadPreferences,
    savePreferences
  }
})