"""
Morning Standup - Daily agent meeting minutes system.

This module provides the schema layer for the daily standup email
that simulates a team meeting between all LightWave agents.

Key Concepts:
    - StandupConfig: Configuration for standup generation
    - StandupSection: Individual section of the standup
    - AgentReport: Report from a single agent
    - StandupMinutes: Complete compiled standup
    - StandupArchive: Historical standup storage

Usage:
    from lightwave.schema.pydantic.sst import (
        StandupConfig,
        StandupMinutes,
        generate_standup,
    )

    # Load standup configuration
    config = StandupConfig.from_sst()

    # Generate today's standup (in Celery task)
    minutes = generate_standup(config)

    # Archive for historical tracking
    minutes.archive()
"""

from __future__ import annotations

from dataclasses import dataclass
from datetime import date as DateType
from datetime import datetime as DateTimeType
from enum import Enum
from functools import lru_cache
from pathlib import Path

import yaml
from pydantic import BaseModel, ConfigDict, Field

# =============================================================================
# ENUMS
# =============================================================================


class SectionFormat(str, Enum):
    """How a standup section is formatted."""

    NOTION_CALLOUT = "notion_callout"
    NOTION_TOGGLE = "notion_toggle"
    NOTION_CHECKLIST = "notion_checklist"
    NOTION_DATABASE_VIEW = "notion_database_view"
    NOTION_KANBAN = "notion_kanban"
    NOTION_QUOTE_BLOCKS = "notion_quote_blocks"
    NOTION_PROGRESS_BARS = "notion_progress_bars"
    NOTION_CALENDAR_VIEW = "notion_calendar_view"


class CalloutStyle(str, Enum):
    """Callout box color styles."""

    BLUE = "blue"
    YELLOW = "yellow"
    RED = "red"
    GREEN = "green"
    PURPLE = "purple"
    GRAY = "gray"


class AgentPerspective(str, Enum):
    """Agent's perspective in the roundtable."""

    SPRINT_PRIORITIES = "Sprint & Priorities"
    ARCHITECTURE_QUALITY = "Architecture & Quality"
    CREATIVE_VISION = "Creative Vision"
    FINANCIAL_HEALTH = "Financial Health"
    BRAND_VOICE = "Brand & Voice"
    INFRASTRUCTURE = "Infrastructure"
    CONTENT = "Content"


class HealthStatus(str, Enum):
    """Overall health status."""

    EXCELLENT = "excellent"  # 90-100
    GOOD = "good"  # 70-89
    ATTENTION = "attention"  # 50-69
    CRITICAL = "critical"  # 0-49


# =============================================================================
# AGENT REPORT SCHEMAS
# =============================================================================


class AgentInsight(BaseModel):
    """A single insight from an agent."""

    model_config = ConfigDict(extra="forbid")

    agent: str = Field(..., description="Agent that provided this insight")
    perspective: str = Field(..., description="Agent's perspective/focus area")
    insight: str = Field(..., description="The insight content")
    priority: int = Field(default=0, description="Priority level 0-10")
    action_suggested: str | None = Field(None, description="Suggested action")


class TaskRecommendation(BaseModel):
    """A recommended task for today."""

    model_config = ConfigDict(extra="forbid")

    task_id: str
    title: str
    reason: str = Field(..., description="Why this task is recommended")
    principle_alignment: float = Field(..., ge=0, le=100)
    estimated_effort: str | None = None
    affected_files_count: int = 0
    unlocks: list[str] = Field(default_factory=list, description="What this unlocks")


class UrgentItem(BaseModel):
    """An urgent item requiring attention."""

    model_config = ConfigDict(extra="forbid")

    id: str
    title: str
    urgency_reason: str
    due_date: DateType | None = None
    hours_overdue: float | None = None
    blocker_type: str | None = None


class PlatformStatus(BaseModel):
    """Platform deployment and health status."""

    model_config = ConfigDict(extra="forbid")

    deployment_status: str = "healthy"
    last_deploy: DateTimeType | None = None
    error_rate_24h: float = 0.0
    uptime_percentage: float = 100.0
    pending_prs: int = 0
    ci_status: str = "passing"


class FinancialSummary(BaseModel):
    """Financial summary for business ops."""

    model_config = ConfigDict(extra="forbid")

    invoices_pending: int = 0
    invoices_overdue: int = 0
    expected_income_this_month: float = 0.0
    expenses_to_categorize: int = 0

    # Good Boy Creative - Erin's loan-out (business partner)
    good_boy_creative_invoice_received: bool = False
    good_boy_creative_reminder: str | None = None

    # QuickBooks integration
    quickbooks_invoice_count: int = 0
    quickbooks_bookkeeper_tasks: int = 0
    quickbooks_bookkeeper_messages_pending: int = 0  # Messages Joel might miss


