"""LLM-based commit summarizer."""

import logging
from typing import List, Dict, Any
from openai import OpenAI
from .github_client import CommitInfo

logger = logging.getLogger(__name__)


class CommitSummarizer:
    """Summarizes commits using LLM."""
    
    def __init__(self, api_url: str, api_key: str, model: str = "gpt-3.5-turbo"):
        """Initialize summarizer.
        
        Args:
            api_url: LLM API base URL
            api_key: LLM API key
            model: Model name
        """
        self.client = OpenAI(api_key=api_key, base_url=api_url)
        self.model = model
    
    def summarize_commits(self, commits: List[CommitInfo], repo_name: str, 
                         branch: str) -> str:
        """Summarize commits in Chinese with markdown formatting.
        
        Args:
            commits: List of CommitInfo objects
            repo_name: Repository name
            branch: Branch name
            
        Returns:
            Markdown formatted summary in Chinese
        """
        if not commits:
            return f"# {repo_name} ({branch}) - 每日提交汇总\n\n**没有找到提交记录。**"
        
        # Organize commits by change type
        organized = self._organize_commits(commits, repo_name)
        
        # Create prompt for LLM
        prompt = self._create_prompt(organized, repo_name, branch)
        
        try:
            response = self.client.chat.completions.create(
                model=self.model,
                messages=[
                    {"role": "system", "content": "你是一个专业的技术文档编写助手，擅长总结代码变更。请使用中文回答，并以清晰的markdown格式组织内容。"},
                    {"role": "user", "content": prompt}
                ],
                temperature=0.7,
                max_tokens=2000
            )
            
            summary = response.choices[0].message.content
            return summary
            
        except Exception as e:
            logger.error(f"Error calling LLM API: {e}")
            # Fallback to basic summary
            return self._create_basic_summary(organized, repo_name, branch)
    
    def _organize_commits(self, commits: List[CommitInfo], 
                         repo_name: str) -> Dict[str, List[Dict[str, Any]]]:
        """Organize commits by change type and module.
        
        Args:
            commits: List of CommitInfo objects
            repo_name: Repository name for generating URLs
            
        Returns:
            Dictionary organized by change type
        """
        organized = {
            'added': {},      # module -> list of changes
            'modified': {},   # module -> list of changes
            'deleted': {},    # module -> list of changes
        }
        
        for commit in commits:
            for file_change in commit.files_changed:
                filename = file_change['filename']
                status = file_change['status']
                
                # Determine module from file path
                module = self._get_module_from_path(filename)
                
                change_info = {
                    'filename': filename,
                    'message': commit.message.split('\n')[0],  # First line only
                    'author': commit.author,
                    'additions': file_change['additions'],
                    'deletions': file_change['deletions'],
                    'pr_number': commit.pr_number,
                    'pr_url': commit.pr_url,
                    'sha': commit.sha[:7]
                }
                
                # Categorize by status
                if status == 'added':
                    category = 'added'
                elif status == 'removed':
                    category = 'deleted'
                else:
                    category = 'modified'
                
                if module not in organized[category]:
                    organized[category][module] = []
                organized[category][module].append(change_info)
        
        return organized
    
    def _get_module_from_path(self, filepath: str) -> str:
        """Extract module name from file path.
        
        Args:
            filepath: File path
            
        Returns:
            Module name
        """
        parts = filepath.split('/')
        if len(parts) > 1:
            return parts[0]
        return 'root'
    
    def _create_prompt(self, organized: Dict[str, List[Dict[str, Any]]], 
                      repo_name: str, branch: str) -> str:
        """Create prompt for LLM.
        
        Args:
            organized: Organized commit data
            repo_name: Repository name
            branch: Branch name
            
        Returns:
            Prompt string
        """
        prompt = f"""请总结以下GitHub仓库的提交记录：

仓库: {repo_name}
分支: {branch}
时间范围: 过去24小时

提交记录已按照新增、修改、删除分类，并按模块组织。请生成一个清晰的中文Markdown格式汇总：

1. 使用一级标题作为总标题
2. 使用二级标题分类（## 新增功能、## 代码修改、## 删除内容）
3. 在每个分类下，按模块使用三级标题
4. 对同一模块的多个变更进行合并描述
5. 为每个PR添加markdown格式的超链接，使用PR编号作为链接文本

原始数据：
```json
{organized}
```

请生成简洁、专业的中文汇总。"""
        
        return prompt
    
    def _create_basic_summary(self, organized: Dict[str, List[Dict[str, Any]]], 
                             repo_name: str, branch: str) -> str:
        """Create a basic summary without LLM (fallback).
        
        Args:
            organized: Organized commit data
            repo_name: Repository name
            branch: Branch name
            
        Returns:
            Basic markdown summary
        """
        lines = [
            f"# {repo_name} ({branch}) - 每日提交汇总",
            "",
            f"**生成时间**: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}",
            ""
        ]
        
        # Added files
        if organized['added']:
            lines.append("## 新增功能")
            lines.append("")
            for module, changes in organized['added'].items():
                lines.append(f"### {module}")
                lines.append("")
                for change in changes:
                    pr_link = ""
                    if change['pr_number']:
                        pr_link = f" - [PR #{change['pr_number']}]({change['pr_url']})"
                    lines.append(f"- **{change['filename']}** (+{change['additions']}){pr_link}")
                    lines.append(f"  - {change['message']}")
                lines.append("")
        
        # Modified files
        if organized['modified']:
            lines.append("## 代码修改")
            lines.append("")
            for module, changes in organized['modified'].items():
                lines.append(f"### {module}")
                lines.append("")
                for change in changes:
                    pr_link = ""
                    if change['pr_number']:
                        pr_link = f" - [PR #{change['pr_number']}]({change['pr_url']})"
                    lines.append(f"- **{change['filename']}** (+{change['additions']}/-{change['deletions']}){pr_link}")
                    lines.append(f"  - {change['message']}")
                lines.append("")
        
        # Deleted files
        if organized['deleted']:
            lines.append("## 删除内容")
            lines.append("")
            for module, changes in organized['deleted'].items():
                lines.append(f"### {module}")
                lines.append("")
                for change in changes:
                    pr_link = ""
                    if change['pr_number']:
                        pr_link = f" - [PR #{change['pr_number']}]({change['pr_url']})"
                    lines.append(f"- **{change['filename']}** (-{change['deletions']}){pr_link}")
                    lines.append(f"  - {change['message']}")
                lines.append("")
        
        return "\n".join(lines)


from datetime import datetime
