"""
Executive Report - Korean-language executive summary generation
===============================================================
Purpose: Generate stakeholder-ready executive summaries in Korean from
         aggregated SEO report data, with audience-specific detail levels
         for C-level, marketing, and technical teams.
Python: 3.10+

Usage:
    python executive_report.py --report aggregated_report.json --audience c-level --output report.md
    python executive_report.py --report aggregated_report.json --audience marketing --output report.md
    python executive_report.py --report aggregated_report.json --audience technical --output report.md
    python executive_report.py --report aggregated_report.json --audience c-level --format notion
"""

import argparse
import json
import logging
import sys
from dataclasses import dataclass, field
from datetime import datetime
from pathlib import Path
from typing import Any

logger = logging.getLogger(__name__)

logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s - %(levelname)s - %(message)s",
)


# ---------------------------------------------------------------------------
# Data classes
# ---------------------------------------------------------------------------

@dataclass
class AudienceConfig:
    """Configuration for report audience targeting."""
    level: str = "c-level"  # c-level | marketing | technical
    detail_depth: str = "summary"  # summary | moderate | detailed
    include_recommendations: bool = True
    include_technical_details: bool = False
    max_issues: int = 5
    max_recommendations: int = 5

    @classmethod
    def from_level(cls, level: str) -> "AudienceConfig":
        """Create config preset from audience level."""
        presets = {
            "c-level": cls(
                level="c-level",
                detail_depth="summary",
                include_recommendations=True,
                include_technical_details=False,
                max_issues=5,
                max_recommendations=3,
            ),
            "marketing": cls(
                level="marketing",
                detail_depth="moderate",
                include_recommendations=True,
                include_technical_details=False,
                max_issues=10,
                max_recommendations=5,
            ),
            "technical": cls(
                level="technical",
                detail_depth="detailed",
                include_recommendations=True,
                include_technical_details=True,
                max_issues=20,
                max_recommendations=10,
            ),
        }
        return presets.get(level, presets["c-level"])


@dataclass
class ExecutiveSummary:
    """Generated executive summary content."""
    title: str = ""
    domain: str = ""
    period: str = ""
    health_score: float = 0.0
    health_trend: str = "stable"
    key_wins: list[str] = field(default_factory=list)
    key_concerns: list[str] = field(default_factory=list)
    recommendations: list[str] = field(default_factory=list)
    narrative: str = ""
    audience: str = "c-level"
    category_summary: dict[str, str] = field(default_factory=dict)
    audit_id: str = ""
    timestamp: str = ""


# ---------------------------------------------------------------------------
# Korean text templates
# ---------------------------------------------------------------------------

HEALTH_LABELS_KR = {
    "excellent": "우수",
    "good": "양호",
    "average": "보통",
    "poor": "미흡",
    "critical": "위험",
}

TREND_LABELS_KR = {
    "improving": "개선 중",
    "stable": "안정",
    "declining": "하락 중",
}

CATEGORY_LABELS_KR = {
    "technical": "기술 SEO",
    "on_page": "온페이지 SEO",
    "performance": "성능 (Core Web Vitals)",
    "content": "콘텐츠 전략",
    "links": "링크 프로필",
    "local": "로컬 SEO",
    "keywords": "키워드 전략",
    "competitor": "경쟁 분석",
    "schema": "스키마/구조화 데이터",
    "kpi": "KPI 프레임워크",
    "search_console": "서치 콘솔",
    "ecommerce": "이커머스 SEO",
    "international": "국제 SEO",
    "ai_search": "AI 검색 가시성",
    "entity_seo": "지식 그래프",
}