class PrincipleGap(BaseModel):
    """A gap in principle alignment."""

    model_config = ConfigDict(extra="forbid")

    principle_id: str
    principle_name: str
    current_score: float
    ideal_score: float = 100.0
    gap: float
    recommendation: str


class PrinciplesAlignment(BaseModel):
    """Overall principles alignment status."""

    model_config = ConfigDict(extra="forbid")

    overall_score: float = Field(..., ge=0, le=100)
    status: HealthStatus
    top_aligned: list[str] = Field(default_factory=list)
    gaps: list[PrincipleGap] = Field(default_factory=list)
    sources_evaluated: list[str] = Field(default_factory=list)


# =============================================================================
# SECTION SCHEMAS
# =============================================================================


class StandupSectionConfig(BaseModel):
    """Configuration for a standup section."""

    model_config = ConfigDict(extra="allow")  # Allow flexible config

    order: int
    icon: str
    title: str
    agent: str | None = None
    format: SectionFormat = SectionFormat.NOTION_TOGGLE
    show_if_empty: bool = True
    empty_message: str | None = None
    callout_style: CalloutStyle | None = None


class ExecutiveSummary(BaseModel):
    """The at-a-glance executive summary."""

    model_config = ConfigDict(extra="forbid")

    health_score: float = Field(..., ge=0, le=100)
    health_status: HealthStatus
    urgent_count: int = 0
    blocked_count: int = 0
    completed_yesterday: int = 0
    sprint_burn_rate: float = 0.0  # Percentage of sprint complete
    sprint_days_remaining: int = 0


class EngineeringGoals(BaseModel):
    """Today's engineering focus."""

    model_config = ConfigDict(extra="forbid")

    recommended_tasks: list[TaskRecommendation] = Field(default_factory=list)
    active_plans: list[str] = Field(default_factory=list)
    code_reviews_pending: int = 0


class CreativeVerticalStatus(BaseModel):
    """Status for a creative vertical (cineOS, photography, etc.)."""

    model_config = ConfigDict(extra="forbid")

    name: str
    icon: str
    active_projects: int = 0
    items_needing_attention: list[str] = Field(default_factory=list)
    principle_score: float | None = None
    highlights: list[str] = Field(default_factory=list)


# =============================================================================
# STANDUP MINUTES
# =============================================================================


