"""
LLM 智能筛选与综述生成模块
"""

import json
import os
from typing import List, Optional, Dict, Any
from pathlib import Path

from openai import AsyncOpenAI

from .models import ProjectInfo, SearchResults


class LLMFilter:
    """LLM 智能筛选器"""
    
    def __init__(self, config=None):
        """
        Args:
            config: LLMConfig 或 None（从环境变量读取）
        """
        if config:
            self.client = AsyncOpenAI(
                api_key=config.api_key,
                base_url=config.base_url,
            )
            self.model = config.model
        else:
            self.client = AsyncOpenAI(
                api_key=os.getenv("OPENAI_API_KEY"),
                base_url=os.getenv("NSFC_LLM_BASE_URL"),
            )
            self.model = os.getenv("NSFC_LLM_MODEL", "gpt-4o")
    
    async def filter_projects(
        self, 
        projects: List[ProjectInfo], 
        criteria: str,
        batch_size: int = 20
    ) -> List[ProjectInfo]:
        """
        根据用户条件筛选相关项目
        
        Args:
            projects: 项目列表
            criteria: 筛选条件描述
            batch_size: 每批处理数量
        
        Returns:
            筛选后的项目列表
        """
        if not projects:
            return []
        
        filtered = []
        total_batches = (len(projects) + batch_size - 1) // batch_size
        
        for i in range(0, len(projects), batch_size):
            batch = projects[i:i+batch_size]
            batch_num = i // batch_size + 1
            print(f"  筛选进度: {batch_num}/{total_batches}")
            
            # 构建项目摘要
            project_summaries = []
            for idx, p in enumerate(batch):
                summary = f"{idx+1}. {p.project_name} | {p.project_leader} | {p.institution}"
                if p.keywords:
                    summary += f" | 关键词: {p.keywords}"
                # 添加摘要信息（优先中文摘要，其次结题摘要）
                abstract = p.abstract_cn or p.conclusion_abstract
                if abstract:
                    # 截取前200字，避免过长
                    abstract_short = abstract[:200] + "..." if len(abstract) > 200 else abstract
                    summary += f"\n   摘要: {abstract_short}"
                project_summaries.append(summary)
            
            prompt = self._build_filter_prompt(project_summaries, criteria)
            
            try:
                response = await self._call_llm(prompt)
                selected_indices = self._parse_indices(response, len(batch))
                
                for idx in selected_indices:
                    if 0 <= idx < len(batch):
                        filtered.append(batch[idx])
            except Exception as e:
                print(f"  ⚠ 批次 {batch_num} 筛选失败: {e}")
        
        return filtered
    
    def _build_filter_prompt(self, summaries: List[str], criteria: str) -> str:
        """构建筛选提示词"""
        projects_text = "\n".join(summaries)
        
        return f"""你是一个科研项目筛选助手。请根据用户的筛选条件，从以下项目列表中选出相关项目。

## 筛选条件
{criteria}

## 项目列表
{projects_text}

## 输出要求
1. 仔细分析每个项目与筛选条件的相关性
2. 只输出符合条件的项目序号，用逗号分隔
3. 如果没有符合条件的项目，输出 "无"
4. 只输出序号，不要解释

## 输出格式示例
1,3,5,7
"""
    
    async def _call_llm(self, prompt: str) -> str:
        """调用 LLM"""
        response = await self.client.chat.completions.create(
            model=self.model,
            messages=[{"role": "user", "content": prompt}],
            temperature=0.1,
        )
        return response.choices[0].message.content or ""
    
    def _parse_indices(self, response: str, max_idx: int) -> List[int]:
        """解析 LLM 返回的序号"""
        if not response or "无" in response:
            return []
        
        indices = []
        # 提取数字
        import re
        numbers = re.findall(r'\d+', response)
        
        for num in numbers:
            idx = int(num) - 1  # 转为 0-based
            if 0 <= idx < max_idx:
                indices.append(idx)
        
        return list(set(indices))  # 去重
