import json
from pathlib import Path
from datetime import datetime
from typing import Any

from .sources.base import ResolutionResult


# Path to the mappings file
MAPPINGS_PATH = Path.home() / ".config" / "comfy-resolve" / "mappings.json"


def load_mappings() -> dict[str, Any]:
    """
    Load all mappings from the mappings file.
    
    Returns:
        Dictionary of filename -> mapping data
    """
    if not MAPPINGS_PATH.exists():
        return {}
    
    try:
        with open(MAPPINGS_PATH, "r", encoding="utf-8") as f:
            data: dict[str, Any] = json.load(f)
            return data
    except (json.JSONDecodeError, IOError):
        return {}


def save_mappings(mappings: dict[str, Any]) -> None:
    """
    Save all mappings to the mappings file.
    
    Args:
        mappings: Dictionary of filename -> mapping data
    """
    # Ensure directory exists
    MAPPINGS_PATH.parent.mkdir(parents=True, exist_ok=True)
    
    with open(MAPPINGS_PATH, "w", encoding="utf-8") as f:
        json.dump(mappings, f, indent=2)


def get_mapping(filename: str) -> dict[str, Any] | None:
    """
    Get a specific mapping by filename.
    
    Args:
        filename: The filename to look up
        
    Returns:
        Mapping data if found, None otherwise
    """
    mappings = load_mappings()
    return mappings.get(filename)


def save_mapping(filename: str, result: ResolutionResult) -> None:
    """
    Save a resolution result as a mapping.
    
    Args:
        filename: The filename to map
        result: The resolution result to save
    """
    mappings = load_mappings()
    
    # Convert ResolutionResult to dict
    mapping_data: dict[str, Any] = {
        "resolved_name": result.resolved_name,
        "confidence": result.confidence,
        "confirmed_at": datetime.utcnow().isoformat() + "Z",
    }
    
    if result.source:
        mapping_data["source"] = {
            "type": result.source.source_type,
            "repo": result.source.repo,
            "file": result.source.file,
            "download_url": result.source.download_url,
            "sha256": result.source.sha256,
            "file_size_bytes": result.source.file_size_bytes,
        }
    
    mappings[filename] = mapping_data
    save_mappings(mappings)


def delete_mapping(filename: str) -> None:
    """
    Delete a specific mapping.
    
    Args:
        filename: The filename mapping to delete
    """
    mappings = load_mappings()
    if filename in mappings:
        del mappings[filename]
        save_mappings(mappings)


def list_mappings() -> list[dict[str, Any]]:
    """
    List all mappings.
    
    Returns:
        List of mapping dictionaries with filename included
    """
    mappings = load_mappings()
    result = []
    for filename, data in mappings.items():
        entry = {"filename": filename}
        entry.update(data)
        result.append(entry)
    return result
