// @ts-nocheck
/**
 * 搜索脉搏 — 纯本站搜索数据驱动的实时热榜
 * 不再依赖任何外部 API (Bilibili/Baidu/TMDB 已移除)
 * 数据来源: 本站 hot_keywords 表，真实用户搜索行为
 */
import { getDb } from '../database/database';
import { formatLocalDateTime } from '../utils/time';

// ==================== 类型定义 ====================

export interface HotKeyword {
  keyword: string;
  count: number;
  updatedAt: string;
  genre: string;       // 自动检测的分类
  genreEmoji: string;  // 对应 emoji
  heatLevel: number;   // 0-5 热度等级 (用于火焰效果)
  isRising: boolean;   // 是否在上升中
}

export interface SearchPulse {
  generatedAt: string;
  totalSearches: number;     // 总搜索次数
  uniqueKeywords: number;    // 不同关键词数
  hottestHour: string;       // 搜索最活跃的小时
  hotList: HotKeyword[];     // 热榜 Top 20
  recentList: HotKeyword[];  // 最新搜索 Top 15
  categories: CategoryGroup[]; // 按分类聚合
}

export interface CategoryGroup {
  name: string;
  emoji: string;
  keywords: HotKeyword[];
}

// ==================== 自动分类检测 ====================

/** 根据关键词内容自动推断分类 */
const GENRE_RULES: { emoji: string; name: string; patterns: RegExp[] }[] = [
  {
    emoji: '🎬', name: '影视',
    patterns: [/电影/, /影院/, /上映/, /票房/, /好莱坞/, /导演/, /演员/, /奥斯卡/, /戛纳/,
              /电视剧/, /剧集/, /韩剧/, /美剧/, /日剧/, /英剧/, /国产剧/, /网剧/,
              /4[kK]/, /1080[pP]/, /720[pP]/, /[BbDd]lu[Rr]ay/, /[Hh][Dd]/,
              /[Mm][Pp]4/, /[Mm][Kk][Vv]/, /[Rr][Mm][Vv][Bb]/, /[Aa][Vv][Ii]/]
  },
  {
    emoji: '🎮', name: '动漫',
    patterns: [/动漫/, /动画/, /番剧/, /新番/, /日漫/, /国漫/, /漫画/, /二次元/,
              /bilibili/i, /鬼灭/, /海贼/, /火影/, /咒术/, /间谍过家家/,
              /柯南/, /哆啦[Aa]梦/, /蜡笔小新/, /龙珠/, /进击的巨人/]
  },
  {
    emoji: '🎵', name: '音乐',
    patterns: [/音乐/, /歌曲/, /专辑/, /无损/, /[Ff][Ll][Aa][Cc]/, /[Aa][Pp][Ee]/,
              /[Mm][Pp]3/, /演唱会/, /[Mm][Vv]/, /歌手/, /乐队/, /DJ/,
              /周杰伦/, /Taylor/, /BTS/]
  },
  {
    emoji: '📚', name: '书籍',
    patterns: [/书/, /小说/, /电子书/, /[Pp][Dd][Ff]/, /[Ee][Pp][Uu][Bb]/, /[Mm][Oo][Bb][Ii]/,
              /txt/, /漫画书/, /杂志/, /文献/, /论文/, /考试/, /教材/]
  },
  {
    emoji: '💻', name: '软件',
    patterns: [/软件/, /破解/, /注册机/, /激活/, /[Cc]rack/, /[Pp]atch/,
              /[Ww]indows/, /[Mm]ac[Oo][Ss]/, /[Ll]inux/, /[Aa]ndroid/,
              /[Ee]xe/, /[Dd][Mm][Gg]/, /安装包/, /[Aa][Pp][Kk]/]
  },
  {
    emoji: '🎮', name: '游戏',
    patterns: [/游戏/, /[Ss]team/, /[Ee]pic/, /[Ss]witch/, /[Pp][Ss]5/, /[Xx]box/,
              /手游/, /端游/, /模拟器/, /[Rr][Oo][Mm]/, /[Ii][Ss][Oo]/,
              /原神/, /王者/, /吃鸡/, /[Mm]inecraft/]
  },
];

