from __future__ import annotations

from pathlib import Path
from typing import Optional, Union

from .config import ToxoConfig
from ..utils.exceptions import ToxoError
from ..utils.logger import get_logger


def load_legacy_layer(
    path: Union[str, Path],
    *,
    config: Optional[ToxoConfig] = None,
):
    """
    Legacy `.toxo` load path.

    Kept for reference/back-compat in older artifacts; the supported path is
    `ToxoPackageManager.load_package(...)`.
    """
    # Local import to avoid importing the entire runtime when unused.
    from .toxo_layer import ToxoLayer

    import json
    import tempfile
    import zipfile

    path = Path(path)
    if not path.exists():
        raise ToxoError(f"Toxo file not found: {path}")

    logger = get_logger("toxo.layer.load")
    logger.info(f"Loading ToxoLayer from {path}")

    with tempfile.TemporaryDirectory() as temp_dir:
        temp_path = Path(temp_dir)

        with zipfile.ZipFile(path, "r") as zip_ref:
            zip_ref.extractall(temp_path)

        manifest_path = temp_path / "manifest.json"
        if not manifest_path.exists():
            raise ToxoError("Invalid .toxo file: missing manifest.json")

        with open(manifest_path, "r") as f:
            manifest = json.load(f)

        config_path = temp_path / "config" / "toxo_config.json"
        if config_path.exists():
            with open(config_path, "r") as f:
                config_data = json.load(f)
        else:
            config_data = {
                "domain": manifest.get("domain", "loaded_domain"),
                "task_type": manifest.get("task_type", "loaded_task"),
            }

        if config is None:
            config = ToxoConfig()

        layer = ToxoLayer(
            domain=config_data.get("domain", "loaded_domain"),
            task_type=config_data.get("task_type", "loaded_task"),
            name=manifest.get("name", "loaded_layer"),
            description=manifest.get("description", "Loaded from .toxo file"),
            config=config,
        )

        training_data_path = temp_path / "training" / "training_data.json"
        if training_data_path.exists():
            with open(training_data_path, "r") as f:
                training_data = json.load(f)

            layer.feedback_history = training_data.get("feedback", [])
            layer.training_examples = training_data.get("examples", [])
            layer.feedback_data = training_data.get("feedback", [])
            logger.info(
                f"Loaded {len(layer.training_examples)} training examples and {len(layer.feedback_data)} feedback items"
            )
        else:
            layer.training_examples = []
            layer.feedback_data = []

        soft_prompt_path = temp_path / "components" / "soft_prompt.npy"
        if soft_prompt_path.exists():
            import numpy as np  # type: ignore

            layer.soft_prompt_engine.current_prompt = np.load(soft_prompt_path)
            layer.is_trained = True
            logger.info("Loaded soft prompt")

        memory_path = temp_path / "memory_systems.json"
        if memory_path.exists():
            with open(memory_path, "r") as f:
                layer.memory_systems = json.load(f)
            logger.info(f"Memory systems data available: {list(layer.memory_systems.keys())}")
        else:
            layer.memory_systems = {}

        cognitive_path = temp_path / "cognitive_systems.json"
        if cognitive_path.exists():
            with open(cognitive_path, "r") as f:
                layer.cognitive_systems = json.load(f)
            logger.info(f"Cognitive systems data available: {list(layer.cognitive_systems.keys())}")
        else:
            layer.cognitive_systems = {}

        logger.info(f"Successfully loaded ToxoLayer: {layer.name}")
        return layer

