/**
 * Search Results Optimizer
 * 
 * For each cloud type, keep only the top N most relevant results.
 * Order groups by priority: real cloud storage > other providers > magnet/others.
 * 
 * Goal: give users a manageable, high-quality result set instead of overwhelming them
 * with hundreds of results dominated by magnet links.
 */

import { detectCloudType } from '../config/cloud-labels';

/** Minimal result shape the optimizer needs */
interface OptimizableResult {
  title?: string;
  url?: string;
  source?: string;
  score?: number;
  [key: string]: any;
}

/** Priority tiers for result ordering */
const CLOUD_PRIORITY: Record<string, number> = {
  // Tier 1: Major cloud storage (most useful for save-to-cloud feature)
  baidu: 10,
  quark: 10,
  aliyun: 10,
  // Tier 2: Other cloud storage
  '115': 20,
  tianyi: 20,
  '123pan': 20,
  uc: 20,
  xunlei: 20,
  pikpak: 20,
  // Tier 3: Mobile/app links (not very useful)
  mobile: 50,
  // Tier 4: Direct links (lowest utility for cloud saving)
  magnet: 100,
  ed2k: 100,
  others: 100,
};

const DEFAULT_PRIORITY = 50;

/** Get cloud type for a result, with an extra check for tracker URLs */
function getCloudType(result: OptimizableResult): string {
  const url = result.url;
  // Check for tracker/private-site URLs not covered by shared detection
  if (url && /mteam|hdarea|hdsky/i.test(url)) return 'others';
  return detectCloudType(url);
}

function getPriority(cloudType: string): number {
  return CLOUD_PRIORITY[cloudType] ?? DEFAULT_PRIORITY;
}

export interface OptimizationResult {
  results: OptimizableResult[];
  /** Per-type stats for display */
  perType: Array<{ type: string; count: number; total: number }>;
  /** How many items were kept vs filtered */
  keptCount: number;
  filteredCount: number;
}

/**
 * Optimize search results:
 * 1. Group by cloud type
 * 2. Sort by score descending within each group
 * 3. Keep only top `maxPerType` results per type
 * 4. Order groups by priority (cloud storage first)
 */
export function optimizeSearchResults(
  items: OptimizableResult[],
  maxPerType: number = 20
): OptimizationResult {
  // Step 1: Group by cloud type
  const grouped: Record<string, OptimizableResult[]> = {};
  const typeTotals: Record<string, number> = {};

  for (const item of items) {
    const ct = getCloudType(item);
    if (!grouped[ct]) {
      grouped[ct] = [];
    }
    grouped[ct].push(item);
    typeTotals[ct] = (typeTotals[ct] || 0) + 1;
  }

  // Step 2 & 3: Sort each group by score desc, take top N
  const kept: OptimizableResult[] = [];
  const perType: Array<{ type: string; count: number; total: number }> = [];

  for (const [ct, groupItems] of Object.entries(grouped)) {
    // Sort by score descending (higher score = more relevant)
    groupItems.sort((a, b) => (b.score || 0) - (a.score || 0));

    const top = groupItems.slice(0, maxPerType);
    kept.push(...top);

    perType.push({
      type: ct,
      count: top.length,
      total: typeTotals[ct],
    });
  }

  // Step 4: Sort kept results by cloud priority, then by score within same priority
  kept.sort((a, b) => {
    const pa = getPriority(getCloudType(a));
    const pb = getPriority(getCloudType(b));
    if (pa !== pb) return pa - pb;
    return (b.score || 0) - (a.score || 0);
  });

  const keptCount = kept.length;
  const filteredCount = items.length - keptCount;

  return {
    results: kept,
    perType,
    keptCount,
    filteredCount,
  };
}