# Common English issue descriptions -> Korean translations
ISSUE_TRANSLATIONS_KR: dict[str, str] = {
    "missing meta description": "메타 설명(meta description) 누락",
    "missing title tag": "타이틀 태그 누락",
    "duplicate title": "중복 타이틀 태그",
    "duplicate meta description": "중복 메타 설명",
    "missing h1": "H1 태그 누락",
    "multiple h1 tags": "H1 태그 다수 사용",
    "missing alt text": "이미지 alt 텍스트 누락",
    "broken links": "깨진 링크 발견",
    "redirect chain": "리다이렉트 체인 발견",
    "mixed content": "Mixed Content (HTTP/HTTPS 혼합) 발견",
    "missing canonical": "Canonical 태그 누락",
    "noindex on important page": "중요 페이지에 noindex 설정됨",
    "slow page load": "페이지 로딩 속도 저하",
    "cls exceeds threshold": "CLS(누적 레이아웃 변경) 임계값 초과",
    "lcp exceeds threshold": "LCP(최대 콘텐츠풀 페인트) 임계값 초과",
    "missing sitemap": "사이트맵 누락",
    "robots.txt blocking important pages": "robots.txt에서 중요 페이지 차단 중",
    "missing schema markup": "스키마 마크업 누락",
    "missing hreflang": "hreflang 태그 누락",
    "thin content": "콘텐츠 부족 (Thin Content)",
    "orphan pages": "고아 페이지 발견 (내부 링크 없음)",
}


def _translate_description(desc: str) -> str:
    """Translate common English issue descriptions to Korean."""
    desc_lower = desc.lower().strip()
    # Check exact match
    if desc_lower in ISSUE_TRANSLATIONS_KR:
        return ISSUE_TRANSLATIONS_KR[desc_lower]
    # Check partial match (case-insensitive replace)
    for eng, kor in ISSUE_TRANSLATIONS_KR.items():
        if eng in desc_lower:
            # Find the original-case substring and replace it
            idx = desc_lower.index(eng)
            return desc[:idx] + kor + desc[idx + len(eng):]
    return desc


AUDIENCE_INTRO_KR = {
    "c-level": "본 보고서는 SEO 성과의 핵심 지표와 비즈니스 영향을 요약한 경영진용 보고서입니다.",
    "marketing": "본 보고서는 SEO 전략 실행 현황과 마케팅 성과를 분석한 마케팅팀 보고서입니다.",
    "technical": "본 보고서는 SEO 기술 진단 결과와 상세 개선 사항을 포함한 기술팀 보고서입니다.",
}


# ---------------------------------------------------------------------------
# Generator
# ---------------------------------------------------------------------------