function detectGenre(keyword: string): { emoji: string; name: string } {
  for (const rule of GENRE_RULES) {
    for (const p of rule.patterns) {
      if (p.test(keyword)) {
        return { emoji: rule.emoji, name: rule.name };
      }
    }
  }
  return { emoji: '🔍', name: '其他' };
}

/** 根据搜索次数计算热度等级 0-5 */
function calcHeatLevel(count: number, maxCount: number): number {
  if (maxCount === 0) return 0;
  const ratio = count / maxCount;
  if (ratio >= 0.8) return 5;
  if (ratio >= 0.6) return 4;
  if (ratio >= 0.4) return 3;
  if (ratio >= 0.2) return 2;
  if (ratio >= 0.05) return 1;
  return 0;
}

/** 简单的"是否在上升"判断：最近更新过且搜索次数在中上水平 */
function isRising(updatedAt: string, count: number, maxCount: number): boolean {
  const updated = new Date(updatedAt);
  const now = new Date();
  const hoursAgo = (now.getTime() - updated.getTime()) / 3600000;
  return hoursAgo < 24 && count >= maxCount * 0.1;
}

// ==================== 缓存 ====================
let cache: { data: SearchPulse; time: number } | null = null;
const CACHE_TTL = 30 * 60 * 1000; // 30分钟缓存

function isCacheValid(): boolean {
  return cache !== null && (Date.now() - cache.time) < CACHE_TTL;
}

// ==================== 主查询 ====================

async function generateSearchPulse(): Promise<SearchPulse> {
  const db = getDb();
  const now = new Date();
  const localNow = formatLocalDateTime();

  // 1. 统计概览
  const stats = db.prepare(
    'SELECT COUNT(*) as total, SUM(search_count) as totalSearches FROM hot_keywords'
  ).get() as any;
  const uniqueKeywords = stats?.total || 0;
  const totalSearches = stats?.totalSearches || 0;

  // 2. 热榜 Top 20
  const hotRows = db.prepare(
    'SELECT keyword, search_count as count, updated_at as updatedAt FROM hot_keywords ORDER BY search_count DESC LIMIT 20'
  ).all() as any[];
  
  const maxHotCount = hotRows.length > 0 ? hotRows[0].count : 1;
  
  const hotList: HotKeyword[] = hotRows.map((row: any) => {
    const genre = detectGenre(row.keyword);
    return {
      keyword: row.keyword,
      count: row.count,
      updatedAt: row.updatedAt,
      genre: genre.name,
      genreEmoji: genre.emoji,
      heatLevel: calcHeatLevel(row.count, maxHotCount),
      isRising: isRising(row.updatedAt, row.count, maxHotCount),
    };
  });

  // 3. 最新搜索 Top 15
  const recentRows = db.prepare(
    'SELECT keyword, search_count as count, updated_at as updatedAt FROM hot_keywords ORDER BY updated_at DESC LIMIT 15'
  ).all() as any[];
  
  const recentList: HotKeyword[] = recentRows.map((row: any) => {
    const genre = detectGenre(row.keyword);
    return {
      keyword: row.keyword,
      count: row.count,
      updatedAt: row.updatedAt,
      genre: genre.name,
      genreEmoji: genre.emoji,
      heatLevel: 1,
      isRising: true, // 最新搜索都算上升
    };
  });

  // 4. 按分类聚合
  const allKeywords = db.prepare(
    'SELECT keyword, search_count as count, updated_at as updatedAt FROM hot_keywords WHERE search_count >= 3 ORDER BY search_count DESC'
  ).all() as any[];
  
  const categoryMap = new Map<string, HotKeyword[]>();
  for (const row of allKeywords) {
    const genre = detectGenre(row.keyword);
    if (!categoryMap.has(genre.name)) {
      categoryMap.set(genre.name, []);
    }
    const group = categoryMap.get(genre.name)!;
    if (group.length < 8) {
      group.push({
        keyword: row.keyword,
        count: row.count,
        updatedAt: row.updatedAt,
        genre: genre.name,
        genreEmoji: genre.emoji,
        heatLevel: 0,
        isRising: false,
      });
    }
  }
  
  const categories: CategoryGroup[] = Array.from(categoryMap.entries())
    .sort((a, b) => b[1].length - a[1].length)
    .slice(0, 6)
    .map(([name, keywords]) => ({
      name,
      emoji: keywords[0]?.genreEmoji || '📋',
      keywords,
    }));

  // 5. 搜索最活跃的小时
  const hourRow = db.prepare(
    "SELECT updated_at FROM hot_keywords ORDER BY updated_at DESC LIMIT 100"
  ).all() as any[];
  
  const hours = hourRow.map((r: any) => new Date(r.updated_at).getHours());
  const hourCount = new Map<number, number>();
  for (const h of hours) {
    hourCount.set(h, (hourCount.get(h) || 0) + 1);
  }
  let maxH = 19;
  let maxC = 0;
  for (const [h, c] of hourCount) {
    if (c > maxC) { maxC = c; maxH = h; }
  }
  const hottestHour = `${String(maxH).padStart(2, '0')}:00`;

  return {
    generatedAt: localNow,
    totalSearches,
    uniqueKeywords,
    hottestHour,
    hotList,
    recentList,
    categories,
  };
}

