"""Main CLI entry point for iqtoolkit-analyzer"""

import logging
from pathlib import Path
from typing import List

import click
import yaml

from iqtoolkit_analyzer.config import IQToolkitConfig

from ..__version__ import __version__

# Import CLI command groups
from .mongodb_commands import mongodb_group
from .pg_commands import postgresql_group

# Configure logging
logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
)


@click.group(invoke_without_command=False)
@click.version_option(version=__version__, prog_name="iqtoolkit-analyzer")
def cli() -> None:
    """
    iqtoolkit-analyzer: Database analysis and optimization toolkit

    Use 'iqtoolkit-analyzer --help' to see all available commands.
    Tip: run any subcommand with --examples to print usage snippets.
    """
    pass


def _validation_hints(issues: List[str]) -> List[str]:
    hints: List[str] = []
    for issue in issues:
        if "default_provider" in issue and "not defined" in issue:
            hints.append(
                "Add providers.<name> entry or update default_provider to match."
            )
        elif "missing a model" in issue:
            provider_name = issue.split("'")[1] if "'" in issue else "<provider>"
            hints.append(f"Set providers.{provider_name}.model to a valid model name.")
        elif "missing an api_key" in issue:
            provider_name = issue.split("'")[1] if "'" in issue else "<provider>"
            hints.append(
                f"Set providers.{provider_name}.api_key (or env var via ${{VAR}})."
            )
        elif "missing required fields" in issue:
            db_name = issue.split("'")[1] if "'" in issue else "<database>"
            missing = issue.split(":", 1)[-1].strip()
            hints.append(f"Set databases.{db_name}.{missing.replace(', ', ', ')}.")
        elif "unsupported type" in issue:
            hints.append("Use one of: postgresql, postgres, mongodb, mongo.")
        elif "log_format" in issue:
            hints.append("Set log_format to plain, csv, or json.")
        elif "top_n" in issue:
            hints.append("Set top_n to a positive integer (e.g., 5).")
    return hints


@click.group(name="config", help="Configuration management commands")
def config_group() -> None:
    """Configuration file utilities."""
    pass


@config_group.command(name="validate", help="Validate configuration file")
@click.option(
    "--config",
    "-c",
    default=".iqtoolkit-analyzer.yml",
    help="Config file path (default: .iqtoolkit-analyzer.yml)",
)
def validate_config(config: str) -> None:
    cfg = IQToolkitConfig.load(config)
    issues = cfg.validate()
    if not issues:
        click.secho("✅ Configuration is valid", fg="green", bold=True)
        return

    click.secho("❌ Configuration issues found:", fg="red", bold=True)
    for issue in issues:
        click.echo(f"  - {issue}")

    hints = _validation_hints(issues)
    if hints:
        click.secho("\nSuggested fixes:", fg="yellow")
        for hint in hints:
            click.echo(f"  - {hint}")

    raise click.ClickException("Configuration validation failed")


@config_group.command(name="show", help="Show resolved configuration")
@click.option(
    "--config",
    "-c",
    default=".iqtoolkit-analyzer.yml",
    help="Config file path (default: .iqtoolkit-analyzer.yml)",
)
def show_config(config: str) -> None:
    cfg = IQToolkitConfig.load(config)
    payload = {
        "default_provider": cfg.default_provider,
        "providers": {name: vars(provider) for name, provider in cfg.providers.items()},
        "databases": {name: vars(db) for name, db in cfg.databases.items()},
        "log_format": cfg.log_format,
        "top_n": cfg.top_n,
        "output": cfg.output,
    }
    click.echo(yaml.safe_dump(payload, sort_keys=False))


@config_group.command(name="create", help="Create a sample configuration file")
@click.option(
    "--output",
    "-o",
    default=".iqtoolkit-analyzer.yml",
    help="Output path (default: .iqtoolkit-analyzer.yml)",
)
def create_config(output: str) -> None:
    sample = {
        "default_provider": "openai",
        "providers": {
            "openai": {"api_key": "${OPENAI_API_KEY}", "model": "gpt-4o"},
            "ollama": {"model": "mistral"},
            "vertex": {
                "project": "${GCP_PROJECT}",
                "region": "${GCP_REGION}",
                "model": "gemini-1.5-pro",
            },
        },
        "databases": {
            "local_postgres": {
                "type": "postgresql",
                "host": "localhost",
                "port": 5432,
                "database": "postgres",
                "username": "postgres",
                "password": "password",
            }
        },
        "log_format": "plain",
        "top_n": 5,
        "output": "./reports/report.md",
    }
    output_path = Path(output)
    output_path.parent.mkdir(parents=True, exist_ok=True)
    output_path.write_text(yaml.safe_dump(sample, sort_keys=False))
    click.secho(f"✅ Wrote sample config to {output_path}", fg="green")


# Register command groups
cli.add_command(postgresql_group)
cli.add_command(mongodb_group)
cli.add_command(config_group)


def main() -> None:
    """Entry point for the CLI"""
    cli()


if __name__ == "__main__":
    main()
