"""
PIX-8 Fantasy Console
Pure Python • TIC-80 inspired
"""

import sys
import importlib.util
import pygame

# -------------------------
# Console constants
# -------------------------

WIDTH = 128
HEIGHT = 128
SCALE = 4
FPS = 60

__version__ = "0.0.3"

PALETTE = [
    (0, 0, 0),
    (29, 43, 83),
    (126, 37, 83),
    (0, 135, 81),
    (171, 82, 54),
    (95, 87, 79),
    (194, 195, 199),
    (255, 241, 232),
    (255, 0, 77),
    (255, 163, 0),
    (255, 236, 39),
    (0, 228, 54),
    (41, 173, 255),
    (131, 118, 156),
    (255, 119, 168),
    (255, 204, 170),
]

# -------------------------
# Input System
# -------------------------

class Input:
    def __init__(self):
        self.keys = None
        self.joystick = None

        if pygame.joystick.get_count() > 0:
            self.joystick = pygame.joystick.Joystick(0)
            self.joystick.init()

    def update(self):
        self.keys = pygame.key.get_pressed()

    def btn(self, key):
        return bool(self.keys and self.keys[key])

    def btn_gamepad(self, button):
        return bool(self.joystick and self.joystick.get_button(button))

# -------------------------
# PIX-8 Core
# -------------------------

class Pix8:
    def __init__(self, show_gui=True):
        pygame.init()
        pygame.font.init()

        self.show_gui = show_gui

        self.window = pygame.display.set_mode(
            (WIDTH * SCALE, HEIGHT * SCALE)
        )
        pygame.display.set_caption("PIX-8")

        self.surface = pygame.Surface((WIDTH, HEIGHT))
        self.clock = pygame.time.Clock()
        self.input = Input()

        self.cart = None
        self.running = True

        # UI font rendered at FINAL resolution (no blur)
        self.ui_font = pygame.font.SysFont("consolas", 16)

    # -------- Graphics API --------

    def cls(self, color=0):
        self.surface.fill(PALETTE[color])

    def pix(self, x, y, color):
        if 0 <= x < WIDTH and 0 <= y < HEIGHT:
            self.surface.set_at((x, y), PALETTE[color])

    def rect(self, x, y, w, h, color):
        pygame.draw.rect(
            self.surface,
            PALETTE[color],
            pygame.Rect(x, y, w, h)
        )

    def print(self, text, x, y, color=7):
        # Draws text INTO GAME RESOLUTION (pixel-style)
        font = pygame.font.SysFont("consolas", 8)
        img = font.render(str(text), False, PALETTE[color])
        self.surface.blit(img, (x, y))

    # -------- Input API --------

    def btn(self, key):
        return self.input.btn(key)

    # -------- Cartridge System --------

    def load_cart(self, path: str):
        spec = importlib.util.spec_from_file_location("cart", path)
        cart = importlib.util.module_from_spec(spec)
        spec.loader.exec_module(cart)

        self.cart = cart
        if hasattr(cart, "init"):
            cart.init(self)

    # -------- Main Loop --------

    def run(self):
        while self.running:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    self.running = False

            self.input.update()

            if self.cart and hasattr(self.cart, "update"):
                self.cart.update(self)

            if self.cart and hasattr(self.cart, "draw"):
                self.cart.draw(self)

            # Scale game surface
            scaled = pygame.transform.scale(
                self.surface,
                (WIDTH * SCALE, HEIGHT * SCALE)
            )
            self.window.blit(scaled, (0, 0))

            # Draw GUI AFTER scaling (crisp text)
            if self.show_gui:
                self._draw_gui()

            pygame.display.flip()
            self.clock.tick(FPS)

        pygame.quit()
        sys.exit()

    # -------- GUI --------

    def _draw_gui(self):
        bar = pygame.Surface((WIDTH * SCALE, 24))
        bar.fill((29, 43, 83))

        self.window.blit(bar, (0, 0))

        title = self.ui_font.render(
            f"PIX-8 {__version__}", True, (255, 241, 232)
        )
        fps = self.ui_font.render(
            f"{int(self.clock.get_fps())} FPS", True, (255, 241, 232)
        )

        self.window.blit(title, (8, 4))
        self.window.blit(fps, (WIDTH * SCALE - 80, 4))

# -------------------------
# Example Cartridge
# -------------------------

class ExampleCart:
    def __init__(self):
        self.x = 60
        self.y = 60

    def update(self, p: Pix8):
        if p.btn(pygame.K_LEFT):
            self.x -= 1
        if p.btn(pygame.K_RIGHT):
            self.x += 1
        if p.btn(pygame.K_UP):
            self.y -= 1
        if p.btn(pygame.K_DOWN):
            self.y += 1

    def draw(self, p: Pix8):
        p.cls(0)
        p.rect(self.x, self.y, 8, 8, 8)
        p.print("HELLO PIX-8", 28, 110, 11)

# -------------------------
# __main__
# -------------------------

def main():
    # --nogui flag disables GUI bar
    show_gui = "--nogui" not in sys.argv

    console = Pix8(show_gui=show_gui)

    # Default cart
    console.cart = ExampleCart()

    # External cartridge
    for arg in sys.argv[1:]:
        if arg.endswith(".py"):
            console.load_cart(arg)

    console.run()

if __name__ == "__main__":
    main()

