"""Visual cone placement editor. Click on the 5m×5m map to place cones."""
import json
import os
import tkinter as tk

from PIL import Image, ImageTk

MAP_FILE = "智能车地图源文件.avif"
OUTPUT = "cones.json"
MAP_SIZE_M = 5.0  # meters
CANVAS_W = 800
CANVAS_H = 800


class ConeEditor:
    def __init__(self, root):
        self.root = root
        root.title("锥桶编辑器 — 左键放置 / 右键删除 / 滚轮保存")
        self.cones = []  # list of {"x": world_x, "y": world_y}

        # Load map image
        img = Image.open(MAP_FILE)
        self.img_w, self.img_h = img.size
        img = img.resize((CANVAS_W, CANVAS_H), Image.LANCZOS)
        self.photo = ImageTk.PhotoImage(img)

        # Canvas
        self.canvas = tk.Canvas(root, width=CANVAS_W, height=CANVAS_H, cursor="crosshair")
        self.canvas.pack()
        self.canvas.create_image(0, 0, anchor=tk.NW, image=self.photo)

        # Info label
        self.info = tk.Label(root, text="左键放置 | 右键删除最近 | 鼠标查看坐标")
        self.info.pack()

        # Buttons
        btn_frame = tk.Frame(root)
        btn_frame.pack(pady=5)
        tk.Button(btn_frame, text="保存 (cones.json)", command=self.save).pack(side=tk.LEFT, padx=5)
        tk.Button(btn_frame, text="清除全部", command=self.clear).pack(side=tk.LEFT, padx=5)
        tk.Button(btn_frame, text="加载已有", command=self.load_existing).pack(side=tk.LEFT, padx=5)
        tk.Label(btn_frame, text=f"地图: {MAP_SIZE_M}m×{MAP_SIZE_M}m | (-2.5,-2.5) → (2.5,2.5)").pack(side=tk.LEFT, padx=10)

        # Bindings
        self.canvas.bind("<Button-1>", self.on_click)
        self.canvas.bind("<Button-3>", self.on_right_click)
        self.canvas.bind("<Motion>", self.on_move)

        # Load existing if available
        self.load_existing()

    def px_to_world(self, px, py):
        x = px / CANVAS_W * MAP_SIZE_M - MAP_SIZE_M / 2
        y = MAP_SIZE_M / 2 - py / CANVAS_H * MAP_SIZE_M
        return x, y

    def world_to_px(self, wx, wy):
        px = (wx + MAP_SIZE_M / 2) / MAP_SIZE_M * CANVAS_W
        py = (MAP_SIZE_M / 2 - wy) / MAP_SIZE_M * CANVAS_H
        return px, py

    def on_move(self, event):
        wx, wy = self.px_to_world(event.x, event.y)
        self.info.config(text=f"坐标: ({wx:.3f}, {wy:.3f}) | 锥桶数量: {len(self.cones)}")

    def on_click(self, event):
        wx, wy = self.px_to_world(event.x, event.y)
        # Clamp to map bounds
        half = MAP_SIZE_M / 2
        wx = max(-half, min(half, wx))
        wy = max(-half, min(half, wy))
        self.cones.append({"x": round(wx, 3), "y": round(wy, 3)})
        self.redraw()

    def on_right_click(self, event):
        if not self.cones:
            return
        wx, wy = self.px_to_world(event.x, event.y)
        # Remove nearest cone
        idx = min(range(len(self.cones)), key=lambda i: (self.cones[i]["x"] - wx) ** 2 + (self.cones[i]["y"] - wy) ** 2)
        self.cones.pop(idx)
        self.redraw()

    def redraw(self):
        self.canvas.delete("cone")
        r = 5
        for c in self.cones:
            px, py = self.world_to_px(c["x"], c["y"])
            self.canvas.create_oval(px - r, py - r, px + r, py + r, fill="blue", outline="white", width=2, tags="cone")

    def save(self):
        with open(OUTPUT, "w") as f:
            json.dump(self.cones, f, indent=2)
        print(f"已保存 {len(self.cones)} 个锥桶到 {OUTPUT}")
        self.info.config(text=f"已保存 {len(self.cones)} 个锥桶")

    def clear(self):
        self.cones.clear()
        self.redraw()
        print("已清除所有锥桶")

    def load_existing(self):
        if os.path.exists(OUTPUT):
            with open(OUTPUT) as f:
                self.cones = json.load(f)
            self.redraw()
            print(f"已加载 {len(self.cones)} 个锥桶")


if __name__ == "__main__":
    root = tk.Tk()
    app = ConeEditor(root)
    root.mainloop()
