"""
Markdown report generator for code review results.

This module provides utilities for generating markdown-formatted reports
from code review results.
"""

from typing import Any, Dict, List, Optional
import os
from datetime import datetime

from vaahai.reporting.formats import OutputFormat


class MarkdownReporter:
    """
    Generates markdown-formatted reports from code review results.
    
    This class converts the review results into a well-structured markdown
    document that can be displayed in any markdown viewer or converted to
    other formats.
    """
    
    def __init__(self, results: Dict[str, Any]):
        """
        Initialize the markdown reporter.
        
        Args:
            results: Dictionary containing the review results
        """
        self.results = results
        
    def generate_report(self) -> str:
        """
        Generate a markdown report from the review results.
        
        Returns:
            Markdown-formatted string containing the report
        """
        if self.results.get("status") == "error":
            return self._generate_error_report()
        
        # Start building the report
        report = []
        
        # Add report header
        report.append(self._generate_header())
        
        # Add summary section
        report.append(self._generate_summary())
        
        # Add key findings section
        report.append(self._generate_key_findings())
        
        # Add recommendations section
        report.append(self._generate_recommendations())
        
        # Add statistics section
        report.append(self._generate_statistics())
        
        # Add issues by file section
        report.append(self._generate_issues_by_file())
        
        # Add footer
        report.append(self._generate_footer())
        
        return "\n\n".join(report)
    
    def _generate_error_report(self) -> str:
        """Generate a report for error results."""
        return f"""# Code Review Error

## Error Details

**Status:** Error

**Message:** {self.results.get('message', 'Unknown error')}

*Generated by VaahAI Code Review*
"""
    
    def _generate_header(self) -> str:
        """Generate the report header."""
        now = datetime.now()
        date_str = now.strftime("%Y-%m-%d %H:%M:%S")
        
        return f"""# VaahAI Code Review Report

*Generated on: {date_str}*
"""
    
    def _generate_summary(self) -> str:
        """Generate the summary section."""
        total_issues = self.results.get("total_issues", 0)
        message = self.results.get("message", "")
    
        # Get file information if available
        file_results = self.results.get("file_results", [])
        num_files = len(file_results) if file_results else 1
    
        if file_results:
            summary = f"## Summary\n\n{message}\n\n"
            summary += f"- **Files Reviewed:** {num_files}\n"
            summary += f"- **Total Issues:** {total_issues}\n"
        else:
            # Handle different result formats (dict or list)
            results = self.results.get("results", {})
            file_path = "Unknown file"
            
            if isinstance(results, dict):
                # If results is a dict of step results
                if results:
                    # Get the first step result
                    first_step = next(iter(results.values()))
                    file_path = first_step.get("file_path", "Unknown file")
            elif isinstance(results, list) and results:
                # If results is a list of step results
                file_path = results[0].get("file_path", "Unknown file")
            
            summary = f"## Summary\n\n{message}\n\n"
            summary += f"- **File:** {file_path}\n"
            summary += f"- **Total Issues:** {total_issues}\n"
        
        # Add progress information if available
        progress = self.results.get("progress", {})
        if progress:
            total_steps = progress.get("total_steps", 0)
            completed_steps = progress.get("completed_steps", 0)
            failed_steps = progress.get("failed_steps", 0)
            
            summary += f"- **Review Steps:** {completed_steps}/{total_steps} completed"
            if failed_steps > 0:
                summary += f", {failed_steps} failed"
            summary += "\n"
        
        return summary
    
    def _generate_key_findings(self) -> str:
        """Generate the key findings section."""
        key_findings = self.results.get("key_findings", [])
        
        if not key_findings:
            return ""
        
        section = "## Key Findings\n\n"
        
        for finding in key_findings:
            finding_type = finding.get("type", "")
            severity = finding.get("severity", "")
            count = finding.get("count", 0)
            message = finding.get("message", "")
            
            if finding_type == "severity" and severity:
                severity_emoji = self._get_severity_emoji(severity)
                section += f"- {severity_emoji} **{severity.title()}:** {message}\n"
            else:
                section += f"- **Issue ({count} occurrences):** {message}\n"
        
        return section
    
    def _generate_recommendations(self) -> str:
        """Generate the recommendations section."""
        recommendations = self.results.get("recommendations", [])
        
        if not recommendations:
            return ""
        
        section = "## Actionable Recommendations\n\n"
        
        for i, recommendation in enumerate(recommendations, 1):
            section += f"{i}. {recommendation}\n"
        
        return section
    
    def _generate_statistics(self) -> str:
        """Generate the statistics section."""
        statistics = self.results.get("statistics", {})
        
        if not statistics:
            return ""
        
        section = "## Statistics\n\n"
        
        # File statistics
        total_files = statistics.get("total_files", 0)
        files_with_issues = statistics.get("files_with_issues", 0)
        files_with_issues_percentage = statistics.get("files_with_issues_percentage", 0)
        
        section += "### File Statistics\n\n"
        section += f"- **Total Files:** {total_files}\n"
        section += f"- **Files with Issues:** {files_with_issues} ({files_with_issues_percentage:.1f}%)\n"
        section += f"- **Average Issues per File:** {statistics.get('issues_per_file', 0):.2f}\n\n"
        
        # Issues by severity
        issues_by_severity = statistics.get("issues_by_severity", {})
        
        if issues_by_severity:
            section += "### Issues by Severity\n\n"
            section += "| Severity | Count | Percentage |\n"
            section += "|----------|-------|------------|\n"
            
            total_issues = statistics.get("total_issues", 0)
            
            for severity, count in issues_by_severity.items():
                if total_issues > 0:
                    percentage = (count / total_issues) * 100
                else:
                    percentage = 0
                
                severity_emoji = self._get_severity_emoji(severity)
                section += f"| {severity_emoji} {severity.title()} | {count} | {percentage:.1f}% |\n"
            
            section += "\n"
        
        # Issues by category
        issues_by_category = statistics.get("issues_by_category", {})
        
        if issues_by_category:
            section += "### Issues by Category\n\n"
            section += "| Category | Count | Percentage |\n"
            section += "|----------|-------|------------|\n"
            
            total_issues = statistics.get("total_issues", 0)
            
            for category, count in issues_by_category.items():
                if total_issues > 0:
                    percentage = (count / total_issues) * 100
                else:
                    percentage = 0
                
                section += f"| {category.replace('_', ' ').title()} | {count} | {percentage:.1f}% |\n"
            
            section += "\n"
        
        # Most common issues
        most_common_issues = statistics.get("most_common_issues", [])
        
        if most_common_issues:
            section += "### Most Common Issues\n\n"
            
            for issue, count in most_common_issues:
                section += f"- **({count} occurrences):** {issue}\n"
        
        return section
    
    def _generate_issues_by_file(self) -> str:
        """Generate the issues by file section."""
        # For directory reviews
        file_results = self.results.get("file_results", [])
    
        if file_results:
            section = "## Issues by File\n\n"
    
            for file_result in file_results:
                file_path = file_result.get("file_path", "")
                file_issues = file_result.get("total_issues", 0)
    
                if file_issues > 0:
                    file_name = os.path.basename(file_path)
                    section += f"### {file_name} ({file_issues} issues)\n\n"
    
                    # Get the results for this file
                    results = file_result.get("results", [])
                    section += self._format_issues(results, file_path)
    
            return section
    
        # For single file reviews
        results = self.results.get("results", [])
    
        if not results:
            return ""
    
        section = "## Detailed Issues\n\n"
        # Handle different result formats (dict or list)
        file_path = ""
        if isinstance(results, dict):
            # If results is a dict of step results
            section += "### Issues by Step\n\n"
            for step_id, step_result in results.items():
                if step_result.get("issues"):
                    section += f"#### {step_id}\n\n"
                    for issue in step_result.get("issues", []):
                        section += f"- {issue}\n"
                    section += "\n"
            return section
        elif isinstance(results, list) and results:
            # If results is a list of step results
            file_path = results[0].get("file_path", "")
        
        file_name = os.path.basename(file_path) if file_path else "Unknown file"
        section += f"### {file_name}\n\n"
        
        section += self._format_issues(results, file_path)
        
        return section
    
    def _format_issues(self, results: List[Dict[str, Any]], file_path: str) -> str:
        """Format issues for a specific file."""
        formatted = ""
        
        for result in results:
            step_name = result.get("step_name", "")
            step_category = result.get("step_category", "").replace("_", " ").title()
            step_severity = result.get("step_severity", "").lower()
            issues = result.get("issues", [])
            
            if not issues:
                continue
            
            severity_emoji = self._get_severity_emoji(step_severity)
            formatted += f"#### {severity_emoji} {step_name} ({step_category})\n\n"
            
            for issue in issues:
                line = issue.get("line", "")
                message = issue.get("message", "")
                code = issue.get("code", "")
                
                if line:
                    formatted += f"- **Line {line}:** {message}\n"
                else:
                    formatted += f"- {message}\n"
                
                if code:
                    formatted += f"```\n{code}\n```\n\n"
        
        return formatted
    
    def _generate_footer(self) -> str:
        """Generate the report footer."""
        return "---\n*Generated by VaahAI Code Review*"
    
    def _get_severity_emoji(self, severity: str) -> str:
        """Get an emoji for the given severity level."""
        severity = severity.lower()
        
        if severity == "critical":
            return "🔴"
        elif severity == "high":
            return "🟠"
        elif severity == "medium":
            return "🟡"
        elif severity == "low":
            return "🟢"
        else:
            return "ℹ️"


def generate_markdown_report(results: Dict[str, Any]) -> str:
    """
    Generate a markdown report from review results.
    
    Args:
        results: Dictionary containing the review results
        
    Returns:
        Markdown-formatted string containing the report
    """
    reporter = MarkdownReporter(results)
    return reporter.generate_report()
