"""Token command implementation for MakePython."""

from __future__ import annotations

import getpass
from pathlib import Path
from typing import TYPE_CHECKING

from ...interfaces.command import CommandResult, CommandType, ValidatableCommand

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


# PyPI token configuration file (standard .pypirc format)
TOKEN_FILE = Path.home() / ".pypirc"


class TokenCommand(ValidatableCommand):
    """Set PyPI authentication token."""

    name = "token"
    alias = "tk"
    description = "Set PyPI authentication token"
    command_type = CommandType.TOKEN

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

        Args:
            context: Execution context

        Returns
        -------
            True if validation passes, False otherwise
        """
        # Always valid - token can be set anytime
        return True

    def _load_token(self) -> str | None:
        """Load token from .pypirc configuration file.

        Returns
        -------
            Token string if exists, None otherwise
        """
        if not TOKEN_FILE.exists():
            return None

        try:
            import configparser

            config = configparser.ConfigParser()
            config.read(TOKEN_FILE, encoding="utf-8")

            # Try to get token from pypi section
            if "pypi" in config and "password" in config["pypi"]:
                return config["pypi"]["password"]

            # Try pypi.org section
            if "pypi.org" in config and "password" in config["pypi.org"]:
                return config["pypi.org"]["password"]

            return None
        except Exception as e:
            self.logger.warning(f"Failed to load token from .pypirc: {e}")
            return None

    def _save_token(self, token: str) -> bool:
        """Save token to .pypirc configuration file.

        Args:
            token: PyPI token to save

        Returns
        -------
            True if successfully saved, False otherwise
        """
        try:
            import configparser

            # Create .pypirc directory if needed
            TOKEN_FILE.parent.mkdir(parents=True, exist_ok=True)

            # Read existing config or create new one
            config = configparser.ConfigParser()
            if TOKEN_FILE.exists():
                config.read(TOKEN_FILE, encoding="utf-8")

            # Set up pypi section with token
            if "pypi" not in config:
                config["pypi"] = {}
            config["pypi"]["repository"] = "https://upload.pypi.org/legacy/"
            config["pypi"]["username"] = "__token__"
            config["pypi"]["password"] = token

            # Write config file
            with open(TOKEN_FILE, "w", encoding="utf-8") as f:
                config.write(f)

            self.logger.debug(f"Token saved to {TOKEN_FILE}")
            return True
        except Exception as e:
            self.logger.error(f"Failed to save token: {e}")
            return False

    def execute(self, context: ExecutionContext) -> CommandResult:
        """Execute token command.

        Args:
            context: Execution context

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

        self.logger.info("Configure PyPI authentication token")

        try:
            # Prompt for token
            print("\nEnter your PyPI API token (will not be visible):")
            token = getpass.getpass("> ")

            if not token.strip():
                return CommandResult(success=False, message="Token cannot be empty")

            # Validate token format (basic check)
            if not token.startswith("pypi-"):
                self.logger.warning("Token doesn't start with 'pypi-'. Are you sure it's correct?")
                confirm = input("Continue anyway? (y/n): ").strip().lower()
                if confirm != "y":
                    return CommandResult(success=False, message="Token configuration cancelled")

            # Save token
            if self._save_token(token):
                self.logger.info("PyPI token configured successfully")
                return CommandResult(success=True, message="PyPI token configured successfully")
            return CommandResult(success=False, message="Failed to save token")

        except KeyboardInterrupt:
            self.logger.info("Token configuration cancelled by user")
            return CommandResult(success=False, message="Cancelled by user")
        except Exception as e:
            self.logger.exception(f"Failed to configure token: {e}")
            return CommandResult(success=False, message=str(e))