class StandupMinutes(BaseModel):
    """Complete compiled standup minutes."""

    model_config = ConfigDict(extra="forbid")

    # Metadata
    standup_id: str = Field(..., description="Unique ID for this standup")
    generated_at: DateTimeType
    date: DateType
    day_of_week: str
    week_number: int

    # Header
    title: str
    subtitle: str
    quote_of_day: str | None = None

    # Sections
    executive_summary: ExecutiveSummary
    urgent_items: list[UrgentItem] = Field(default_factory=list)
    engineering_goals: EngineeringGoals
    platform_status: PlatformStatus
    creative_verticals: list[CreativeVerticalStatus] = Field(default_factory=list)
    financial_summary: FinancialSummary
    content_pipeline_summary: dict[str, int] = Field(default_factory=dict)
    agent_insights: list[AgentInsight] = Field(default_factory=list)
    principles_alignment: PrinciplesAlignment

    # Looking ahead
    deadlines_this_week: list[str] = Field(default_factory=list)
    sprint_end_date: DateType | None = None

    # Footer
    agents_consulted: list[str] = Field(default_factory=list)

    @property
    def is_healthy(self) -> bool:
        """Check if overall status is healthy."""
        return self.executive_summary.health_status in [
            HealthStatus.EXCELLENT,
            HealthStatus.GOOD,
        ]

    @property
    def needs_attention(self) -> bool:
        """Check if standup indicates items needing attention."""
        return (
            len(self.urgent_items) > 0
            or self.executive_summary.blocked_count > 0
            or self.executive_summary.health_status == HealthStatus.CRITICAL
        )

    def to_markdown(self) -> str:
        """Convert standup to markdown for archival."""
        lines = [
            f"# {self.title}",
            f"*{self.subtitle}*",
            "",
        ]

        if self.quote_of_day:
            lines.extend([f"> {self.quote_of_day}", ""])

        # Executive Summary
        lines.extend(
            [
                "## 📊 At a Glance",
                "",
                f"- **Health Score:** {self.executive_summary.health_score:.0f}/100 ({self.executive_summary.health_status.value})",
                f"- **Urgent:** {self.executive_summary.urgent_count}",
                f"- **Blocked:** {self.executive_summary.blocked_count}",
                f"- **Completed Yesterday:** {self.executive_summary.completed_yesterday}",
                f"- **Sprint Progress:** {self.executive_summary.sprint_burn_rate:.0f}%",
                "",
            ]
        )

        # Urgent Items
        if self.urgent_items:
            lines.extend(["## 🚨 Needs Attention", ""])
            for item in self.urgent_items:
                lines.append(f"- **{item.title}**: {item.urgency_reason}")
            lines.append("")

        # Engineering Goals
        lines.extend(["## 🎯 Today's Engineering Focus", ""])
        for task in self.engineering_goals.recommended_tasks:
            lines.append(f"- [ ] **{task.title}** ({task.principle_alignment:.0f}% aligned)")
            lines.append(f"  - {task.reason}")
        lines.append("")

        # Agent Roundtable
        lines.extend(["## 🤖 Agent Roundtable", ""])
        for insight in self.agent_insights:
            lines.append(f"> **{insight.agent}** ({insight.perspective}):")
            lines.append(f"> {insight.insight}")
            lines.append("")

        # Principles
        lines.extend(
            [
                "## ⚖️ Principles Alignment",
                "",
                f"**Overall Score:** {self.principles_alignment.overall_score:.0f}/100",
                "",
            ]
        )
        if self.principles_alignment.gaps:
            lines.append("**Gaps to Address:**")
            for gap in self.principles_alignment.gaps[:3]:
                lines.append(f"- {gap.principle_name}: {gap.recommendation}")
            lines.append("")

        # Footer
        lines.extend(
            [
                "---",
                f"*Generated at {self.generated_at.strftime('%Y-%m-%d %H:%M:%S')}*",
                f"*Agents consulted: {', '.join(self.agents_consulted)}*",
            ]
        )

        return "\n".join(lines)

    def to_html(self) -> str:
        """Convert standup to Notion-style HTML for email."""
        # This would be implemented with proper Notion-style templates
        # For now, return a placeholder
        return f"<h1>{self.title}</h1><p>Full HTML template to be implemented</p>"


# =============================================================================
# STANDUP CONFIGURATION
# =============================================================================


class StandupConfig(BaseModel):
    """Configuration loaded from SST for standup generation."""

    model_config = ConfigDict(extra="allow")  # YAML has many fields

    schedule: str = Field("0 9 * * *", description="Cron schedule")
    recipient: str = Field(..., description="Email recipient - from rbac.yaml")
    sender: str = Field(..., description="Email sender - from email.yaml")
    reply_to: str = Field(..., description="Reply-to address - from email.yaml")
    timezone: str = Field("America/Los_Angeles")
    skip_weekends: bool = False

    sections: dict[str, StandupSectionConfig] = Field(default_factory=dict)

    @classmethod
    def _resolve_sst_ref(cls, ref_data: dict | str, definitions_path: Path) -> str:
        """Resolve a $ref pointer to another SST file."""
        if isinstance(ref_data, str):
            return ref_data

        if not isinstance(ref_data, dict) or "$ref" not in ref_data:
            return str(ref_data)

        ref = ref_data["$ref"]
        # Parse ref like "rbac.yaml#/default_user_accounts/tenant_admin"
        file_part, path_part = ref.split("#")

        # Use SST registry to find the file path
        # Convert filename like "rbac.yaml" to registry key "rbac"
        from lightwave.schema.core.paths import get_sst_path

        sst_key = file_part.replace(".yaml", "").replace("-", "_")
        ref_file = get_sst_path(sst_key)

        with open(ref_file) as f:
            ref_data = yaml.safe_load(f)

        # Navigate the path
        path_parts = [p for p in path_part.split("/") if p]
        value = ref_data
        for part in path_parts:
            value = value[part]

        return str(value)

    @classmethod
    @lru_cache(maxsize=1)
    def from_sst(cls) -> "StandupConfig":
        """Load standup configuration from SST."""
        from lightwave.schema.core.paths import DEFINITIONS_DIR, get_sst_path

        definitions_path = DEFINITIONS_DIR
        yaml_path = get_sst_path("morning_standup")

        with open(yaml_path) as f:
            data = yaml.safe_load(f)

        meta = data.get("_meta", {})

        # Resolve SST references for email addresses
        recipient = cls._resolve_sst_ref(meta.get("recipient", {}), definitions_path)
        sender = cls._resolve_sst_ref(meta.get("sender", {}), definitions_path)
        reply_to = cls._resolve_sst_ref(meta.get("reply_to", {}), definitions_path)

        # Parse sections
        sections = {}
        for section_key, section_data in data.get("standup_sections", {}).items():
            if section_key in ["description", "header", "footer"]:
                continue
            if isinstance(section_data, dict) and "order" in section_data:
                sections[section_key] = StandupSectionConfig(**section_data)

        return cls(
            schedule=meta.get("schedule", "0 9 * * *"),
            recipient=recipient,
            sender=sender,
            reply_to=reply_to,
            timezone=data.get("preferences", {}).get("timezone", "America/Los_Angeles"),
            skip_weekends=data.get("preferences", {}).get("skip_weekends", False),
            sections=sections,
        )

    def get_section(self, name: str) -> StandupSectionConfig | None:
        """Get a section configuration by name."""
        return self.sections.get(name)

    def get_ordered_sections(self) -> list[tuple[str, StandupSectionConfig]]:
        """Get sections in display order."""
        return sorted(
            self.sections.items(),
            key=lambda x: x[1].order,
        )


