"""
Report Generator - Generate Markdown intelligence reports

Generates comprehensive investigation reports in Markdown format with
proper structure, artifacts tables, and actionable recommendations.
"""

from datetime import datetime
from pathlib import Path
from typing import Optional

from groknroll.osint.artifact_extractor import Artifact
from groknroll.osint.content_scraper import ScrapedContent
from groknroll.osint.dark_web_search import SearchResult
from groknroll.osint.intelligence_analyzer import IntelligenceReport


class ReportGenerator:
    """
    Generate Markdown intelligence reports for OSINT investigations.

    Creates structured reports with:
    - Executive summary
    - Search results table
    - Extracted artifacts
    - Key findings and recommendations

    Usage:
        generator = ReportGenerator()
        report = generator.generate(investigation, results, artifacts)
        generator.save(report, Path("output/report.md"))
    """

    REPORT_TEMPLATE = """# OSINT Investigation Report

**Query:** {query}
**Refined Query:** {refined_query}
**Generated:** {timestamp}
**Status:** {status}

---

## Executive Summary

{summary}

---

## Investigation Statistics

| Metric | Value |
|--------|-------|
| Search Engines Used | {engines_used} |
| Results Found | {results_count} |
| Pages Scraped | {scraped_count} |
| Artifacts Extracted | {artifacts_count} |

---

## Key Findings

{key_findings}

---

## Threat Indicators

{threat_indicators}

---

## Search Results

{results_table}

---

## Extracted Artifacts

{artifacts_section}

---

## Recommendations

{recommendations}

---

## Source URLs

{source_urls}

---

*Report generated by groknroll OSINT*
"""

    def __init__(self, output_dir: Optional[Path] = None):
        """
        Initialize report generator.

        Args:
            output_dir: Default output directory for reports
        """
        self.output_dir = output_dir or Path("osint_reports")

    def generate(
        self,
        query: str,
        refined_query: str,
        results: list[SearchResult],
        scraped_contents: list[ScrapedContent],
        artifacts: list[Artifact],
        report: Optional[IntelligenceReport] = None,
        status: str = "complete",
    ) -> str:
        """
        Generate full investigation report in Markdown format.

        Args:
            query: Original investigation query
            refined_query: LLM-refined query
            results: Search results from dark web engines
            scraped_contents: Scraped page contents
            artifacts: Extracted intelligence artifacts
            report: Optional IntelligenceReport from analyzer
            status: Investigation status

        Returns:
            Markdown report string
        """
        timestamp = datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S UTC")

        # Build results table
        results_table = self._build_results_table(results[:50])

        # Build artifacts section
        artifacts_section = self._build_artifacts_section(artifacts)

        # Build source URLs list
        source_urls = self._build_source_urls(results)

        # Get unique engines
        engines = set(r.source_engine for r in results)

        # Format key findings
        key_findings = "- No key findings generated"
        if report and report.key_findings:
            key_findings = "\n".join(f"- {f}" for f in report.key_findings)

        # Format threat indicators
        threat_indicators = "- No threat indicators identified"
        if report and report.threat_indicators:
            threat_indicators = "\n".join(f"- {i}" for i in report.threat_indicators)

        # Format recommendations
        recommendations = "- Review extracted artifacts manually"
        if report and report.recommendations:
            recommendations = "\n".join(f"- {r}" for r in report.recommendations)

        # Get summary
        summary = "Investigation complete. Review findings below."
        if report and report.summary:
            summary = report.summary

        return self.REPORT_TEMPLATE.format(
            query=query,
            refined_query=refined_query,
            timestamp=timestamp,
            status=status,
            summary=summary,
            engines_used=len(engines),
            results_count=len(results),
            scraped_count=len([c for c in scraped_contents if c.success]),
            artifacts_count=len(artifacts),
            key_findings=key_findings,
            threat_indicators=threat_indicators,
            results_table=results_table,
            artifacts_section=artifacts_section,
            recommendations=recommendations,
            source_urls=source_urls,
        )

    def _build_results_table(self, results: list[SearchResult]) -> str:
        """Build Markdown table of search results."""
        if not results:
            return "*No results found*"

        lines = [
            "| # | Title | URL | Source |",
            "|---|-------|-----|--------|",
        ]

        for i, r in enumerate(results, 1):
            title = r.title[:40] + "..." if len(r.title) > 40 else r.title
            title = title.replace("|", "\\|")
            url = r.url[:50] + "..." if len(r.url) > 50 else r.url
            lines.append(f"| {i} | {title} | {url} | {r.source_engine} |")

        return "\n".join(lines)

    def _build_artifacts_section(self, artifacts: list[Artifact]) -> str:
        """Build artifacts section organized by type."""
        if not artifacts:
            return "*No artifacts extracted*"

        # Group by type
        by_type: dict[str, list[Artifact]] = {}
        for artifact in artifacts:
            art_type = artifact.artifact_type
            if art_type not in by_type:
                by_type[art_type] = []
            by_type[art_type].append(artifact)

        sections = []
        for art_type, type_artifacts in sorted(by_type.items()):
            section = f"### {art_type.upper()} ({len(type_artifacts)})\n\n"
            section += "| Value | Confidence | Context |\n"
            section += "|-------|------------|---------||\n"

            for artifact in type_artifacts[:20]:  # Limit per type
                value = artifact.value[:50]
                context = artifact.context[:40].replace("|", "\\|") if artifact.context else "-"
                section += f"| `{value}` | {artifact.confidence:.0%} | {context} |\n"

            if len(type_artifacts) > 20:
                section += f"\n*... and {len(type_artifacts) - 20} more*\n"

            sections.append(section)

        return "\n".join(sections)

    def _build_source_urls(self, results: list[SearchResult]) -> str:
        """Build numbered list of source URLs."""
        if not results:
            return "*No sources*"

        lines = []
        for i, r in enumerate(results[:30], 1):
            lines.append(f"{i}. {r.url}")

        if len(results) > 30:
            lines.append(f"\n*... and {len(results) - 30} more*")

        return "\n".join(lines)

    def save(self, report: str, output_path: Optional[Path] = None) -> Path:
        """
        Save report to file.

        Args:
            report: Markdown report content
            output_path: Target file path (auto-generated if not provided)

        Returns:
            Path to saved report file
        """
        if output_path is None:
            self.output_dir.mkdir(parents=True, exist_ok=True)
            timestamp = datetime.utcnow().strftime("%Y%m%d_%H%M%S")
            output_path = self.output_dir / f"osint_report_{timestamp}.md"

        # Ensure parent directory exists
        output_path.parent.mkdir(parents=True, exist_ok=True)

        with open(output_path, "w", encoding="utf-8") as f:
            f.write(report)

        return output_path

    def generate_json(
        self,
        query: str,
        refined_query: str,
        results: list[SearchResult],
        scraped_contents: list[ScrapedContent],
        artifacts: list[Artifact],
        report: Optional[IntelligenceReport] = None,
    ) -> dict:
        """
        Generate report data as JSON-serializable dictionary.

        Args:
            query: Original investigation query
            refined_query: LLM-refined query
            results: Search results
            scraped_contents: Scraped contents
            artifacts: Extracted artifacts
            report: Intelligence report

        Returns:
            Dictionary with all investigation data
        """
        return {
            "metadata": {
                "query": query,
                "refined_query": refined_query,
                "generated_at": datetime.utcnow().isoformat(),
                "results_count": len(results),
                "scraped_count": len([c for c in scraped_contents if c.success]),
                "artifacts_count": len(artifacts),
            },
            "results": [r.to_dict() for r in results],
            "scraped_contents": [c.to_dict() for c in scraped_contents],
            "artifacts": [a.to_dict() for a in artifacts],
            "report": report.to_dict() if report else None,
        }
