"""Tests for config export/import (Phase 5)."""

from __future__ import annotations

from pathlib import Path

import pytest
from ruamel.yaml import YAML
from typer.testing import CliRunner

from ilum.cli.main import app
from ilum.config.manager import ConfigManager
from ilum.config.models import ClusterConfig, IlumConfig, ProfileConfig
from ilum.config.paths import IlumPaths


@pytest.fixture()
def config_env(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> ConfigManager:
    """Set up temporary config environment with test profiles."""
    import sys

    if sys.platform == "win32":
        monkeypatch.setenv("APPDATA", str(tmp_path / "appdata"))
        monkeypatch.setenv("LOCALAPPDATA", str(tmp_path / "localappdata"))
    else:
        monkeypatch.setenv("XDG_CONFIG_HOME", str(tmp_path / "config"))
        monkeypatch.setenv("XDG_DATA_HOME", str(tmp_path / "data"))
        monkeypatch.setenv("XDG_STATE_HOME", str(tmp_path / "state"))
        monkeypatch.setenv("XDG_CACHE_HOME", str(tmp_path / "cache"))

    paths = IlumPaths.default()
    paths.ensure_dirs()
    mgr = ConfigManager(paths)

    config = IlumConfig(
        active_profile="default",
        profiles={
            "default": ProfileConfig(
                name="default",
                release_name="ilum",
                enabled_modules=["core", "ui", "mongodb"],
                cluster=ClusterConfig(
                    namespace="default",
                    kubecontext="minikube",
                ),
            ),
            "production": ProfileConfig(
                name="production",
                release_name="ilum-prod",
                enabled_modules=["core", "ui", "mongodb", "kafka", "monitoring"],
                cluster=ClusterConfig(
                    namespace="ilum-prod",
                    kubecontext="arn:aws:eks:us-east-1:123456:cluster/prod",
                ),
            ),
        },
    )
    mgr.save(config)
    return mgr


class TestConfigExport:
    def test_export_to_stdout(self, config_env: ConfigManager) -> None:
        runner = CliRunner()
        result = runner.invoke(app, ["config", "export", "default"])
        assert result.exit_code == 0
        assert "release_name: ilum" in result.output

    def test_export_to_file(self, config_env: ConfigManager, tmp_path: Path) -> None:
        out_file = tmp_path / "exported.yaml"
        runner = CliRunner()
        result = runner.invoke(app, ["config", "export", "default", "--out", str(out_file)])
        assert result.exit_code == 0
        assert out_file.exists()

        yaml = YAML()
        with out_file.open() as f:
            data = yaml.load(f)
        assert data["release_name"] == "ilum"

    def test_export_excludes_cluster_context_by_default(self, config_env: ConfigManager) -> None:
        runner = CliRunner()
        result = runner.invoke(app, ["config", "export", "production"])
        assert result.exit_code == 0
        assert "kubecontext" not in result.output or "arn:" not in result.output

    def test_export_includes_cluster_with_flag(self, config_env: ConfigManager) -> None:
        runner = CliRunner()
        result = runner.invoke(app, ["config", "export", "production", "--include-cluster"])
        assert result.exit_code == 0
        # The kubecontext should be present
        assert "kubecontext" in result.output or "arn" in result.output

    def test_export_unknown_profile(self, config_env: ConfigManager) -> None:
        runner = CliRunner()
        result = runner.invoke(app, ["config", "export", "nonexistent"])
        assert result.exit_code == 1
        assert "Unknown profile" in result.output


class TestConfigImport:
    def test_import_profile(self, config_env: ConfigManager, tmp_path: Path) -> None:
        # First export
        export_file = tmp_path / "profile.yaml"
        runner = CliRunner()
        runner.invoke(app, ["config", "export", "default", "--out", str(export_file)])

        # Import with new name
        result = runner.invoke(app, ["config", "import", str(export_file), "--name", "imported"])
        assert result.exit_code == 0
        assert "Imported" in result.output

        # Verify it exists
        config = config_env.load()
        assert "imported" in config.profiles

    def test_import_rejects_duplicate_name(self, config_env: ConfigManager, tmp_path: Path) -> None:
        export_file = tmp_path / "profile.yaml"
        runner = CliRunner()
        runner.invoke(app, ["config", "export", "default", "--out", str(export_file)])

        result = runner.invoke(app, ["config", "import", str(export_file), "--name", "default"])
        assert result.exit_code == 1
        assert "already exists" in result.output

    def test_import_force_overwrites(self, config_env: ConfigManager, tmp_path: Path) -> None:
        export_file = tmp_path / "profile.yaml"
        runner = CliRunner()
        runner.invoke(app, ["config", "export", "default", "--out", str(export_file)])

        result = runner.invoke(
            app, ["config", "import", str(export_file), "--name", "default", "--force"]
        )
        assert result.exit_code == 0
        assert "Imported" in result.output

    def test_import_validates_data(self, config_env: ConfigManager, tmp_path: Path) -> None:
        bad_file = tmp_path / "bad.yaml"
        yaml = YAML()
        yaml.dump({"enabled_modules": "not_a_list"}, bad_file)

        runner = CliRunner()
        result = runner.invoke(app, ["config", "import", str(bad_file), "--name", "bad"])
        assert result.exit_code == 1

    def test_import_file_not_found(self, config_env: ConfigManager) -> None:
        runner = CliRunner()
        result = runner.invoke(app, ["config", "import", "/nonexistent/file.yaml", "--name", "x"])
        assert result.exit_code == 1
        assert "not found" in result.output.lower() or "File not found" in result.output

    def test_import_uses_name_from_file(self, config_env: ConfigManager, tmp_path: Path) -> None:
        """If no --name given, use 'name' field from the YAML file."""
        export_file = tmp_path / "named.yaml"
        yaml = YAML()
        yaml.dump(
            {
                "name": "from-file",
                "release_name": "ilum-imported",
                "enabled_modules": ["core"],
            },
            export_file,
        )

        runner = CliRunner()
        result = runner.invoke(app, ["config", "import", str(export_file)])
        assert result.exit_code == 0

        config = config_env.load()
        assert "from-file" in config.profiles
