"""Debug logging service for API requests and responses."""

import json
from datetime import datetime
from pathlib import Path
from typing import Optional, Any
import threading

# Thread-safe debug log storage
_debug_log = []
_debug_lock = threading.Lock()
_debug_enabled = True  # Can be toggled via settings

# Max entries to keep in memory
MAX_DEBUG_ENTRIES = 100


def is_debug_enabled() -> bool:
    """Check if debug mode is enabled."""
    return _debug_enabled


def set_debug_enabled(enabled: bool):
    """Enable or disable debug mode."""
    global _debug_enabled
    _debug_enabled = enabled


def log_request(
    service: str,
    endpoint: str,
    method: str,
    url: str,
    headers: dict,
    payload: Any,
    provider: str = None
) -> str:
    """
    Log an outgoing API request.

    Returns:
        Request ID for correlating with response
    """
    if not _debug_enabled:
        return ""

    request_id = f"{service}_{datetime.now().strftime('%H%M%S%f')}"

    # Sanitize headers (hide API keys)
    safe_headers = {}
    for k, v in headers.items():
        if 'authorization' in k.lower() or 'api' in k.lower():
            safe_headers[k] = f"{v[:20]}..." if len(str(v)) > 20 else "***"
        else:
            safe_headers[k] = v

    entry = {
        "id": request_id,
        "type": "request",
        "timestamp": datetime.now().isoformat(),
        "service": service,
        "provider": provider,
        "endpoint": endpoint,
        "method": method,
        "url": url,
        "headers": safe_headers,
        "payload": _truncate_payload(payload),
        "payload_size": len(json.dumps(payload)) if payload else 0
    }

    with _debug_lock:
        _debug_log.append(entry)
        # Trim if too many entries
        if len(_debug_log) > MAX_DEBUG_ENTRIES:
            _debug_log.pop(0)

    return request_id


def log_response(
    request_id: str,
    status_code: int,
    response_data: Any,
    error: str = None,
    duration_ms: float = None
):
    """Log an API response."""
    if not _debug_enabled:
        return

    entry = {
        "id": f"{request_id}_response",
        "request_id": request_id,
        "type": "response",
        "timestamp": datetime.now().isoformat(),
        "status_code": status_code,
        "response": _truncate_payload(response_data),
        "response_size": len(json.dumps(response_data)) if response_data else 0,
        "error": error,
        "duration_ms": duration_ms
    }

    with _debug_lock:
        _debug_log.append(entry)
        if len(_debug_log) > MAX_DEBUG_ENTRIES:
            _debug_log.pop(0)


def get_debug_log(limit: int = 50) -> list:
    """Get recent debug log entries."""
    with _debug_lock:
        return list(reversed(_debug_log[-limit:]))


def clear_debug_log():
    """Clear all debug log entries."""
    global _debug_log
    with _debug_lock:
        _debug_log = []


def get_debug_entry(request_id: str) -> dict:
    """Get a specific request and its response."""
    with _debug_lock:
        request = None
        response = None
        for entry in _debug_log:
            if entry.get("id") == request_id:
                request = entry
            elif entry.get("request_id") == request_id:
                response = entry

        return {
            "request": request,
            "response": response
        }


def _truncate_payload(data: Any, max_length: int = 5000) -> Any:
    """Truncate large payloads for storage."""
    if data is None:
        return None

    if isinstance(data, str):
        if len(data) > max_length:
            return data[:max_length] + f"... [truncated {len(data) - max_length} chars]"
        return data

    if isinstance(data, dict):
        result = {}
        for k, v in data.items():
            result[k] = _truncate_payload(v, max_length // 2)
        return result

    if isinstance(data, list):
        if len(data) > 10:
            return [_truncate_payload(item, max_length // 10) for item in data[:10]] + [f"... and {len(data) - 10} more items"]
        return [_truncate_payload(item, max_length // len(data)) for item in data]

    return data


def format_debug_entry(entry: dict) -> str:
    """Format a debug entry for display."""
    lines = []

    if entry.get("type") == "request":
        lines.append(f"=== REQUEST [{entry.get('id')}] ===")
        lines.append(f"Time: {entry.get('timestamp')}")
        lines.append(f"Service: {entry.get('service')} / Provider: {entry.get('provider')}")
        lines.append(f"Method: {entry.get('method')} {entry.get('url')}")
        lines.append(f"Headers: {json.dumps(entry.get('headers', {}), indent=2)}")
        lines.append(f"Payload ({entry.get('payload_size')} bytes):")
        lines.append(json.dumps(entry.get('payload'), indent=2, ensure_ascii=False))

    elif entry.get("type") == "response":
        lines.append(f"=== RESPONSE [{entry.get('request_id')}] ===")
        lines.append(f"Time: {entry.get('timestamp')}")
        lines.append(f"Status: {entry.get('status_code')}")
        if entry.get('duration_ms'):
            lines.append(f"Duration: {entry.get('duration_ms'):.0f}ms")
        if entry.get('error'):
            lines.append(f"Error: {entry.get('error')}")
        lines.append(f"Response ({entry.get('response_size')} bytes):")
        lines.append(json.dumps(entry.get('response'), indent=2, ensure_ascii=False))

    return "\n".join(lines)
