"""Result reporting and output formatting."""
import json
import csv
from pathlib import Path
from typing import List
from datetime import datetime

import aiohttp
from rich.console import Console
from rich.table import Table

from reclaimor.config import Config
from reclaimor.scanner.result import ScanResult
from reclaimor.utils.logger import setup_logger

logger = setup_logger(__name__)
console = Console()


class Reporter:
    """Generate reports in various formats."""
    
    def __init__(self, config: Config):
        self.config = config
    
    def print_console(self, results: List[ScanResult]):
        """Print results to console with rich formatting."""
        table = Table(title="ReClaimor Scan Results")
        
        table.add_column("Domain", style="cyan")
        table.add_column("Status", style="bold")
        table.add_column("Confidence", justify="right")
        table.add_column("Provider", style="yellow")
        table.add_column("Exploited", justify="center")
        
        vulnerable_count = 0
        
        for result in results:
            if result.vulnerable:
                vulnerable_count += 1
                status = "[red]VULNERABLE[/red]"
                confidence = f"[red]{result.confidence}%[/red]"
            else:
                status = "[green]SAFE[/green]"
                confidence = f"[dim]{result.confidence}%[/dim]"
            
            exploited = "✓" if result.exploit_successful else ("⚠" if result.exploit_attempted else "-")
            
            table.add_row(
                result.domain,
                status,
                confidence,
                result.provider or "-",
                exploited,
            )
        
        console.print(table)
        console.print(f"\n[bold]Summary:[/bold] {vulnerable_count}/{len(results)} vulnerable")
    
    def save(self, results: List[ScanResult], output_path: str, format: str):
        """Save results to file in specified format."""
        path = Path(output_path)
        
        if format == "json":
            self._save_json(results, path)
        elif format == "csv":
            self._save_csv(results, path)
        elif format == "html":
            self._save_html(results, path)
        else:
            self._save_text(results, path)
    
    def _save_json(self, results: List[ScanResult], path: Path):
        """Save as JSON."""
        data = {
            "scan_date": datetime.utcnow().isoformat(),
            "total_scanned": len(results),
            "vulnerable_count": sum(1 for r in results if r.vulnerable),
            "results": [r.to_dict() for r in results],
        }
        
        with open(path, "w") as f:
            json.dump(data, f, indent=2)
        
        logger.info(f"Saved JSON report to {path}")
    
    def _save_csv(self, results: List[ScanResult], path: Path):
        """Save as CSV."""
        with open(path, "w", newline="") as f:
            writer = csv.writer(f)
            writer.writerow([
                "Domain", "Vulnerable", "Confidence", "Provider",
                "CNAME", "Status Code", "Exploited", "Exploit Success",
                "Timestamp", "Duration (s)", "Error"
            ])
            
            for r in results:
                writer.writerow([
                    r.domain,
                    r.vulnerable,
                    r.confidence,
                    r.provider or "",
                    r.cname or "",
                    r.status_code or "",
                    r.exploit_attempted,
                    r.exploit_successful,
                    r.timestamp.isoformat(),
                    f"{r.scan_duration:.2f}",
                    r.error or "",
                ])
        
        logger.info(f"Saved CSV report to {path}")
    
    def _save_html(self, results: List[ScanResult], path: Path):
        """Save as HTML report."""
        html = self._generate_html(results)
        with open(path, "w") as f:
            f.write(html)
        logger.info(f"Saved HTML report to {path}")
    
    def _save_text(self, results: List[ScanResult], path: Path):
        """Save as plain text."""
        with open(path, "w") as f:
            f.write("ReClaimor Scan Results\n")
            f.write("=" * 80 + "\n\n")
            
            for r in results:
                f.write(f"Domain: {r.domain}\n")
                f.write(f"Status: {'VULNERABLE' if r.vulnerable else 'SAFE'}\n")
                f.write(f"Confidence: {r.confidence}%\n")
                if r.provider:
                    f.write(f"Provider: {r.provider}\n")
                if r.cname:
                    f.write(f"CNAME: {r.cname}\n")
                if r.exploit_attempted:
                    f.write(f"Exploitation: {'SUCCESS' if r.exploit_successful else 'FAILED'}\n")
                f.write("\n")
        
        logger.info(f"Saved text report to {path}")
    
    def _generate_html(self, results: List[ScanResult]) -> str:
        """Generate HTML report."""
        vulnerable = [r for r in results if r.vulnerable]
        
        html = f"""<!DOCTYPE html>
<html>
<head>
    <title>ReClaimor Scan Report</title>
    <style>
        body {{ font-family: Arial, sans-serif; margin: 20px; background: #f5f5f5; }}
        .container {{ max-width: 1200px; margin: 0 auto; background: white; padding: 20px; border-radius: 8px; }}
        h1 {{ color: #333; }}
        .summary {{ background: #e3f2fd; padding: 15px; border-radius: 5px; margin: 20px 0; }}
        table {{ width: 100%; border-collapse: collapse; margin: 20px 0; }}
        th {{ background: #1976d2; color: white; padding: 12px; text-align: left; }}
        td {{ padding: 10px; border-bottom: 1px solid #ddd; }}
        .vulnerable {{ color: #d32f2f; font-weight: bold; }}
        .safe {{ color: #388e3c; }}
        .high {{ background: #ffebee; }}
        .medium {{ background: #fff3e0; }}
    </style>
</head>
<body>
    <div class="container">
        <h1>🔍 ReClaimor Scan Report</h1>
        <div class="summary">
            <h3>Summary</h3>
            <p><strong>Total Scanned:</strong> {len(results)}</p>
            <p><strong>Vulnerable:</strong> {len(vulnerable)}</p>
            <p><strong>Scan Date:</strong> {datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S')} UTC</p>
        </div>
        
        <h2>Vulnerable Domains</h2>
        <table>
            <tr>
                <th>Domain</th>
                <th>Confidence</th>
                <th>Provider</th>
                <th>CNAME</th>
                <th>Exploited</th>
            </tr>
"""
        
        for r in vulnerable:
            severity_class = "high" if r.confidence >= 70 else "medium"
            exploited = "✓" if r.exploit_successful else ("⚠" if r.exploit_attempted else "-")
            html += f"""
            <tr class="{severity_class}">
                <td class="vulnerable">{r.domain}</td>
                <td>{r.confidence}%</td>
                <td>{r.provider or '-'}</td>
                <td>{r.cname or '-'}</td>
                <td>{exploited}</td>
            </tr>
"""
        
        html += """
        </table>
        
        <p style="margin-top: 40px; color: #666; font-size: 12px;">
            Generated by ReClaimor - https://github.com/letchupkt/ReClaimor
        </p>
    </div>
</body>
</html>
"""
        return html
    
    async def send_webhook(self, results: List[ScanResult], webhook_url: str):
        """Send results to webhook (Slack/Discord)."""
        vulnerable = [r for r in results if r.vulnerable]
        
        if not vulnerable:
            return
        
        # Format message
        message = f"🚨 ReClaimor found {len(vulnerable)} vulnerable subdomain(s):\n\n"
        for r in vulnerable[:5]:  # Limit to 5
            message += f"• {r.domain} ({r.provider}, {r.confidence}% confidence)\n"
        
        if len(vulnerable) > 5:
            message += f"\n... and {len(vulnerable) - 5} more"
        
        payload = {"text": message}
        
        try:
            async with aiohttp.ClientSession() as session:
                async with session.post(webhook_url, json=payload) as resp:
                    if resp.status == 200:
                        logger.info("Webhook notification sent")
                    else:
                        logger.warning(f"Webhook failed: {resp.status}")
        except Exception as e:
            logger.error(f"Webhook error: {e}")