# =============================================================================
# STANDUP ARCHIVE
# =============================================================================


@dataclass
class StandupArchiveEntry:
    """An entry in the standup archive."""

    standup_id: str
    date: DateType
    health_score: float
    urgent_count: int
    blocked_count: int
    completed_count: int
    principle_score: float
    file_path: str


class StandupArchive:
    """Manages historical standup storage and analysis."""

    def __init__(self, base_path: Path):
        self.base_path = base_path

    def save(self, minutes: StandupMinutes) -> str:
        """Save standup minutes to archive."""
        year = minutes.date.year
        month = minutes.date.strftime("%m")
        filename = f"{minutes.date.isoformat()}_standup.md"

        archive_dir = self.base_path / str(year) / month
        archive_dir.mkdir(parents=True, exist_ok=True)

        file_path = archive_dir / filename
        file_path.write_text(minutes.to_markdown())

        return str(file_path)

    def get_weekly_summary(self, week_start: DateType) -> list[StandupArchiveEntry]:
        """Get all standups for a given week."""
        # Implementation would query the archive
        return []

    def get_trend_data(self, days: int = 30) -> dict[str, list[float]]:
        """Get trend data for charts."""
        return {
            "health_scores": [],
            "principle_scores": [],
            "completion_rates": [],
        }


# =============================================================================
# CONVENIENCE FUNCTIONS
# =============================================================================


def get_standup_config() -> StandupConfig:
    """Get the standup configuration (cached)."""
    return StandupConfig.from_sst()


def create_empty_standup(standup_date: DateType | None = None) -> StandupMinutes:
    """Create an empty standup template for the given date."""
    from uuid import uuid4

    if standup_date is None:
        standup_date = DateType.today()

    return StandupMinutes(
        standup_id=str(uuid4())[:8],
        generated_at=DateTimeType.now(),
        date=standup_date,
        day_of_week=standup_date.strftime("%A"),
        week_number=standup_date.isocalendar()[1],
        title=f"Good Morning, Joel - {standup_date.strftime('%B %d, %Y')}",
        subtitle=f"{standup_date.strftime('%A')} Standup | Week {standup_date.isocalendar()[1]}",
        executive_summary=ExecutiveSummary(
            health_score=100,
            health_status=HealthStatus.EXCELLENT,
        ),
        engineering_goals=EngineeringGoals(),
        platform_status=PlatformStatus(),
        financial_summary=FinancialSummary(),
        principles_alignment=PrinciplesAlignment(
            overall_score=100,
            status=HealthStatus.EXCELLENT,
        ),
        agents_consulted=[],
    )


# =============================================================================
# MODULE EXPORTS
# =============================================================================

__all__ = [
    # Enums
    "SectionFormat",
    "CalloutStyle",
    "AgentPerspective",
    "HealthStatus",
    # Report schemas
    "AgentInsight",
    "TaskRecommendation",
    "UrgentItem",
    "PlatformStatus",
    "FinancialSummary",
    "PrincipleGap",
    "PrinciplesAlignment",
    # Section schemas
    "StandupSectionConfig",
    "ExecutiveSummary",
    "EngineeringGoals",
    "CreativeVerticalStatus",
    # Main schemas
    "StandupMinutes",
    "StandupConfig",
    # Archive
    "StandupArchiveEntry",
    "StandupArchive",
    # Functions
    "get_standup_config",
    "create_empty_standup",
]
