

// src/contextmenu.js
import { state } from './state.js';
import { renderApps } from './render.js';
import { saveOrder } from './order.js';

/** Mostra il menu alla posizione (x,y) per la app con id `id`. */
export function showContextMenuFor(id, x, y) {
  state.contextMenuTargetId = id;

  const menu = document.getElementById('context-menu');
  if (!menu) {
    console.warn('[contextmenu] Elemento #context-menu non trovato.');
    return;
  }

  // Clamping per evitare overflow bordo
  const vw = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
  const vh = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);

  const estW = Math.max(menu.offsetWidth || 180, 180);
  const estH = Math.max(menu.offsetHeight || 120, 120);

  const left = Math.min(Math.max(8, x), vw - estW - 8);
  const top  = Math.min(Math.max(8, y), vh - estH - 8);

  menu.style.left = `${left}px`;
  menu.style.top  = `${top}px`;
  menu.classList.remove('hidden');
}

/** Nasconde il menu contestuale. */
export function hideContextMenu() {
  const menu = document.getElementById('context-menu');
  if (!menu) return;
  menu.classList.add('hidden');
  state.contextMenuTargetId = null;
}

/* ============================
   Utility per "Cambia icona"
   ============================ */

/** Crea/ritorna un file input nascosto per icone. */
function ensureHiddenFileInput() {
  let input = document.getElementById('context-icon-file');
  if (!input) {
    input = document.createElement('input');
    input.type = 'file';
    input.id = 'context-icon-file';
    input.accept = 'image/*';
    input.style.position = 'fixed';
    input.style.left = '-9999px';
    input.style.top = '-9999px';
    input.style.width = '1px';
    input.style.height = '1px';
    input.style.opacity = '0';
    document.body.appendChild(input);
  }
  return input;
}

/** Promessa che risolve con il File selezionato, o null se annullato. */
function pickImageFile() {
  return new Promise((resolve) => {
    const input = ensureHiddenFileInput();
    const onChange = () => {
      input.removeEventListener('change', onChange);
      resolve(input.files && input.files[0] ? input.files[0] : null);
      // reset value per permettere nuova scelta dello stesso file
      input.value = '';
    };
    input.addEventListener('change', onChange, { once: true });
    input.click();
  });
}

/** Carica un File immagine in un HTMLImageElement. */
function fileToImage(file) {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.onerror = () => reject(new Error('Impossibile leggere il file.'));
    reader.onload = () => {
      const img = new Image();
      img.onload = () => resolve(img);
      img.onerror = () => reject(new Error('Impossibile caricare l’immagine.'));
      img.src = reader.result;
    };
    reader.readAsDataURL(file);
  });
}

/** Verifica supporto WebP nel canvas. */
function supportsWebP() {
  try {
    const c = document.createElement('canvas');
    const d = c.toDataURL('image/webp');
    return d.startsWith('data:image/webp');
  } catch {
    return false;
  }
}

/**
 * Converte un’immagine in DataURL WebP (qualità 0..1).
 * - Ritaglia al centro per ottenere un quadrato consistente.
 * - Ridimensiona a targetEdge px (default 256).
 */
function imageToWebPDataURL(img, { quality = 0.9, targetEdge = 256 } = {}) {
  const sw = img.naturalWidth || img.width;
  const sh = img.naturalHeight || img.height;
  const side = Math.min(sw, sh);

  // Ritaglio centrale per icone uniformi (quadrate)
  const sx = Math.floor((sw - side) / 2);
  const sy = Math.floor((sh - side) / 2);

  const canvas = document.createElement('canvas');
  canvas.width = targetEdge;
  canvas.height = targetEdge;

  const ctx = canvas.getContext('2d');
  // Preserva trasparenza
  ctx.clearRect(0, 0, targetEdge, targetEdge);
  ctx.drawImage(img, sx, sy, side, side, 0, 0, targetEdge, targetEdge);

  // Se WebP non è supportato, avvisa e ritorna PNG
  if (!supportsWebP()) {
    alert('Il tuo browser non supporta WebP. Salverò in PNG come fallback.');
    return canvas.toDataURL('image/png'); // qualità PNG non è parametrica
  }

  return canvas.toDataURL('image/webp', quality);
}

