"""Tests for create command feature flags (docker, pre-commit, docs, devcontainer, full-dx)."""

from __future__ import annotations

from pathlib import Path
from typing import TYPE_CHECKING

from prisme.cli import main

if TYPE_CHECKING:
    from unittest.mock import MagicMock

    from click.testing import CliRunner


class TestCreateWithDocker:
    """Tests for create --docker flag."""

    def test_create_with_docker_flag(
        self,
        cli_runner: CliRunner,
        mock_subprocess: MagicMock,
    ) -> None:
        with cli_runner.isolated_filesystem():
            result = cli_runner.invoke(
                main,
                ["create", "docker-project", "--docker", "--no-install", "--no-git", "-y"],
            )
            assert result.exit_code == 0
            project_dir = Path("docker-project")
            assert project_dir.exists()

    def test_docker_shows_docker_next_steps(
        self,
        cli_runner: CliRunner,
        mock_subprocess: MagicMock,
    ) -> None:
        with cli_runner.isolated_filesystem():
            result = cli_runner.invoke(
                main,
                ["create", "docker-project", "--docker", "--no-install", "--no-git", "-y"],
            )
            assert result.exit_code == 0
            assert "docker" in result.output.lower()


class TestCreateWithPreCommit:
    """Tests for create --pre-commit flag."""

    def test_create_with_pre_commit_flag(
        self,
        cli_runner: CliRunner,
        mock_subprocess: MagicMock,
    ) -> None:
        with cli_runner.isolated_filesystem():
            result = cli_runner.invoke(
                main,
                ["create", "hook-project", "--pre-commit", "--no-install", "--no-git", "-y"],
            )
            assert result.exit_code == 0
            assert Path("hook-project").exists()


class TestCreateWithDocs:
    """Tests for create --docs flag."""

    def test_create_with_docs_flag(
        self,
        cli_runner: CliRunner,
        mock_subprocess: MagicMock,
    ) -> None:
        with cli_runner.isolated_filesystem():
            result = cli_runner.invoke(
                main,
                ["create", "docs-project", "--docs", "--no-install", "--no-git", "-y"],
            )
            assert result.exit_code == 0
            assert Path("docs-project").exists()


class TestCreateWithDevcontainer:
    """Tests for create --devcontainer flag."""

    def test_create_with_devcontainer_flag(
        self,
        cli_runner: CliRunner,
        mock_subprocess: MagicMock,
    ) -> None:
        with cli_runner.isolated_filesystem():
            result = cli_runner.invoke(
                main,
                ["create", "dc-project", "--devcontainer", "--no-install", "--no-git", "-y"],
            )
            assert result.exit_code == 0
            assert Path("dc-project").exists()


class TestCreateWithFullDx:
    """Tests for create --full-dx flag."""

    def test_create_with_full_dx_flag(
        self,
        cli_runner: CliRunner,
        mock_subprocess: MagicMock,
    ) -> None:
        with cli_runner.isolated_filesystem():
            result = cli_runner.invoke(
                main,
                ["create", "dx-project", "--full-dx", "--no-install", "--no-git", "-y"],
            )
            assert result.exit_code == 0
            assert Path("dx-project").exists()


class TestCreateWithGit:
    """Tests for create with git initialization."""

    def test_create_with_git(
        self,
        cli_runner: CliRunner,
        mock_subprocess: MagicMock,
    ) -> None:
        """Create without --no-git should attempt git init."""
        with cli_runner.isolated_filesystem():
            result = cli_runner.invoke(
                main,
                ["create", "git-project", "--no-install", "-y"],
            )
            assert result.exit_code == 0
            # git init should have been called
            git_calls = [
                call
                for call in mock_subprocess.call_args_list
                if "git" in str(call) and "init" in str(call)
            ]
            assert len(git_calls) > 0


class TestCreateWithNoCi:
    """Tests for create --no-ci flag."""

    def test_create_with_no_ci(
        self,
        cli_runner: CliRunner,
        mock_subprocess: MagicMock,
    ) -> None:
        with cli_runner.isolated_filesystem():
            result = cli_runner.invoke(
                main,
                ["create", "noci-project", "--no-ci", "--no-install", "--no-git", "-y"],
            )
            assert result.exit_code == 0
            assert Path("noci-project").exists()


class TestCreateDotProject:
    """Tests for create command with '.' as project name."""

    def test_create_dot_in_empty_dir(
        self,
        cli_runner: CliRunner,
        mock_subprocess: MagicMock,
    ) -> None:
        with cli_runner.isolated_filesystem():
            result = cli_runner.invoke(
                main,
                ["create", ".", "--no-install", "--no-git", "-y"],
            )
            assert result.exit_code == 0
            assert "success" in result.output.lower()


class TestCreateWithInstall:
    """Tests for create with dependency installation."""

    def test_create_without_no_install_attempts_install(
        self,
        cli_runner: CliRunner,
        mock_subprocess: MagicMock,
    ) -> None:
        with cli_runner.isolated_filesystem():
            result = cli_runner.invoke(
                main,
                ["create", "install-project", "--no-git", "-y"],
            )
            # Should succeed (subprocess is mocked)
            assert result.exit_code == 0


class TestCreateCombinedFlags:
    """Tests for create with combined feature flags."""

    def test_create_docker_and_pre_commit(
        self,
        cli_runner: CliRunner,
        mock_subprocess: MagicMock,
    ) -> None:
        with cli_runner.isolated_filesystem():
            result = cli_runner.invoke(
                main,
                [
                    "create",
                    "combo-project",
                    "--docker",
                    "--pre-commit",
                    "--no-install",
                    "--no-git",
                    "-y",
                ],
            )
            assert result.exit_code == 0

    def test_create_all_flags(
        self,
        cli_runner: CliRunner,
        mock_subprocess: MagicMock,
    ) -> None:
        with cli_runner.isolated_filesystem():
            result = cli_runner.invoke(
                main,
                [
                    "create",
                    "all-flags-project",
                    "--docker",
                    "--full-dx",
                    "--no-install",
                    "--no-git",
                    "-y",
                ],
            )
            assert result.exit_code == 0

    def test_create_minimal_with_docker(
        self,
        cli_runner: CliRunner,
        mock_subprocess: MagicMock,
    ) -> None:
        with cli_runner.isolated_filesystem():
            result = cli_runner.invoke(
                main,
                [
                    "create",
                    "minimal-docker",
                    "--template",
                    "minimal",
                    "--docker",
                    "--no-install",
                    "--no-git",
                    "-y",
                ],
            )
            assert result.exit_code == 0

    def test_create_api_only_with_docs(
        self,
        cli_runner: CliRunner,
        mock_subprocess: MagicMock,
    ) -> None:
        with cli_runner.isolated_filesystem():
            result = cli_runner.invoke(
                main,
                [
                    "create",
                    "api-docs-project",
                    "--template",
                    "api-only",
                    "--docs",
                    "--no-install",
                    "--no-git",
                    "-y",
                ],
            )
            assert result.exit_code == 0
