from pathlib import Path
from rich.console import Console
from typing import Optional

from sibi_flux.init.env_engine import EnvParser
from sibi_flux.init.env_generator import EnvGenerator
from sibi_flux.core.project import ProjectService

console = Console()


def init_env(
    project_path: Path,
    env_file: Optional[Path] = None,
    cleanup: bool = False,
    production_mode: bool = False,
    run_settings: bool = True,
    run_creds: bool = True,
    run_discover: bool = True,
    run_infra: bool = True,
):
    """
    Initializes configuration files for the project.
    Allows running individual steps via boolean flags.
    """

    project_path = Path(project_path).resolve()
    project_root = ProjectService.detect_project_root(project_path)
    conf_dir = project_root / "conf"

    # Display environment mode
    mode_text = "[bold yellow]PRODUCTION[/bold yellow]" if production_mode else "[bold cyan]DEVELOPMENT[/bold cyan]"
    console.print(f"Environment Mode: {mode_text}")

    if cleanup:
        _cleanup_env(conf_dir)
        return

    # Parse Environment
    env_path = ProjectService.setup_environment(project_root, env_file)
    if not env_path.exists():
        console.print(f"[yellow]No environment file found at {env_path}. Skipping generation.[/yellow]")
        return

    content = env_path.read_text().strip()
    if not content or all(line.strip().startswith("#") for line in content.splitlines() if line.strip()):
        console.print(f"[yellow]Environment file {env_path.name} is empty or contains only comments.[/yellow]")
        return

    env_data = EnvParser.parse(content)
    conf_dir.mkdir(parents=True, exist_ok=True)

    # 1. settings.py
    if run_settings:
        settings_code = EnvGenerator.generate_pydantic_code(
            env_data, env_file_name=env_path.name, production_mode=production_mode
        )
        (conf_dir / "settings.py").write_text(settings_code)
        console.print(f"[green]Created conf/settings.py (parsed {len(env_data.sections)} sections)[/green]")

    # 2. credentials/__init__.py
    creds_dir = conf_dir / "credentials"
    if run_creds:
        creds_dir.mkdir(parents=True, exist_ok=True)
        creds_code = EnvGenerator.generate_credentials_code(env_data)
        (creds_dir / "__init__.py").write_text(creds_code)
        console.print(f"[green]Created conf/credentials/__init__.py[/green]")

    # 3. Update modular YAML configs in conf/
    if run_discover:
        from sibi_flux.init.discovery_updater import DiscoveryParamsUpdater
        DiscoveryParamsUpdater.update(project_root, env_data, production_mode=production_mode)

    # 4. Generate configuration package code from YAML files
    if run_infra:
        _generate_infra_code(project_root, project_path.name, conf_dir)


def _cleanup_env(conf_dir: Path):
    settings_path = conf_dir / "settings.py"
    creds_path = conf_dir / "credentials" / "__init__.py"

    removed = []
    if settings_path.exists():
        settings_path.unlink()
        removed.append("conf/settings.py")

    if creds_path.exists():
        creds_path.unlink()
        removed.append("conf/credentials/__init__.py")

    if removed:
        console.print(f"[green]Removed: {', '.join(removed)}[/green]")
    else:
        console.print("[yellow]No configuration files found to remove.[/yellow]")


def _generate_infra_code(project_root: Path, project_name: str, conf_dir: Path):
    discovery_data = ProjectService.load_modular_config(project_root)
    if not discovery_data:
        return

    try:
        # A. Storage
        storage_code = EnvGenerator.generate_storage_code(discovery_data, project_name=project_name)
        if storage_code:
            storage_dir = conf_dir / "storage"
            storage_dir.mkdir(parents=True, exist_ok=True)
            (storage_dir / "__init__.py").write_text(storage_code)
            console.print(f"[green]Created conf/storage/__init__.py[/green]")
        
        # B. OSMnx
        osmnx_code = EnvGenerator.generate_osmnx_code(discovery_data, project_name=project_name)
        if osmnx_code:
            osmnx_dir = conf_dir / "osmnx"
            osmnx_dir.mkdir(parents=True, exist_ok=True)
            (osmnx_dir / "__init__.py").write_text(osmnx_code)
            console.print(f"[green]Created conf/osmnx/__init__.py[/green]")
        else:
            osmnx_dir = conf_dir / "osmnx"
            if osmnx_dir.exists():
                from sibi_flux.core import SecureResource
                secure = SecureResource(project_root=project_root)
                try:
                    # Enforce sandbox
                    secure.get_secure_path(osmnx_dir)
                    import shutil
                    shutil.rmtree(osmnx_dir)
                    console.print(f"[yellow]Removed {osmnx_dir.relative_to(project_root)} (no OSMnx settings found).[/yellow]")
                except Exception as e:
                     console.print(f"[yellow]Skipping {osmnx_dir.name} deletion: {e}[/yellow]")
        
        # C. Main Entry Point
        main_app_code = EnvGenerator.generate_main_app_code(project_root, discovery_data, project_name=project_root.name)
        if main_app_code:
            main_file = project_root / "main.py"
            main_file.write_text(main_app_code)
            console.print(f"[green]Created main.py[/green]")

    except Exception as e:
        console.print(f"[yellow]Warning: Could not generate configuration: {e}[/yellow]")