/* ============================
   Inizializzazione azioni
   ============================ */

export function initContextMenuActions(Storage) {
  // Apertura menu
  document.addEventListener('show-context-for', e => {
    const { id, x, y } = e.detail || {};
    if (!id || typeof x !== 'number' || typeof y !== 'number') return;
    showContextMenuFor(id, x, y);
  });

  const menu = document.getElementById('context-menu');
  if (!menu) {
    console.warn('[contextmenu] #context-menu non trovato in init.');
    return;
  }

  /**
   * Azioni del menu su pointerdown in capture:
   * - Evita conflitti con chiusure globali
   * - Funziona su mouse/touch/pen
   */
  const onActionPointerDown = async (e) => {
    e.stopPropagation();
    e.preventDefault();

    const btn = e.target.closest('button');
    if (!btn) return;

    const targetId = state.contextMenuTargetId;
    if (!targetId) {
      console.warn('[contextmenu] Nessun targetId — menu aperto senza id.');
      hideContextMenu();
      return;
    }

    const app = state.appsData.find(a => a.id === targetId);
    if (!app) {
      console.warn('[contextmenu] Target app non trovata:', targetId);
      hideContextMenu();
      return;
    }

    const action = btn.dataset.action;

    // --- RINOMINA ---
    if (action === 'rename') {
      const nuovoNome = prompt('Nuovo nome app:', app.name ?? '');
      if (nuovoNome && nuovoNome.trim() && nuovoNome.trim() !== app.name) {
        app.name = nuovoNome.trim();
        try {
          await Storage.saveApps(state.appsData);
          await saveOrder(Storage);
          renderApps();
        } catch (err) {
          console.error('[contextmenu] Errore salvataggio nuovo nome:', err);
          alert('Impossibile salvare il nuovo nome in memoria locale.');
        }
      }
      hideContextMenu();
      return;
    }

    // --- CAMBIA ICONA (file picker + WebP 90 + salvataggio locale) ---
    if (action === 'change-icon') {
      try {
        const file = await pickImageFile();
        if (!file) {
          hideContextMenu();
          return; // utente ha annullato
        }

        // (Opzionale) Limita tipi/size
        const validTypes = ['image/png', 'image/jpeg', 'image/jpg', 'image/webp', 'image/gif'];
        if (file.type && !validTypes.includes(file.type)) {
          alert('Formato non supportato. Usa PNG, JPEG o WebP.');
          hideContextMenu();
          return;
        }

        // Carica immagine e converte in WebP qualità 0.9, 256x256 (quadrato)
        const img = await fileToImage(file);
        const dataUrl = imageToWebPDataURL(img, { quality: 0.9, targetEdge: 256 });

        // Aggiorna l’app con l’icona locale (Data URL)
        app.icon = dataUrl;

        // Persisti modifiche
        await Storage.saveApps(state.appsData);
        await saveOrder(Storage);

        // Re-render
        renderApps();

      } catch (err) {
        console.error('[contextmenu] Errore cambio icona:', err);
        alert('Impossibile cambiare l’icona. Riprova con un’immagine diversa.');
      }
      hideContextMenu();
      return;
    }

    // --- RIMUOVI ---
    if (action === 'remove') {
      if (confirm('Rimuovere questa app dalla griglia?')) {
        try {
          // 1) Rimuovi dai dati
          state.appsData = state.appsData.filter(a => a.id !== app.id);

          // 2) Rimuovi dall’ordine
          state.appsOrder = state.appsOrder.filter(id => id !== app.id);

          // 3) Salva entrambe
          await Storage.saveApps(state.appsData);
          await saveOrder(Storage);

          // 4) Re-render
          renderApps();
        } catch (err) {
          console.error('[contextmenu] Errore salvataggio rimozione:', err);
          alert('Impossibile salvare le modifiche (rimozione app).');
        }
      }
      hideContextMenu();
      return;
    }
  };

  // Registra il listener
  menu.addEventListener('pointerdown', onActionPointerDown, { capture: true });
}