class ExecutiveReportGenerator:
    """Generate Korean-language executive reports from aggregated SEO data."""

    @staticmethod
    def _health_grade(score: float) -> str:
        """Return health grade string."""
        if score >= 90:
            return "excellent"
        elif score >= 75:
            return "good"
        elif score >= 60:
            return "average"
        elif score >= 40:
            return "poor"
        else:
            return "critical"

    def generate_narrative(
        self,
        report: dict[str, Any],
        audience: AudienceConfig,
    ) -> str:
        """Generate Korean narrative text for the executive summary."""
        domain = report.get("domain", "")
        health = report.get("overall_health", 0)
        trend = report.get("health_trend", "stable")
        grade = self._health_grade(health)
        grade_kr = HEALTH_LABELS_KR.get(grade, grade)
        trend_kr = TREND_LABELS_KR.get(trend, trend)

        intro = AUDIENCE_INTRO_KR.get(audience.level, AUDIENCE_INTRO_KR["c-level"])

        # Build narrative paragraphs
        paragraphs = []

        # Opening
        paragraphs.append(intro)

        # Health overview
        paragraphs.append(
            f"{domain}의 전체 SEO Health Score는 **{health}/100** ({grade_kr})이며, "
            f"현재 추세는 **{trend_kr}** 상태입니다."
        )

        # Category highlights
        cat_scores = report.get("category_scores", {})
        if cat_scores:
            strong_cats = [
                CATEGORY_LABELS_KR.get(k, k)
                for k, v in cat_scores.items()
                if v >= 75
            ]
            weak_cats = [
                CATEGORY_LABELS_KR.get(k, k)
                for k, v in cat_scores.items()
                if v < 50
            ]

            if strong_cats:
                paragraphs.append(
                    f"강점 영역: {', '.join(strong_cats[:3])} 등이 양호한 성과를 보이고 있습니다."
                )
            if weak_cats:
                paragraphs.append(
                    f"개선 필요 영역: {', '.join(weak_cats[:3])} 등에서 집중적인 개선이 필요합니다."
                )

        # Skills coverage
        skills = report.get("skills_included", [])
        if skills:
            paragraphs.append(
                f"총 {len(skills)}개의 SEO 진단 도구를 통해 종합 분석을 수행하였습니다."
            )

        # C-level specific: business impact focus
        if audience.level == "c-level":
            if trend == "improving":
                paragraphs.append(
                    "전반적인 SEO 성과가 개선 추세에 있으며, 현재 전략을 유지하면서 "
                    "핵심 약점 영역에 대한 집중 투자가 권장됩니다."
                )
            elif trend == "declining":
                paragraphs.append(
                    "SEO 성과가 하락 추세를 보이고 있어, 원인 분석과 함께 "
                    "긴급한 대응 조치가 필요합니다."
                )
            else:
                paragraphs.append(
                    "SEO 성과가 안정적으로 유지되고 있으나, 경쟁 환경 변화에 대비하여 "
                    "지속적인 모니터링과 선제적 대응이 필요합니다."
                )

        # Marketing specific: channel and content focus
        elif audience.level == "marketing":
            top_issues = report.get("top_issues", [])
            content_issues = [
                i for i in top_issues if i.get("category") in ("content", "keywords")
            ]
            if content_issues:
                paragraphs.append(
                    f"콘텐츠/키워드 관련 이슈가 {len(content_issues)}건 발견되었으며, "
                    f"콘텐츠 전략 수정이 권장됩니다."
                )

        # Technical specific: detailed breakdown
        elif audience.level == "technical":
            for cat, score in sorted(
                cat_scores.items(), key=lambda x: x[1]
            ):
                cat_kr = CATEGORY_LABELS_KR.get(cat, cat)
                paragraphs.append(f"- {cat_kr}: {score}/100")

        return "\n\n".join(paragraphs)

    def format_wins(self, report: dict[str, Any]) -> list[str]:
        """Extract and format key wins in Korean."""
        wins = report.get("top_wins", [])
        formatted: list[str] = []

        for win in wins:
            desc = _translate_description(win.get("description", ""))
            cat = win.get("category", "")
            cat_kr = CATEGORY_LABELS_KR.get(cat, cat)

            if desc:
                formatted.append(f"[{cat_kr}] {desc}")

        return formatted

    def format_concerns(self, report: dict[str, Any]) -> list[str]:
        """Extract and format key concerns in Korean."""
        issues = report.get("top_issues", [])
        formatted: list[str] = []

        severity_kr = {
            "critical": "긴급",
            "high": "높음",
            "medium": "보통",
            "low": "낮음",
        }

        for issue in issues:
            desc = _translate_description(issue.get("description", ""))
            severity = issue.get("severity", "medium")
            cat = issue.get("category", "")
            sev_kr = severity_kr.get(severity, severity)
            cat_kr = CATEGORY_LABELS_KR.get(cat, cat)

            if desc:
                formatted.append(f"[{sev_kr}] [{cat_kr}] {desc}")

        return formatted

    def generate_recommendations(
        self,
        report: dict[str, Any],
        audience: AudienceConfig,
    ) -> list[str]:
        """Generate prioritized action items ranked by impact."""
        recommendations: list[str] = []
        cat_scores = report.get("category_scores", {})
        top_issues = report.get("top_issues", [])

        # Priority 1: Critical issues
        critical = [i for i in top_issues if i.get("severity") == "critical"]
        for issue in critical[:3]:
            cat_kr = CATEGORY_LABELS_KR.get(issue.get("category", ""), "")
            desc = _translate_description(issue.get("description", ""))
            if audience.level == "c-level":
                recommendations.append(
                    f"[긴급] {cat_kr} 영역 긴급 조치 필요 - {desc}"
                )
            else:
                recommendations.append(
                    f"[긴급] {desc} (영역: {cat_kr})"
                )

        # Priority 2: Weak categories
        weak_cats = sorted(
            [(k, v) for k, v in cat_scores.items() if v < 50],
            key=lambda x: x[1],
        )
        for cat, score in weak_cats[:3]:
            cat_kr = CATEGORY_LABELS_KR.get(cat, cat)
            if audience.level == "c-level":
                recommendations.append(
                    f"[개선] {cat_kr} 점수 {score}/100 - 전략적 투자 권장"
                )
            elif audience.level == "marketing":
                recommendations.append(
                    f"[개선] {cat_kr} ({score}/100) - 캠페인 전략 재검토 필요"
                )
            else:
                recommendations.append(
                    f"[개선] {cat_kr} ({score}/100) - 상세 진단 및 기술적 개선 필요"
                )

        # Priority 3: Maintenance for good categories
        strong_cats = [
            (k, v) for k, v in cat_scores.items() if v >= 75
        ]
        if strong_cats:
            cats_kr = ", ".join(
                CATEGORY_LABELS_KR.get(k, k) for k, _ in strong_cats[:3]
            )
            recommendations.append(
                f"[유지] {cats_kr} - 현재 수준 유지 및 모니터링 지속"
            )

        # Audience-specific recommendations
        if audience.level == "c-level":
            health = report.get("overall_health", 0)
            if health < 60:
                recommendations.append(
                    "[전략] SEO 개선을 위한 전문 인력 또는 외부 에이전시 투입 검토"
                )
        elif audience.level == "marketing":
            recommendations.append(
                "[실행] 다음 분기 SEO 개선 로드맵 수립 및 KPI 설정"
            )
        elif audience.level == "technical":
            recommendations.append(
                "[실행] 기술 부채 해소 스프린트 계획 수립"
            )

        return recommendations[:audience.max_recommendations]

    def render_markdown(self, summary: ExecutiveSummary) -> str:
        """Render executive summary as markdown document."""
        lines: list[str] = []

        # Title
        lines.append(f"# {summary.title}")
        lines.append("")

        # Meta
        audience_kr = {
            "c-level": "경영진",
            "marketing": "마케팅팀",
            "technical": "기술팀",
        }
        lines.append(f"**대상**: {audience_kr.get(summary.audience, summary.audience)}")
        lines.append(f"**도메인**: {summary.domain}")
        lines.append(f"**보고 일자**: {summary.period}")
        lines.append(f"**Audit ID**: {summary.audit_id}")
        lines.append("")

        # Health Score
        grade = self._health_grade(summary.health_score)
        grade_kr = HEALTH_LABELS_KR.get(grade, grade)
        trend_kr = TREND_LABELS_KR.get(summary.health_trend, summary.health_trend)

        lines.append("## 종합 건강 점수")
        lines.append("")
        lines.append(f"| 지표 | 값 |")
        lines.append(f"|------|-----|")
        lines.append(f"| 종합 점수 | **{summary.health_score}/100** |")
        lines.append(f"| 등급 | {grade_kr} |")
        lines.append(f"| 추세 | {trend_kr} |")
        lines.append("")

        # Category summary
        if summary.category_summary:
            lines.append("## 영역별 점수")
            lines.append("")
            lines.append("| 영역 | 점수 |")
            lines.append("|------|------|")
            for cat, score_str in summary.category_summary.items():
                cat_kr = CATEGORY_LABELS_KR.get(cat, cat)
                lines.append(f"| {cat_kr} | {score_str} |")
            lines.append("")

        # Narrative
        lines.append("## 종합 분석")
        lines.append("")
        lines.append(summary.narrative)
        lines.append("")

        # Key wins
        if summary.key_wins:
            lines.append("## 주요 성과")
            lines.append("")
            for win in summary.key_wins:
                lines.append(f"- {win}")
            lines.append("")

        # Key concerns
        if summary.key_concerns:
            lines.append("## 주요 이슈")
            lines.append("")
            for concern in summary.key_concerns:
                lines.append(f"- {concern}")
            lines.append("")

        # Recommendations
        if summary.recommendations:
            lines.append("## 권장 조치 사항")
            lines.append("")
            for i, rec in enumerate(summary.recommendations, 1):
                lines.append(f"{i}. {rec}")
            lines.append("")

        # Footer
        lines.append("---")
        lines.append(
            f"*이 보고서는 SEO Reporting Dashboard (Skill 34)에 의해 "
            f"{summary.timestamp}에 자동 생성되었습니다.*"
        )

        return "\n".join(lines)

    def run(
        self,
        report_json: str,
        audience_level: str = "c-level",
        output_path: str | None = None,
        output_format: str = "markdown",
    ) -> str:
        """Orchestrate executive report generation."""
        # Load report
        report_path = Path(report_json)
        if not report_path.exists():
            raise FileNotFoundError(f"Report file not found: {report_json}")

        report = json.loads(report_path.read_text(encoding="utf-8"))
        logger.info(f"Loaded report: {report.get('domain', 'unknown')}")

        # Configure audience
        audience = AudienceConfig.from_level(audience_level)
        logger.info(f"Audience: {audience.level} (depth: {audience.detail_depth})")

        # Build summary
        domain = report.get("domain", "")
        summary = ExecutiveSummary(
            title=f"SEO 성과 보고서 - {domain}",
            domain=domain,
            period=report.get("report_date", ""),
            health_score=report.get("overall_health", 0),
            health_trend=report.get("health_trend", "stable"),
            audit_id=report.get("audit_id", ""),
            audience=audience.level,
            timestamp=datetime.now().isoformat(),
        )

        # Category summary
        cat_scores = report.get("category_scores", {})
        summary.category_summary = {
            cat: f"{score}/100"
            for cat, score in sorted(
                cat_scores.items(), key=lambda x: x[1], reverse=True
            )
        }

        # Generate content
        summary.narrative = self.generate_narrative(report, audience)
        summary.key_wins = self.format_wins(report)[:audience.max_issues]
        summary.key_concerns = self.format_concerns(report)[:audience.max_issues]
        summary.recommendations = self.generate_recommendations(report, audience)

        # Render
        if output_format == "markdown":
            content = self.render_markdown(summary)
        elif output_format == "notion":
            # For Notion, we output markdown that can be pasted into Notion
            content = self.render_markdown(summary)
            logger.info(
                "Notion format: use MCP tools to push this markdown to Notion "
                f"database {report.get('audit_id', 'DASH-YYYYMMDD-NNN')}"
            )
        else:
            content = self.render_markdown(summary)

        # Save or print
        if output_path:
            Path(output_path).write_text(content, encoding="utf-8")
            logger.info(f"Executive report saved to {output_path}")
        else:
            print(content)

        return content


