import platform
import sys
from enum import Enum

import typer
from loguru import logger

from ..config import CONFIG, LogConfig
from ._typer import RecurveTyper, exit_with_error
from .agent import agent_app
from .config import config_app
from .data import data_app
from .service import service_app

app = RecurveTyper(help="Reorc Agent Command Line Interface")
app.add_typer(agent_app, name="agent")
app.add_typer(config_app, name="config")
app.add_typer(service_app, name="service")
app.add_typer(data_app, name="data")


class LogLevel(str, Enum):
    DEBUG = "DEBUG"
    INFO = "INFO"
    WARNING = "WARNING"
    ERROR = "ERROR"
    CRITICAL = "CRITICAL"


def _setup_logging(log_config: LogConfig, log_level: str) -> None:
    """Setup logging system with console and file handlers."""
    logger.remove()

    # 1. Console logging (always enabled for development and debugging)
    logger.add(sys.stderr, level=log_level, colorize=True, backtrace=True, diagnose=True)

    # 2. File logging (with rotation)
    if log_config.enable_file_logging:
        try:
            # Ensure log directory exists
            log_config.log_dir.mkdir(parents=True, exist_ok=True)

            # Validate configuration
            is_valid, error_msg = log_config.validate_config()
            if not is_valid:
                logger.warning(f"Invalid log configuration: {error_msg}. Using defaults.")
                log_config = LogConfig()

            # Add file log handler
            logger.add(
                log_config.log_file_path,
                level=log_level,
                colorize=False,  # No color codes in file
                rotation=log_config.rotation_size,  # Rotate by size
                retention=log_config.retention_count,  # Number of files to retain
                compression=log_config.compression,  # Compression format
                enqueue=log_config.enqueue,  # Async writing (non-blocking)
                backtrace=True,
                diagnose=False,  # Disable diagnostics in production to avoid leaking sensitive info
                catch=True,  # Automatically catch sink errors
                encoding="utf8",
                delay=False,
            )

            logger.info(
                f"File logging enabled: {log_config.log_file_path}, "
                f"rotation: {log_config.rotation_size}, "
                f"retention: {log_config.retention_count} files (~{log_config.retention_size}), "
                f"compression: {log_config.compression}"
            )

        except PermissionError:
            logger.warning(f"Set Log Failed[Permission denied]: Cannot write to {log_config.log_dir}")
            logger.warning("Falling back to console-only logging")
        except Exception as e:
            logger.error(f"Set Log Failed[Unknown error]: {e}")
            logger.warning("Falling back to console-only logging")
    else:
        logger.info("File logging disabled (console-only mode)")


@app.callback()
def on_init(log_level: LogLevel = LogLevel.INFO):
    """CLI initialization callback."""
    _setup_logging(CONFIG.log_config, log_level.value)


@app.command()
async def version():
    """Show version information."""
    from recurvedata.agent._version import VERSION

    py_impl = platform.python_implementation()
    py_version = platform.python_version()
    system = platform.system()

    typer.echo(f"Running Reorc Agent {VERSION} with {py_impl} {py_version} on {system}.")


@app.command()
async def login():
    """Login the agent to the Reorc service."""
    from .._internal.agent import Agent
    from ..exceptions import UnauthorizedError

    agent = Agent.default()
    if agent.has_logged_in:
        yes: bool = typer.confirm("Agent already logged in. Do you want to re-login?", default=False)
        if not yes:
            return

    encoded_token: str = typer.prompt("Paste your API key", hide_input=True)

    try:
        await agent.login(encoded_token)
    except ValueError:
        exit_with_error("Invalid token.")
    except UnauthorizedError:
        exit_with_error("Invalid token.")
    except Exception as e:
        exit_with_error(f"Failed to login: {e}")

    typer.secho("Agent logged in.", fg="green")


@app.command()
async def logout():
    """Logout the agent from the Reorc service."""
    from .._internal.agent import Agent

    agent = Agent.default()
    if not agent.has_logged_in:
        exit_with_error("Agent not logged in.", fg=typer.colors.YELLOW)

    await agent.logout()


if __name__ == "__main__":
    app()
