import { reactive } from 'vue'
import { Notify } from 'quasar'
import { HUB_URL } from 'src/config/hub'

// Store partagé (module-level) : un seul état d'avatars pour toute l'app.
//  · hasPhoto[email] = true  → ce courriel A une photo (sinon on n'affiche QUE les initiales,
//    sans tenter de <img> → zéro requête 404 pour les membres sans photo).
//  · versions[email]        → jeton de cache-bust (bump après upload/suppression).
const hasPhoto = reactive({})
const versions = reactive({})

function keyOf (email) { return String(email || '').toLowerCase() }
export function avatarVersion (email) { return versions[keyOf(email)] || '' }
export function hasAvatar (email) { return !!hasPhoto[keyOf(email)] }
function bump (email, v) { versions[keyOf(email)] = v || Date.now() }

// Index chargé une seule fois (promesse singleton) : GET /avatars → { avatars: { email: version } }.
// Renseigne hasPhoto + versions. Idempotent : plusieurs <UserAvatar> peuvent l'appeler.
let _indexP = null
export function ensureAvatarIndex () {
  if (!_indexP) {
    _indexP = fetch(HUB_URL + '/avatars')
      .then(r => r.ok ? r.json() : { avatars: {} })
      .then(data => {
        for (const [email, v] of Object.entries(data.avatars || {})) {
          hasPhoto[keyOf(email)] = true
          versions[keyOf(email)] = v
        }
      })
      .catch(() => { _indexP = null }) // échec → réessayable au prochain montage
  }
  return _indexP
}

// Réduit une image (File/Blob) à un carré <= max px, en JPEG base64 (data URL).
// Garde les avatars petits (< 1 Mo) et cohérents, sans dépendance externe.
export async function fileToAvatarDataUrl (file, max = 256, quality = 0.85) {
  const dataUrl = await new Promise((resolve, reject) => {
    const fr = new FileReader()
    fr.onload = () => resolve(fr.result)
    fr.onerror = reject
    fr.readAsDataURL(file)
  })
  const img = await new Promise((resolve, reject) => {
    const i = new Image()
    i.onload = () => resolve(i)
    i.onerror = reject
    i.src = dataUrl
  })
  const side = Math.min(img.width, img.height)          // recadrage carré centré
  const sx = (img.width - side) / 2
  const sy = (img.height - side) / 2
  const out = Math.min(max, side)
  const canvas = document.createElement('canvas')
  canvas.width = out; canvas.height = out
  const ctx = canvas.getContext('2d')
  ctx.drawImage(img, sx, sy, side, side, 0, 0, out, out)
  return canvas.toDataURL('image/jpeg', quality)
}

export function useAvatar () {
  async function uploadAvatar (dataUrl, { as } = {}) {
    const url = HUB_URL + '/avatars' + (as ? ('?as=' + encodeURIComponent(as)) : '')
    const r = await fetch(url, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ dataUrl }),
    })
    const data = await r.json().catch(() => ({}))
    if (!r.ok) { Notify.create({ type: 'negative', message: 'Photo: ' + (data.error || ('HTTP ' + r.status)) }); return false }
    hasPhoto[keyOf(data.email || as)] = true
    bump(data.email || as, data.version)
    Notify.create({ type: 'positive', message: 'Photo de profil mise à jour', timeout: 1500 })
    return true
  }

  async function deleteAvatar ({ as } = {}) {
    const url = HUB_URL + '/avatars' + (as ? ('?as=' + encodeURIComponent(as)) : '')
    const r = await fetch(url, { method: 'DELETE' })
    const data = await r.json().catch(() => ({}))
    if (!r.ok) { Notify.create({ type: 'negative', message: 'Photo: ' + (data.error || ('HTTP ' + r.status)) }); return false }
    hasPhoto[keyOf(data.email || as)] = false
    bump(data.email || as)
    return true
  }

  return { uploadAvatar, deleteAvatar, fileToAvatarDataUrl, avatarVersion }
}
