"""
Decision logging and tracking functionality
"""

import json
import os
from pathlib import Path
from typing import Any, Dict, List, Optional


class DecisionLogger:
    """
    Logger for tracking decision-making process

    This logger records all decisions made by the Agent, including performance
    analysis, issue identification, and improvement plans. It provides a complete
    audit trail for debugging and analysis.
    """

    def __init__(self, log_path: str = "logs/decisions"):
        """
        Initialize the decision logger

        Args:
            log_path: Path to store decision logs
        """
        self.log_path = Path(log_path)
        self.log_path.mkdir(parents=True, exist_ok=True)
        self.current_log_file = self.log_path / "decisions.jsonl"

    def log_decision(
        self,
        decision_type: str,
        input_data: Dict[str, Any],
        output_data: Dict[str, Any],
        metadata: Dict[str, Any],
    ) -> None:
        """
        Log a decision to the log file

        Args:
            decision_type: Type of decision (e.g., 'performance_analysis', 'issue_identification')
            input_data: Input data used for the decision
            output_data: Output/result of the decision
            metadata: Additional metadata (timestamp, model version, etc.)
        """
        import time

        log_entry = {
            "decision_type": decision_type,
            "timestamp": metadata.get("timestamp", int(time.time())),
            "input": input_data,
            "output": output_data,
            "metadata": metadata,
        }

        # Append to log file in JSON Lines format
        with open(self.current_log_file, "a", encoding="utf-8") as f:
            f.write(json.dumps(log_entry, ensure_ascii=False) + "\n")

    def get_decision_history(
        self,
        start_time: int,
        end_time: int,
        decision_type: Optional[str] = None,
    ) -> List[Dict[str, Any]]:
        """
        Query decision history within a time range

        Args:
            start_time: Start timestamp (inclusive)
            end_time: End timestamp (inclusive)
            decision_type: Optional filter by decision type

        Returns:
            List of decision log entries matching the criteria
        """
        if not self.current_log_file.exists():
            return []

        results = []

        with open(self.current_log_file, "r", encoding="utf-8") as f:
            for line in f:
                if not line.strip():
                    continue

                try:
                    entry = json.loads(line)
                    timestamp = entry.get("timestamp", 0)

                    # Filter by time range
                    if timestamp < start_time or timestamp > end_time:
                        continue

                    # Filter by decision type if specified
                    if decision_type and entry.get("decision_type") != decision_type:
                        continue

                    results.append(entry)

                except json.JSONDecodeError:
                    # Skip malformed lines
                    continue

        return results

    def get_latest_decisions(
        self, limit: int = 10, decision_type: Optional[str] = None
    ) -> List[Dict[str, Any]]:
        """
        Get the most recent decisions

        Args:
            limit: Maximum number of decisions to return
            decision_type: Optional filter by decision type

        Returns:
            List of recent decision log entries
        """
        if not self.current_log_file.exists():
            return []

        results = []

        with open(self.current_log_file, "r", encoding="utf-8") as f:
            for line in f:
                if not line.strip():
                    continue

                try:
                    entry = json.loads(line)

                    # Filter by decision type if specified
                    if decision_type and entry.get("decision_type") != decision_type:
                        continue

                    results.append(entry)

                except json.JSONDecodeError:
                    continue

        # Return the last N entries
        return results[-limit:] if results else []

    def get_decision_by_id(self, decision_id: str) -> Optional[Dict[str, Any]]:
        """
        Get a specific decision by its ID

        Args:
            decision_id: Decision ID to search for

        Returns:
            Decision log entry if found, None otherwise
        """
        if not self.current_log_file.exists():
            return None

        with open(self.current_log_file, "r", encoding="utf-8") as f:
            for line in f:
                if not line.strip():
                    continue

                try:
                    entry = json.loads(line)

                    # Check if this entry contains the decision ID
                    output = entry.get("output", {})
                    if isinstance(output, dict):
                        if output.get("plan_id") == decision_id:
                            return entry
                        if output.get("issue_id") == decision_id:
                            return entry

                except json.JSONDecodeError:
                    continue

        return None

    def get_statistics(self) -> Dict[str, Any]:
        """
        Get statistics about logged decisions

        Returns:
            Dictionary with statistics (total count, counts by type, etc.)
        """
        if not self.current_log_file.exists():
            return {
                "total_decisions": 0,
                "by_type": {},
                "oldest_timestamp": None,
                "newest_timestamp": None,
            }

        total = 0
        by_type: Dict[str, int] = {}
        oldest_timestamp = None
        newest_timestamp = None

        with open(self.current_log_file, "r", encoding="utf-8") as f:
            for line in f:
                if not line.strip():
                    continue

                try:
                    entry = json.loads(line)
                    total += 1

                    # Count by type
                    decision_type = entry.get("decision_type", "unknown")
                    by_type[decision_type] = by_type.get(decision_type, 0) + 1

                    # Track timestamps
                    timestamp = entry.get("timestamp")
                    if timestamp:
                        if oldest_timestamp is None or timestamp < oldest_timestamp:
                            oldest_timestamp = timestamp
                        if newest_timestamp is None or timestamp > newest_timestamp:
                            newest_timestamp = timestamp

                except json.JSONDecodeError:
                    continue

        return {
            "total_decisions": total,
            "by_type": by_type,
            "oldest_timestamp": oldest_timestamp,
            "newest_timestamp": newest_timestamp,
        }

    def clear_logs(self) -> None:
        """
        Clear all decision logs

        Warning: This operation is irreversible!
        """
        if self.current_log_file.exists():
            self.current_log_file.unlink()

    def export_to_json(self, output_path: str) -> None:
        """
        Export all decision logs to a single JSON file

        Args:
            output_path: Path to output JSON file
        """
        if not self.current_log_file.exists():
            with open(output_path, "w", encoding="utf-8") as f:
                json.dump([], f, indent=2)
            return

        decisions = []

        with open(self.current_log_file, "r", encoding="utf-8") as f:
            for line in f:
                if not line.strip():
                    continue

                try:
                    entry = json.loads(line)
                    decisions.append(entry)
                except json.JSONDecodeError:
                    continue

        with open(output_path, "w", encoding="utf-8") as f:
            json.dump(decisions, f, indent=2, ensure_ascii=False)
