"""
main.py — Powernet entry point.

Scene graph
-----------
main_menu  ←→  world_manager  ←→  new_world
               world_manager  →   game  (stub)
main_menu  ←→  settings

Key bindings (global)
---------------------
F3    Toggle debug overlay
F11   Toggle fullscreen / windowed
ESC   Context-dependent (handled by each scene)
"""

from __future__ import annotations

import sys
import pygame


def _toggle_fullscreen(screen: pygame.Surface) -> pygame.Surface:
    if screen.get_flags() & pygame.FULLSCREEN:
        return pygame.display.set_mode((1280, 720), pygame.RESIZABLE)
    return pygame.display.set_mode((0, 0), pygame.FULLSCREEN | pygame.RESIZABLE)


def _draw_debug(
    surface: pygame.Surface,
    clock: pygame.time.Clock,
    scene_name: str,
) -> None:
    """Draw the F3 debug overlay (top-left corner)."""
    try:
        import psutil  # type: ignore[import]
        cpu = f"{psutil.cpu_percent():.0f}%"
        mem = psutil.virtual_memory()
        ram = f"{mem.used / 1024**2:.0f} / {mem.total / 1024**2:.0f} MB"
    except Exception:
        cpu = "n/a"
        ram = "n/a"

    fps = clock.get_fps()
    lines = [
        "DEBUG  (F3 to close)",
        "",
        f"FPS:    {fps:.1f}",
        f"CPU:    {cpu}",
        f"RAM:    {ram}",
        f"Scene:  {scene_name}",
        f"Pygame: {pygame.version.ver}",
        f"Python: {sys.version.split()[0]}",
    ]

    pad = 10
    line_h = 18
    panel_w = 220
    panel_h = pad * 2 + len(lines) * line_h
    panel = pygame.Surface((panel_w, panel_h), pygame.SRCALPHA)
    panel.fill((8, 14, 22, 210))
    pygame.draw.rect(panel, (50, 80, 130, 180), panel.get_rect(), width=1)
    sw = surface.get_width()
    panel_x = sw - panel_w - 8
    surface.blit(panel, (panel_x, 8))

    try:
        from helpers.gui import theme
        font = theme.font(14)
    except Exception:
        font = pygame.font.SysFont("monospace", 13)

    for i, line in enumerate(lines):
        col = (232, 137, 12) if i == 0 else (170, 190, 215)
        s = font.render(line, True, col)
        surface.blit(s, (panel_x + pad, 8 + pad + i * line_h))


def main() -> None:
    pygame.init()
    pygame.display.set_caption("Powernet")
    screen = pygame.display.set_mode((1280, 720), pygame.RESIZABLE)
    clock  = pygame.time.Clock()

    # Load settings and apply language before importing scenes.
    from helpers.settings import get_settings
    from helpers.i18n import set_language
    settings = get_settings()
    set_language(settings.language)

    # Apply music volume from settings.
    from helpers.music import music_manager, MUSIC_END
    music_manager.set_volume(settings.volume_music / 100.0)

    # Apply colorblind palette if enabled.
    from helpers.gui import theme
    theme.apply_colorblind(settings.colorblind_mode)

    # Apply display mode from settings before opening the window properly.
    if settings.fullscreen:
        screen = pygame.display.set_mode((0, 0), pygame.FULLSCREEN | pygame.RESIZABLE)
    elif settings.resolution_w and settings.resolution_h:
        screen = pygame.display.set_mode(
            (settings.resolution_w, settings.resolution_h), pygame.RESIZABLE
        )

    # Import scenes after pygame.init() so font/mixer subsystems are ready.
    from scenes.main_menu      import MainMenu
    from scenes.world_manager  import WorldManager
    from scenes.new_world      import NewWorld
    from scenes.edit_world     import EditWorld
    from scenes.settings_menu  import SettingsMenu
    from scenes.credits        import Credits
    from scenes.game           import Game
    from scenes.loading_screen import LoadingScreen  # type: ignore[import]
    from helpers.world_data    import WorldMeta

    scene: object = MainMenu(screen)
    scene_name: str = "MainMenu"
    running = True
    debug_visible = False

    # Determine FPS cap (0 = unlimited → use a high cap so the loop stays responsive)
    fps_cap = settings.fps_limit if settings.fps_limit > 0 else 0

    while running:
        dt = min(clock.tick(fps_cap) / 1000.0, 0.1)   # cap dt at 100 ms

        events = pygame.event.get()

        for event in events:
            if event.type == pygame.QUIT:
                running = False
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_F11:
                    screen = _toggle_fullscreen(screen)
                elif event.key == pygame.K_F3:
                    debug_visible = not debug_visible
            elif event.type == MUSIC_END:
                # Global track cycling — works regardless of which scene is active.
                music_manager.next_track()

        result = scene.update(dt, events)  # type: ignore[union-attr]

        # ---- Scene transitions ----
        if result == "quit":
            running = False

        elif result == "world_manager":
            scene = WorldManager(screen)
            scene_name = "WorldManager"

        elif result == "new_world":
            scene = NewWorld(screen)
            scene_name = "NewWorld"

        elif result and result.startswith("created:"):
            scene = WorldManager(screen)
            scene_name = "WorldManager"

        elif result and result.startswith("edit_world:"):
            world_id = result.split(":", 1)[1]
            scene = EditWorld(screen, world_id)
            scene_name = "EditWorld"

        elif result == "settings":
            scene = SettingsMenu(screen)
            scene_name = "SettingsMenu"

        elif result == "back":
            music_manager.set_playlist("menu")
            scene = MainMenu(screen)
            scene_name = "MainMenu"

        elif result and result.startswith("play:"):
            world_id = result.split(":", 1)[1]
            # Switch to game playlist and go through loading screen
            music_manager.set_playlist("game")
            scene      = LoadingScreen(screen, world_id)
            scene_name = "LoadingScreen"

        elif result and result.startswith("play_ready:"):
            world_id = result.split(":", 1)[1]
            try:
                meta = WorldMeta.load(world_id)
            except FileNotFoundError:
                meta = None
            if meta is not None:
                scene      = Game(screen, meta)
                scene_name = "Game"

        elif result == "credits":
            scene = Credits(screen)
            scene_name = "Credits"

        # ---- Render ----
        scene.draw(screen)  # type: ignore[union-attr]

        if debug_visible:
            _draw_debug(screen, clock, scene_name)

        pygame.display.flip()

    pygame.quit()
    sys.exit(0)


if __name__ == "__main__":
    main()