# ---------------------------------------------------------------------------
# CLI
# ---------------------------------------------------------------------------

def parse_args(argv: list[str] | None = None) -> argparse.Namespace:
    parser = argparse.ArgumentParser(
        description="SEO Executive Report - Korean-language executive summary generator",
        formatter_class=argparse.RawDescriptionHelpFormatter,
        epilog="""\
Examples:
  python executive_report.py --report aggregated_report.json --audience c-level --output report.md
  python executive_report.py --report aggregated_report.json --audience marketing --output report.md
  python executive_report.py --report aggregated_report.json --audience technical --format notion
        """,
    )
    parser.add_argument(
        "--report",
        required=True,
        help="Path to aggregated report JSON file (from report_aggregator.py)",
    )
    parser.add_argument(
        "--audience",
        choices=["c-level", "marketing", "technical"],
        default="c-level",
        help="Target audience level (default: c-level)",
    )
    parser.add_argument(
        "--output",
        type=str,
        default=None,
        help="Output file path (prints to stdout if omitted)",
    )
    parser.add_argument(
        "--format",
        choices=["markdown", "notion"],
        default="markdown",
        dest="output_format",
        help="Output format (default: markdown)",
    )
    return parser.parse_args(argv)


def main() -> None:
    args = parse_args()

    generator = ExecutiveReportGenerator()
    generator.run(
        report_json=args.report,
        audience_level=args.audience,
        output_path=args.output,
        output_format=args.output_format,
    )


if __name__ == "__main__":
    main()
