import tkinter as tk
import random

# ---------------- CONFIG ----------------
TILE_SIZE = 30

WORLD_WIDTH = 200
WORLD_HEIGHT = 90

SCREEN_WIDTH = 20
SCREEN_HEIGHT = 15

root = tk.Tk()
root.title("Cave Sandbox FIX spawn")

canvas = tk.Canvas(
    root,
    width=SCREEN_WIDTH*TILE_SIZE,
    height=SCREEN_HEIGHT*TILE_SIZE,
    bg="black"
)
canvas.pack()

# ---------------- MONDE ----------------
world = [[0 for _ in range(WORLD_WIDTH)] for _ in range(WORLD_HEIGHT)]

# ---------------- GENERATION ----------------
surface = WORLD_HEIGHT // 3
heights = []

for x in range(WORLD_WIDTH):
    surface += random.choice([-1, 0, 0, 1])
    surface = max(10, min(WORLD_HEIGHT//2 - 10, surface))
    heights.append(surface)

for x in range(WORLD_WIDTH):
    h = heights[x]

    for y in range(WORLD_HEIGHT):

        # plafond épais
        if y < 6:
            world[y][x] = 2

        # terrain haut
        elif y < h:
            world[y][x] = 2

        # sol profond
        elif y > h + 12:
            world[y][x] = 2

        # zone grotte
        else:
            if y > WORLD_HEIGHT // 2:
                if random.random() < 0.12:
                    world[y][x] = 0
                else:
                    world[y][x] = 2
            else:
                world[y][x] = 0

# ---------------- SPAWN SAFE ----------------
def find_spawn():
    for y in range(WORLD_HEIGHT):
        for x in range(WORLD_WIDTH):
            # cherche un espace vide de 2x2
            if (
                world[y][x] == 0 and
                world[y+1][x] == 0 and
                world[y][x+1] == 0 and
                world[y+1][x+1] == 0
            ):
                return x, y
    return 10, 10  # fallback

spawn_x, spawn_y = find_spawn()

# ---------------- JOUEUR ----------------
player = {
    "x": float(spawn_x),
    "y": float(spawn_y),
    "vx": 0.0,
    "vy": 0.0,
    "on_ground": False
}

keys = set()

# ---------------- CAMERA ----------------
camera_x = 0.0
camera_y = 0.0
dead_zone = 4

# ---------------- COLLISIONS ----------------
def is_solid(x, y):
    if x < 0 or x >= WORLD_WIDTH or y < 0 or y >= WORLD_HEIGHT:
        return True
    return world[y][x] != 0

def collides(x, y):
    return (
        is_solid(int(x), int(y)) or
        is_solid(int(x + 0.9), int(y)) or
        is_solid(int(x), int(y + 0.9)) or
        is_solid(int(x + 0.9), int(y + 0.9))
    )

# ---------------- MOVE ----------------
def move():
    new_x = player["x"] + player["vx"]
    if not collides(new_x, player["y"]):
        player["x"] = new_x

    player["vy"] += 0.04
    new_y = player["y"] + player["vy"]

    if not collides(player["x"], new_y):
        player["y"] = new_y
        player["on_ground"] = False
    else:
        if player["vy"] > 0:
            player["on_ground"] = True
        player["vy"] = 0

# ---------------- CAMERA ----------------
def update_camera():
    global camera_x, camera_y

    left = camera_x + dead_zone
    right = camera_x + SCREEN_WIDTH - dead_zone
    top = camera_y + dead_zone
    bottom = camera_y + SCREEN_HEIGHT - dead_zone

    if player["x"] < left:
        camera_x -= left - player["x"]
    elif player["x"] > right:
        camera_x += player["x"] - right

    if player["y"] < top:
        camera_y -= top - player["y"]
    elif player["y"] > bottom:
        camera_y += player["y"] - bottom

    camera_x = max(0, min(WORLD_WIDTH - SCREEN_WIDTH, camera_x))
    camera_y = max(0, min(WORLD_HEIGHT - SCREEN_HEIGHT, camera_y))

# ---------------- LIGHT ----------------
def get_light(x, y, px, py):
    d = abs(x - px) + abs(y - py)

    if d < 3:
        return 1.0
    elif d < 6:
        return 0.6
    elif d < 10:
        return 0.3
    return 0.1

# ---------------- UPDATE ----------------
def update():
    if "q" in keys:
        player["vx"] = -0.23
    elif "d" in keys:
        player["vx"] = 0.23
    else:
        player["vx"] = 0

    if "space" in keys and player["on_ground"]:
        player["vy"] = -0.4
        player["on_ground"] = False

    move()
    update_camera()
    draw()

    root.after(16, update)

# ---------------- DRAW ----------------
def draw():
    canvas.delete("all")

    cam_x = int(camera_x)
    cam_y = int(camera_y)

    for y in range(SCREEN_HEIGHT):
        for x in range(SCREEN_WIDTH):

            wx = x + cam_x
            wy = y + cam_y

            if 0 <= wx < WORLD_WIDTH and 0 <= wy < WORLD_HEIGHT:
                tile = world[wy][wx]

                if tile != 0:

                    light = get_light(wx, wy, player["x"], player["y"])

                    if light > 0.8:
                        color = "#d6b77a"
                    elif light > 0.5:
                        color = "#8a6a3a"
                    elif light > 0.2:
                        color = "#4a341a"
                    else:
                        color = "#0a0a0a"

                    canvas.create_rectangle(
                        x*TILE_SIZE, y*TILE_SIZE,
                        (x+1)*TILE_SIZE, (y+1)*TILE_SIZE,
                        fill=color,
                        outline=""
                    )

    # joueur
    px = (player["x"] - cam_x) * TILE_SIZE
    py = (player["y"] - cam_y) * TILE_SIZE

    canvas.create_rectangle(
        px, py,
        px + TILE_SIZE,
        py + TILE_SIZE,
        fill="white"
    )

# ---------------- INPUT ----------------
def key_down(event):
    keys.add(event.keysym.lower())

def key_up(event):
    keys.discard(event.keysym.lower())

root.bind("<KeyPress>", key_down)
root.bind("<KeyRelease>", key_up)

update()
root.mainloop()