// ==================== 导出接口 ====================

/** 获取搜索脉搏数据 (30分钟缓存) */
export async function getSearchPulse(): Promise<SearchPulse> {
  if (isCacheValid()) {
    return cache!.data;
  }
  try {
    const data = await generateSearchPulse();
    cache = { data, time: Date.now() };
    return data;
  } catch (err) {
    console.error('[SearchPulse] Error:', err);
    if (cache) return cache.data;
    return {
      generatedAt: formatLocalDateTime(),
      totalSearches: 0,
      uniqueKeywords: 0,
      hottestHour: '--',
      hotList: [],
      recentList: [],
      categories: [],
    };
  }
}

// ==================== 兼容旧接口 ====================

export interface RankingItem {
  keyword: string;
  searchCount: number;
  updatedAt: string;
  rating?: number;
}

export interface CategorizedRanking {
  category: string;
  label: string;
  hot: RankingItem[];
  newest: RankingItem[];
}

export interface CategorizedResponse {
  fetchedAt: string;
  categories: CategorizedRanking[];
}

/** 兼容旧接口，返回搜索脉搏数据 */
export async function getCategorizedRankings(): Promise<CategorizedResponse> {
  const pulse = await getSearchPulse();
  const fetchedAt = pulse.generatedAt;

  const categories: CategorizedRanking[] = [
    {
      category: 'hot',
      label: '搜索热榜',
      hot: pulse.hotList.map(item => ({
        keyword: item.keyword,
        searchCount: item.count,
        updatedAt: item.updatedAt,
        heatLevel: item.heatLevel,
        isRising: item.isRising,
        genreEmoji: item.genreEmoji,
        genre: item.genre,
      })),
      newest: pulse.recentList.map(item => ({
        keyword: item.keyword,
        searchCount: item.count,
        updatedAt: item.updatedAt,
        heatLevel: item.heatLevel,
        isRising: item.isRising,
        genreEmoji: item.genreEmoji,
        genre: item.genre,
      })),
    },
    // 按分类展示
    ...pulse.categories.map(cat => ({
      category: 'genre_' + cat.name,
      label: cat.emoji + ' ' + cat.name,
      hot: cat.keywords.map(item => ({
        keyword: item.keyword,
        searchCount: item.count,
        updatedAt: item.updatedAt,
        heatLevel: item.heatLevel,
        isRising: item.isRising,
        genreEmoji: item.genreEmoji,
        genre: item.genre,
      })),
      newest: [],
    })),
  ];

  return { fetchedAt, categories };
}

export async function getRankings(): Promise<RankingItem[]> {
  const pulse = await getSearchPulse();
  return pulse.hotList.map(item => ({
    keyword: item.keyword,
    searchCount: item.count,
    updatedAt: item.updatedAt,
  }));
}

export async function getHotKeywords(): Promise<string[]> {
  const pulse = await getSearchPulse();
  return pulse.hotList.map(item => item.keyword);
}