"""Export classification results."""
import logging
import json
import csv
from pathlib import Path
from typing import List, Dict, Any
from datetime import datetime

from src.email_providers.base import ClassificationResult

logger = logging.getLogger(__name__)


class ResultsExporter:
    """Export classification results in multiple formats."""

    def __init__(self, output_dir: str = "results"):
        """Initialize exporter."""
        self.output_dir = Path(output_dir)
        self.output_dir.mkdir(parents=True, exist_ok=True)

    def export_json(
        self,
        results: List[ClassificationResult],
        metadata: Dict[str, Any],
        filename: str = "results.json"
    ) -> Path:
        """Export results as JSON."""
        output_file = self.output_dir / filename

        data = {
            'metadata': metadata,
            'classifications': [
                {
                    'email_id': r.email_id,
                    'category': r.category,
                    'confidence': r.confidence,
                    'method': r.method,
                    'needs_review': r.needs_review,
                    'probabilities': r.probabilities,
                    'error': r.error
                }
                for r in results
            ]
        }

        try:
            with open(output_file, 'w') as f:
                json.dump(data, f, indent=2)
            logger.info(f"Exported JSON to {output_file}")
            return output_file
        except Exception as e:
            logger.error(f"Error exporting JSON: {e}")
            raise

    def export_csv(
        self,
        results: List[ClassificationResult],
        filename: str = "results.csv"
    ) -> Path:
        """Export results as CSV."""
        output_file = self.output_dir / filename

        try:
            with open(output_file, 'w', newline='') as f:
                writer = csv.DictWriter(
                    f,
                    fieldnames=['email_id', 'category', 'confidence', 'method', 'needs_review', 'error']
                )
                writer.writeheader()

                for result in results:
                    writer.writerow({
                        'email_id': result.email_id,
                        'category': result.category,
                        'confidence': round(result.confidence, 3),
                        'method': result.method,
                        'needs_review': result.needs_review,
                        'error': result.error or ''
                    })

            logger.info(f"Exported CSV to {output_file}")
            return output_file
        except Exception as e:
            logger.error(f"Error exporting CSV: {e}")
            raise

    def export_by_category(
        self,
        results: List[ClassificationResult],
        dirname: str = "by_category"
    ) -> Path:
        """Export results organized by category."""
        output_dir = self.output_dir / dirname
        output_dir.mkdir(parents=True, exist_ok=True)

        # Group by category
        by_category = {}
        for result in results:
            if result.category not in by_category:
                by_category[result.category] = []
            by_category[result.category].append(result)

        # Export each category
        for category, category_results in by_category.items():
            filename = output_dir / f"{category}.json"

            data = {
                'category': category,
                'count': len(category_results),
                'emails': [
                    {
                        'email_id': r.email_id,
                        'confidence': r.confidence,
                        'method': r.method
                    }
                    for r in category_results
                ]
            }

            try:
                with open(filename, 'w') as f:
                    json.dump(data, f, indent=2)
                logger.debug(f"Exported {len(category_results)} emails to {filename}")
            except Exception as e:
                logger.error(f"Error exporting {category}: {e}")

        logger.info(f"Exported results organized by category to {output_dir}")
        return output_dir


class ReportGenerator:
    """Generate classification reports."""

    def __init__(self, output_dir: str = "results"):
        """Initialize report generator."""
        self.output_dir = Path(output_dir)

    def generate_report(
        self,
        results: List[ClassificationResult],
        metadata: Dict[str, Any],
        filename: str = "report.txt"
    ) -> Path:
        """Generate text report."""
        output_file = self.output_dir / filename

        # Calculate statistics
        by_category = {}
        by_method = {}
        needs_review_count = 0

        for result in results:
            # By category
            if result.category not in by_category:
                by_category[result.category] = 0
            by_category[result.category] += 1

            # By method
            if result.method not in by_method:
                by_method[result.method] = 0
            by_method[result.method] += 1

            # Needs review
            if result.needs_review:
                needs_review_count += 1

        # Generate report
        report_lines = [
            "=" * 80,
            "EMAIL SORTER CLASSIFICATION REPORT",
            "=" * 80,
            "",
            f"Generated: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}",
            f"Total Emails: {len(results):,}",
            f"Accuracy Estimate: {metadata.get('accuracy_estimate', 0):.1%}",
            "",
            "CATEGORY DISTRIBUTION:",
            "-" * 80,
        ]

        # Sort by count
        for category in sorted(by_category.keys(), key=lambda c: by_category[c], reverse=True):
            count = by_category[category]
            pct = (count / len(results) * 100) if results else 0
            report_lines.append(f"  {category:20s} {count:7,d}  ({pct:5.1f}%)")

        report_lines.extend([
            "",
            "CLASSIFICATION METHOD BREAKDOWN:",
            "-" * 80,
        ])

        for method in sorted(by_method.keys()):
            count = by_method[method]
            pct = (count / len(results) * 100) if results else 0
            report_lines.append(f"  {method:20s} {count:7,d}  ({pct:5.1f}%)")

        report_lines.extend([
            "",
            "QUALITY METRICS:",
            "-" * 80,
            f"  Needs Review: {needs_review_count:,} ({(needs_review_count/len(results)*100) if results else 0:.1f}%)",
            f"  Processing Time: {metadata.get('processing_time', 'unknown')}s",
            "",
            "=" * 80,
        ])

        # Write report
        try:
            with open(output_file, 'w') as f:
                f.write("\n".join(report_lines))

            logger.info(f"Report generated: {output_file}")
            return output_file
        except Exception as e:
            logger.error(f"Error generating report: {e}")
            raise
