import { ref, reactive, computed } from 'vue'
import { Notify } from 'quasar'
import { usePermissions } from './usePermissions'

export function usePermissionMatrix () {
  const { HUB_URL } = usePermissions()

  const permTab = ref('users')
  const permLoading = ref(false)
  const permSaving = ref(false)
  const permDirty = ref(false)
  const permGroups = ref([])
  const permCapabilities = ref([])
  const permMatrix = reactive({})

  const allGroupNames = computed(() => permGroups.value.map(g => g.name))
  const permCategories = computed(() => [...new Set(permCapabilities.value.map(c => c.category))])
  const permCapsByCategory = computed(() => {
    const map = {}
    for (const c of permCapabilities.value) {
      if (!map[c.category]) map[c.category] = []
      map[c.category].push(c)
    }
    return map
  })

  async function loadPerms () {
    permLoading.value = true
    try {
      const res = await fetch(HUB_URL + '/auth/groups')
      const data = await res.json()
      permGroups.value = data.groups
      permCapabilities.value = data.capabilities
      for (const g of data.groups) {
        permMatrix[g.name] = {}
        for (const cap of data.capabilities) {
          permMatrix[g.name][cap.key] = g.permissions[cap.key] === true
        }
      }
    } catch (e) {
      Notify.create({ type: 'negative', message: 'Erreur chargement permissions: ' + e.message })
    } finally {
      permLoading.value = false
    }
  }

  async function saveAllPerms () {
    permSaving.value = true
    try {
      for (const g of permGroups.value) {
        await fetch(HUB_URL + '/auth/groups/' + encodeURIComponent(g.name) + '/permissions', {
          method: 'PUT',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify(permMatrix[g.name]),
        })
      }
      permDirty.value = false
      Notify.create({ type: 'positive', message: 'Permissions sauvegardees', timeout: 2000 })
    } catch (e) {
      Notify.create({ type: 'negative', message: 'Erreur: ' + e.message })
    } finally {
      permSaving.value = false
    }
  }

  async function saveGroupPerms (groupName) {
    permSaving.value = true
    try {
      await fetch(HUB_URL + '/auth/groups/' + encodeURIComponent(groupName) + '/permissions', {
        method: 'PUT',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(permMatrix[groupName]),
      })
      permDirty.value = false
      Notify.create({ type: 'positive', message: `Permissions "${groupName}" sauvegardees`, timeout: 2000 })
    } catch (e) {
      Notify.create({ type: 'negative', message: 'Erreur: ' + e.message })
    } finally {
      permSaving.value = false
    }
  }

  function countGroupPerms (g) {
    return Object.values(permMatrix[g.name] || {}).filter(Boolean).length
  }

  function effectivePerm (user, capKey) {
    if (typeof user.overrides[capKey] === 'boolean') return user.overrides[capKey]
    for (const gName of user.groups) {
      if (permMatrix[gName]?.[capKey]) return true
    }
    return false
  }

  async function setUserOverride (user, capKey, value) {
    if (value === true || value === false) {
      user.overrides[capKey] = value
    } else {
      delete user.overrides[capKey]
    }
    const clean = {}
    for (const [k, v] of Object.entries(user.overrides)) {
      if (typeof v === 'boolean') clean[k] = v
    }
    try {
      await fetch(HUB_URL + '/auth/users/' + encodeURIComponent(user.email) + '/overrides', {
        method: 'PUT',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(clean),
      })
    } catch (e) {
      Notify.create({ type: 'negative', message: 'Erreur override: ' + e.message })
    }
  }

  return {
    permTab, permLoading, permSaving, permDirty,
    permGroups, permCapabilities, permMatrix,
    allGroupNames, permCategories, permCapsByCategory,
    loadPerms, saveAllPerms, saveGroupPerms, countGroupPerms,
    effectivePerm, setUserOverride,
  }
}
