"""Track planfile execution progress in proxym dashboard.

Receives status updates from llx task execution and
updates proxym's ticket system accordingly.
"""

from pathlib import Path
from typing import Any

import time
import yaml
import structlog

from proxym.dashboard._tickets_api import _tickets
from proxym.dashboard.tickets import TicketStatus

logger = structlog.get_logger()


def update_task_status(
    ticket_id: str,
    status: str,
    model_used: str | None = None,
    validation_score: float | None = None,
    files_changed: list[str] | None = None,
    error: str | None = None,
) -> None:
    """Update a proxym ticket based on llx task execution result."""
    try:
        mgr = _tickets()
        ticket = mgr.get_ticket(ticket_id)
        if not ticket:
            logger.warning("ticket_not_found_for_update", ticket_id=ticket_id)
            return
        
        # Map status string to TicketStatus enum
        status_map = {
            "todo": TicketStatus.TODO,
            "in_progress": TicketStatus.IN_PROGRESS,
            "done": TicketStatus.DONE,
            "failed": TicketStatus.CANCELLED,
            "cancelled": TicketStatus.CANCELLED,
        }
        
        new_status = status_map.get(status.lower(), TicketStatus.TODO)
        
        # Prepare updates
        updates = {
            "status": new_status,
        }
        
        # Update metadata with execution results
        metadata = ticket.metadata or {}
        if metadata.get("source") == "planfile":
            if model_used:
                metadata["model_used"] = model_used
            if validation_score is not None:
                metadata["validation_score"] = validation_score
            if files_changed:
                metadata["files_changed"] = files_changed
            if error:
                metadata["error"] = error
            updates["metadata"] = metadata
        
        # Update completion timestamp if done
        if new_status == TicketStatus.DONE:
            updates["completed_at"] = time.time()
        
        mgr.update_ticket(ticket_id, **updates)
        logger.info("ticket_updated_from_planfile", 
                   ticket_id=ticket_id, 
                   status=status,
                   model_used=model_used)
        
    except Exception as exc:
        logger.error("failed_to_update_ticket_status", 
                    ticket_id=ticket_id,
                    error=str(exc))


def check_quality_gates(
    strategy_path: str,
    project_path: str = ".",
) -> list[dict]:
    """Check quality gates from strategy against current project state.

    Uses llx.analyze_project for current metrics, compares against
    strategy thresholds.
    """
    strategy = yaml.safe_load(Path(strategy_path).read_text())
    gates = strategy.get("quality_gates", [])

    try:
        from llx import analyze_project
        metrics = analyze_project(project_path)
        current = {
            "avg_cc": metrics.avg_cc,
            "max_cc": metrics.max_cc,
            "god_modules": metrics.god_modules,
            "critical_count": metrics.critical_count,
            "dup_groups": metrics.dup_groups,
        }
        logger.info("project_metrics_analyzed", project=project_path, metrics=current)
    except ImportError:
        logger.warning("llx_not_available_for_quality_check")
        current = {}
    except Exception as exc:
        logger.error("failed_to_analyze_project", error=str(exc))
        current = {}

    results = []
    for gate in gates:
        metric_name = gate.get("metric", "")
        threshold = gate.get("threshold", 0)
        operator = gate.get("operator", "<=")
        actual = current.get(metric_name, None)

        passed = False
        if actual is not None:
            if operator == "<=":
                passed = actual <= threshold
            elif operator == ">=":
                passed = actual >= threshold
            elif operator == "==":
                passed = actual == threshold
            elif operator == "<":
                passed = actual < threshold
            elif operator == ">":
                passed = actual > threshold

        results.append({
            "name": gate.get("name", metric_name),
            "metric": metric_name,
            "threshold": threshold,
            "actual": actual,
            "operator": operator,
            "passed": passed,
            "description": gate.get("description", ""),
        })

    logger.info("quality_gates_checked", 
                strategy_path=strategy_path,
                total_gates=len(gates),
                passed=sum(1 for r in results if r["passed"]))
    return results


def get_strategy_progress(project_name: str) -> dict:
    """Get execution progress of imported strategy for a project."""
    try:
        mgr = _tickets()
        # Get tickets with source=planfile for this project
        all_tickets = mgr.list_tickets(project_id=project_name)
        
        planfile_tickets = [
            t for t in all_tickets 
            if t.metadata and t.metadata.get("source") == "planfile"
        ]
        
        total = len(planfile_tickets)
        if total == 0:
            return {
                "project": project_name,
                "total_tasks": 0,
                "completed": 0,
                "in_progress": 0,
                "remaining": 0,
                "progress_pct": 0,
            }
        
        done = sum(1 for t in planfile_tickets if t.status == TicketStatus.DONE)
        in_progress = sum(1 for t in planfile_tickets if t.status == TicketStatus.IN_PROGRESS)
        
        return {
            "project": project_name,
            "total_tasks": total,
            "completed": done,
            "in_progress": in_progress,
            "remaining": total - done - in_progress,
            "progress_pct": round(done / total * 100, 1),
        }
        
    except Exception as exc:
        logger.error("failed_to_get_strategy_progress", 
                    project=project_name,
                    error=str(exc))
        return {
            "project": project_name,
            "total_tasks": 0,
            "completed": 0,
            "in_progress": 0,
            "remaining": 0,
            "progress_pct": 0,
        }
