"""Version command implementation for MakePython."""

from __future__ import annotations

import re
from typing import TYPE_CHECKING

from ...core.executor import execute_command_with_context
from ...interfaces.command import CommandResult, CommandType, ValidatableCommand

if TYPE_CHECKING:
    from ...core.context import ExecutionContext


from pytola.core.logger import get_logger

logger = get_logger(__name__)


def parse_version(version_str: str) -> tuple[int, int, int] | None:
    """Parse version string into tuple.

    Args:
        version_str: Version string (e.g., "1.2.3")

    Returns
    -------
        Tuple of (major, minor, patch) or None if invalid
    """
    match = re.match(r"(\d+)\.(\d+)\.(\d+)", version_str)
    if match:
        return int(match.group(1)), int(match.group(2)), int(match.group(3))
    return None


def bump_version_command(context: ExecutionContext, version_type: str = "patch") -> CommandResult:
    """Bump project version using available tools.

    Args:
        context: Execution context
        version_type: Type of version bump (patch/minor/major)

    Returns
    -------
        CommandResult with execution status
    """
    valid_types = ["patch", "minor", "major"]
    if version_type not in valid_types:
        logger.error(f"Invalid version type: {version_type}. Valid types: {valid_types}")
        return CommandResult(success=False, message=f"Invalid version type: {version_type}")

    # Check which version bumping tool is available
    bumpversion_result = execute_command_with_context(["bumpversion", "--version"], context)
    bump2version_result = execute_command_with_context(["bump2version", "--version"], context)

    # Prefer bumpversion if available
    if bumpversion_result.success:
        try:
            logger.info(f"Bumping {version_type} version using bumpversion...")
            cmd = ["bumpversion", version_type]
            result = execute_command_with_context(cmd, context)

            if result.success:
                logger.info(f"Successfully bumped {version_type} version")
                return result
        except Exception as e:
            logger.exception(f"Failed to bump version with bumpversion: {e}")

    # Fallback to bump2version if bumpversion is not available
    if bump2version_result.success:
        try:
            logger.info(f"Bumping {version_type} version using bump2version...")
            cmd = ["bump2version", version_type]
            result = execute_command_with_context(cmd, context)

            if result.success:
                logger.info(f"Successfully bumped {version_type} version (using bump2version)")
                return result
        except Exception as e:
            logger.exception(f"Failed to bump version with bump2version: {e}")

    # If neither tool is available, suggest installation
    logger.error("No version bumping tool found!")
    logger.info("Please install one of the following:")
    logger.info("  pip install bumpversion    # For bumpversion")
    logger.info("  pip install bump2version   # For bump2version")

    return CommandResult(
        success=False,
        message="No version bumping tool found. Please install bumpversion or bump2version.",
    )


class BumpVersionCommand(ValidatableCommand):
    """Bump project version (patch/minor/major)."""

    name = "bumpversion"
    alias = "bump"
    description = "Bump project version (patch/minor/major)"
    command_type = CommandType.BUMP_VERSION

    def validate(self, context: ExecutionContext) -> bool:
        """Validate bumpversion command prerequisites.

        Args:
            context: Execution context

        Returns
        -------
            True if validation passes, False otherwise
        """
        # Check if pyproject.toml exists
        pyproject_path = context.cwd / "pyproject.toml"
        if not pyproject_path.exists():
            self.logger.error("pyproject.toml not found")
            return False

        return True

    def execute(self, context: ExecutionContext, version_type: str = "patch") -> CommandResult:
        """Execute version bump command.

        Args:
            context: Execution context
            version_type: Type of version bump (patch/minor/major)

        Returns
        -------
            CommandResult with execution status
        """
        if not self.validate(context):
            return CommandResult(success=False, message="Validation failed")

        if version_type not in ["patch", "minor", "major"]:
            return CommandResult(success=False, message=f"Invalid version type: {version_type}")

        self.logger.info(f"Bumping {version_type} version...")

        return bump_version_command(context, version_type)
