"""Validation module for LXMFy configuration and best practices."""

import logging
from dataclasses import dataclass
from typing import Any

from .storage import JSONStorage

logger = logging.getLogger(__name__)


@dataclass
class ValidationResult:
    """
    Result of a validation check.

    Attributes:
        valid (bool): Indicates whether the validation was successful.
        messages (list[str]): A list of messages associated with the validation result.
        severity (str): The severity level of the validation result ('error', 'warning', or 'info').
    """
    valid: bool
    messages: list[str]
    severity: str


class ConfigValidator:
    """Validates bot configuration settings."""

    @staticmethod
    def validate_config(config: Any) -> list[ValidationResult]:
        """
        Validate the given bot configuration.

        Args:
            config (Any): The bot configuration object to validate.

        Returns:
            list[ValidationResult]: A list of validation results.
        """
        results = []

        try:
            if len(getattr(config, 'name', '')) < 3:
                results.append(ValidationResult(
                    False,
                    ["Bot name should be at least 3 characters long"],
                    "error"
                ))

            announce = getattr(config, 'announce', 0)
            if 0 < announce < 300:
                results.append(ValidationResult(
                    False,
                    ["Announce interval should be at least 300 seconds to avoid network spam"],
                    "warning"
                ))

            if getattr(config, 'rate_limit', 0) > 10:
                results.append(ValidationResult(
                    False,
                    ["Rate limit above 10 messages per minute may be too permissive"],
                    "warning"
                ))

            if getattr(config, 'cooldown', 0) < 30:
                results.append(ValidationResult(
                    False,
                    ["Cooldown period should be at least 30 seconds"],
                    "warning"
                ))

        except Exception as e:
            logger.error("Error during config validation: %s", str(e))
            results.append(ValidationResult(
                False,
                [f"Error validating configuration: {str(e)}"],
                "error"
            ))

        return results


class BestPracticesChecker:
    """Checks for bot implementation best practices."""

    @staticmethod
    def check_bot(bot: Any) -> list[ValidationResult]:
        """
        Check the bot instance for best practices.

        Args:
            bot (Any): The bot instance to check.

        Returns:
            list[ValidationResult]: A list of validation results.
        """
        results = []

        if not getattr(bot.config, 'permissions_enabled', False):
            results.append(ValidationResult(
                False,
                ["Permission system is disabled. Consider enabling it for better security"],
                "warning"
            ))

        if getattr(bot, 'command_prefix', None) is None:
            results.append(ValidationResult(
                False,
                ["Using no command prefix may cause high processing overhead"],
                "warning"
            ))

        if not getattr(bot, 'admins', None):
            results.append(ValidationResult(
                False,
                ["No admin users configured. Bot management will be limited"],
                "warning"
            ))

        if getattr(bot.config, 'storage_type', '') == "json":
            results.append(ValidationResult(
                True,
                ["Consider using SQLite storage for better performance with large datasets"],
                "info"
            ))

        return results


class PerformanceAnalyzer:
    """Analyzes bot configuration for performance optimization opportunities."""

    @staticmethod
    def analyze_bot(bot: Any) -> list[ValidationResult]:
        """
        Analyze the bot instance for performance optimization opportunities.

        Args:
            bot (Any): The bot instance to analyze.

        Returns:
            list[ValidationResult]: A list of validation results.
        """
        results = []

        if not hasattr(bot, 'transport') or not hasattr(bot.transport, "cached_links"):
            results.append(ValidationResult(
                False,
                ["Link caching is not enabled. This may impact performance"],
                "warning"
            ))

        if hasattr(bot, 'queue') and getattr(bot.queue, 'maxsize', 0) < 10:
            results.append(ValidationResult(
                False,
                ["Consider increasing queue size for better message handling"],
                "info"
            ))

        if hasattr(bot, 'storage') and hasattr(bot.storage, 'backend') and isinstance(bot.storage.backend, JSONStorage):
            results.append(ValidationResult(
                True,
                ["SQLite backend recommended for better performance with large datasets"],
                "info"
            ))

        return results


def validate_bot(bot: Any) -> dict[str, list[ValidationResult]]:
    """
    Run all validation checks on a bot instance.

    Args:
        bot (Any): The bot instance to validate.

    Returns:
        dict[str, list[ValidationResult]]: A dictionary containing validation results for different categories.
    """
    try:
        return {
            "config": ConfigValidator.validate_config(bot.config),
            "best_practices": BestPracticesChecker.check_bot(bot),
            "performance": PerformanceAnalyzer.analyze_bot(bot)
        }
    except Exception as e:
        logger.error("Validation error: %s", str(e))
        return {
            "error": [ValidationResult(
                False,
                [f"Error during validation: {str(e)}"],
                "error"
            )]
        }


def format_validation_results(results: dict[str, list[ValidationResult]]) -> str:
    """
    Format validation results into a readable string.

    Args:
        results (dict[str, list[ValidationResult]]): A dictionary containing validation results.

    Returns:
        str: A formatted string representing the validation results.
    """
    output = []

    for category, checks in results.items():
        output.append(f"\n=== {category.upper()} ===")
        for result in checks:
            prefix = "❌" if not result.valid and result.severity == "error" else \
                     "⚠️" if result.severity == "warning" else "ℹ️"
            output.extend(f"{prefix} {msg}" for msg in result.messages)

    return "\n".join(output)
