/**
 * postPriority.js
 *
 * Système de priorité et clustering pour afficher intelligemment les posts:
 * - Posts importants => cartes complètes (mini)
 * - Posts secondaires => marqueurs simples (icône + hover)
 */

/**
 * Calcule le score de priorité d'un post
 * Score plus élevé = plus important
 */
export function calculatePostPriority(post, viewCenter, allPosts) {
  let score = 0;

  // 1. Score intrinsèque du post (si disponible depuis reco-service)
  const recoScore = typeof post.score === 'number' ? post.score : 40; // Réduit de 50 à 40 pour base plus basse
  score += recoScore * 0.4; // Weight: 40%

  // 2. Catégorie (certaines plus importantes)
  const category = (post?.category || '').toString().toUpperCase();
  const categoryBonus = {
    'EVENT': 20,
    'EVENTS': 20,
    'NEWS': 15,
    'MARKET': 10,
    'FRIENDS': 5,
  };
  score += categoryBonus[category] || 10; // Weight: 10-20

  // 3. Fraîcheur (posts récents prioritaires)
  const createdAt = post?.created_at || post?.CreatedAt || post?.createdAt;
  if (createdAt) {
    const ageHours = (Date.now() - new Date(createdAt).getTime()) / (1000 * 60 * 60);
    if (ageHours < 1) score += 25;
    else if (ageHours < 6) score += 20;
    else if (ageHours < 24) score += 15;
    else if (ageHours < 72) score += 10;
    else score += 5;
  }

  // 4. Distance par rapport au centre de la vue
  if (viewCenter) {
    const lat = typeof post.lat === 'number' ? post.lat : post.latitude;
    const lon = typeof post.lon === 'number' ? post.lon : post.lng;

    if (lat != null && lon != null) {
      const dx = viewCenter.lng - lon;
      const dy = viewCenter.lat - lat;
      const dist = Math.sqrt(dx * dx + dy * dy);

      // Plus proche du centre = meilleur score
      const maxDist = 0.1; // ~10km
      const distScore = Math.max(0, 20 * (1 - dist / maxDist));
      score += distScore; // Weight: 0-20
    }
  }

  // 5. Engagement (si disponible)
  const views = post?.views || post?.view_count || 0;
  const likes = post?.likes || post?.like_count || 0;
  const comments = post?.comments || post?.comment_count || 0;
  const engagementScore = Math.min(20, (views / 100) + (likes * 2) + (comments * 5));
  score += engagementScore; // Weight: 0-20

  return Math.round(score);
}

/**
 * Détecte les clusters de posts proches
 * Retourne Map<clusterId, posts[]>
 */
export function clusterPosts(posts, clusterRadius = 0.001) {
  const clusters = new Map();
  const processed = new Set();
  let clusterId = 0;

  for (const post of posts) {
    if (processed.has(post.id)) continue;

    const lat = typeof post.lat === 'number' ? post.lat : post.latitude;
    const lon = typeof post.lon === 'number' ? post.lon : post.lng;

    if (lat == null || lon == null) continue;

    // Trouve tous les posts dans le rayon
    const cluster = [post];
    processed.add(post.id);

    for (const other of posts) {
      if (processed.has(other.id)) continue;

      const oLat = typeof other.lat === 'number' ? other.lat : other.latitude;
      const oLon = typeof other.lon === 'number' ? other.lon : other.lng;

      if (oLat == null || oLon == null) continue;

      const dx = lat - oLat;
      const dy = lon - oLon;
      const dist = Math.sqrt(dx * dx + dy * dy);

      if (dist < clusterRadius) {
        cluster.push(other);
        processed.add(other.id);
      }
    }

    clusters.set(clusterId++, cluster);
  }

  return clusters;
}

/**
 * Décide quels posts afficher comme cartes complètes vs marqueurs simples
 * Retourne { fullCardPosts: [], simpleMarkerPosts: [] }
 */
export function prioritizePosts(posts, viewCenter, options = {}) {
  const {
    maxFullCards = 15,        // Max de cartes complètes à afficher
    clusterRadius = 0.001,    // Rayon de clustering (~100m)
    minScoreForCard = 40,     // Score minimum pour carte complète
  } = options;

  // 1. Calculer les scores
  const postsWithScores = posts.map(post => ({
    post,
    priority: calculatePostPriority(post, viewCenter, posts),
  }));

  // 2. Trier par priorité descendante
  postsWithScores.sort((a, b) => b.priority - a.priority);

  // 3. Détecter les clusters
  const clusters = clusterPosts(posts, clusterRadius);

  // 4. Sélectionner les posts pour cartes complètes
  const fullCardPosts = [];
  const simpleMarkerPosts = [];
  const clusterRepresentatives = new Set();

  for (const [clusterId, clusterPosts] of clusters.entries()) {
    if (clusterPosts.length === 1) {
      // Pas de cluster, décision simple basée sur le score
      const item = postsWithScores.find(p => p.post.id === clusterPosts[0].id);
      if (item && item.priority >= minScoreForCard && fullCardPosts.length < maxFullCards) {
        fullCardPosts.push(item.post);
      } else {
        simpleMarkerPosts.push(clusterPosts[0]);
      }
    } else {
      // Cluster: prendre le meilleur post pour carte complète, autres en marqueurs simples
      const sortedCluster = clusterPosts
        .map(p => postsWithScores.find(ps => ps.post.id === p.id))
        .filter(Boolean)
        .sort((a, b) => b.priority - a.priority);

      // Le meilleur du cluster devient carte si score suffisant
      if (sortedCluster[0] &&
          sortedCluster[0].priority >= minScoreForCard &&
          fullCardPosts.length < maxFullCards) {
        fullCardPosts.push(sortedCluster[0].post);
        clusterRepresentatives.add(sortedCluster[0].post.id);
      }

      // Les autres deviennent marqueurs simples
      for (let i = (clusterRepresentatives.has(sortedCluster[0]?.post.id) ? 1 : 0); i < sortedCluster.length; i++) {
        simpleMarkerPosts.push(sortedCluster[i].post);
      }
    }
  }

  // 5. Si pas assez de cartes complètes, ajouter les meilleurs marqueurs simples
  if (fullCardPosts.length < maxFullCards) {
    const remaining = postsWithScores
      .filter(p =>
        !fullCardPosts.find(fp => fp.id === p.post.id) &&
        !simpleMarkerPosts.find(sp => sp.id === p.post.id)
      )
      .slice(0, maxFullCards - fullCardPosts.length);

    for (const item of remaining) {
      fullCardPosts.push(item.post);
      const idx = simpleMarkerPosts.findIndex(p => p.id === item.post.id);
      if (idx >= 0) simpleMarkerPosts.splice(idx, 1);
    }
  }

  return {
    fullCardPosts,
    simpleMarkerPosts,
    clusters,
  };
}

/**
 * Génère une couleur pour un marqueur simple basée sur la catégorie
 */
export function getMarkerColorForCategory(category) {
  const cat = (category || '').toString().toUpperCase();

  const colors = {
    'EVENT': '#8b5cf6',      // violet
    'EVENTS': '#8b5cf6',
    'NEWS': '#3b82f6',       // bleu
    'MARKET': '#10b981',     // vert
    'FRIENDS': '#f59e0b',    // orange
  };

  return colors[cat] || '#6b7280'; // gris par défaut
}
