const std = @import("std");
const dvui = @import("dvui");
const WindowContext = @import("../WindowContext.zig");
const Document = @import("../models/Document.zig");
const icons = @import("../icons.zig");
const Object = Document.Object;

const panel_gap: f32 = 12;
const panel_padding: f32 = 5;
const panel_radius: f32 = 24;
const fill_color = dvui.Color.black.opacity(0.2);

const ObjectTreeCallback = union(enum) {
    select: u64,
    delete: u64,
};

fn shapeLabel(shape: Object.ShapeKind) []const u8 {
    return switch (shape) {
        .line => "Line",
        .ellipse => "Ellipse",
        .broken => "Broken line",
    };
}

fn objectTreeRow(open_doc: *WindowContext.OpenDocument, obj: *Object, depth: u32, object_callback: *?ObjectTreeCallback) void {
    const indent_px = depth * 18;
    const is_selected: bool = open_doc.selected_object_id == obj.id;
    const row_id: usize = @intCast(obj.id);

    const focus_color = dvui.themeGet().focus;

    var row = dvui.box(
        @src(),
        .{ .dir = .horizontal },
        .{
            .id_extra = row_id,
            .expand = .horizontal,
        },
    );
    {
        var hovered: bool = false;
        const row_data = row.data();
        var select_row: bool = false;

        // Ручная обработка hover/click по строке без пометки события как handled,
        // чтобы кнопка удаления могла нормально получать свои события.
        for (dvui.events()) |*e| {
            switch (e.evt) {
                .mouse => |*mouse| {
                    if (!dvui.eventMatchSimple(e, row_data)) continue;
                    hovered = true;
                    if (mouse.action == .release and mouse.button == .left) {
                        select_row = true;
                    }
                },
                else => {},
            }
        }

        const background = is_selected or hovered;
        var content = dvui.box(@src(), .{ .dir = .horizontal }, .{
            .expand = .horizontal,
            .margin = dvui.Rect{ .x = @floatFromInt(indent_px) },
            .background = background,
            .color_fill = if (is_selected) focus_color.opacity(0.35) else if (hovered) focus_color.opacity(0.18) else null,
        });
        {
            dvui.labelNoFmt(
                @src(),
                shapeLabel(obj.shape),
                .{},
                .{ .id_extra = row_id, .expand = .horizontal },
            );

            if (hovered) {
                const delete_opts: dvui.Options = .{
                    .id_extra = row_id +% 1,
                    .margin = dvui.Rect{ .x = 4, .w = 6 },
                    .padding = dvui.Rect.all(2),
                    .gravity_y = 0.5,
                    .gravity_x = 1.0,
                };
                if (dvui.buttonIcon(@src(), "Delete object", icons.trash, .{}, .{}, delete_opts)) {
                    object_callback.* = .{ .delete = obj.id };
                    select_row = false;
                }
            }
        }
        content.deinit();

        if (select_row) {
            object_callback.* = .{ .select = obj.id };
        }
    }
    row.deinit();
    for (obj.children.items) |*child| {
        objectTreeRow(open_doc, child, depth + 1, object_callback);
    }
}

fn objectTree(ctx: *WindowContext) void {
    const active_doc = ctx.activeDocument();
    var object_callback: ?ObjectTreeCallback = null;
    if (active_doc) |open_doc| {
        const doc = &open_doc.document;
        if (doc.objects.items.len == 0) {
            dvui.label(@src(), "No objects", .{}, .{});
        } else {
            for (doc.objects.items) |*obj| {
                objectTreeRow(open_doc, obj, 0, &object_callback);
            }
        }
        if (object_callback) |callback| {
            switch (callback) {
                .select => |obj_id| {
                    if (open_doc.selected_object_id == obj_id) {
                        open_doc.selected_object_id = null;
                    } else {
                        open_doc.selected_object_id = obj_id;
                    }
                },
                .delete => |obj_id| {
                    _ = doc.removeObjectById(ctx.allocator, obj_id);
                    if (open_doc.selected_object_id == obj_id)
                        open_doc.selected_object_id = null;
                    open_doc.canvas.requestRedraw();
                },
            }
        }
    } else {
        dvui.label(@src(), "No document", .{}, .{});
    }
}

pub fn leftPanel(ctx: *WindowContext) void {
    var padding = dvui.Rect.all(panel_gap);
    padding.w = 0;
    var panel = dvui.box(
        @src(),
        .{ .dir = .vertical },
        .{
            .expand = .vertical,
            // Фиксированная ширина левой панели
            .min_size_content = .{ .w = 220 },
            .max_size_content = .{ .h = undefined, .w = 220 },
            .background = true,
            .padding = padding,
        },
    );
    {

        // Нижняя часть: настройки
        var settings_section = dvui.box(
            @src(),
            .{ .dir = .vertical },
            .{
                .expand = .horizontal,
                .gravity_y = 1.0,
                .margin = .{ .y = 5 },
                .padding = dvui.Rect.all(panel_padding),
                .corner_radius = dvui.Rect.all(panel_radius),
                .color_fill = fill_color,
                .background = true,
            },
        );
        {
            dvui.label(@src(), "Settings", .{}, .{});

            const active_doc = ctx.activeDocument();
            if (active_doc) |doc| {
                const canvas = &doc.canvas;
                if (dvui.checkbox(@src(), &canvas.native_scaling, "Scaling", .{})) {}
                if (dvui.checkbox(@src(), &canvas.draw_document, "Draw document", .{})) {
                    canvas.requestRedraw();
                }
                if (dvui.checkbox(@src(), &canvas.show_render_stats, "Show stats", .{})) {}
                {
                    dvui.label(@src(), "Rendering quality", .{}, .{});
                    var quality = canvas.getRenderingQuality();
                    if (dvui.sliderEntry(
                        @src(),
                        "{d:0.0}%",
                        .{ .value = &quality, .min = 1.0, .max = 100.0, .interval = 1.0 },
                        .{ .expand = .horizontal },
                    )) {
                        canvas.setRenderingQuality(quality);
                    }
                }
                if (!canvas.draw_document) {
                    if (dvui.button(@src(), if (doc.cpu_render.type == .Gradient) "Gradient" else "Squares", .{}, .{})) {
                        if (doc.cpu_render.type == .Gradient) {
                            doc.cpu_render.type = .Squares;
                        } else {
                            doc.cpu_render.type = .Gradient;
                        }
                        canvas.requestRedraw();
                    }
                }
                if (dvui.button(@src(), "Add random shapes", .{}, .{})) {
                    canvas.addRandomShapes() catch {};
                }
                if (dvui.button(@src(), "Request redraw", .{}, .{})) {
                    canvas.requestRedraw();
                }
            } else {
                dvui.label(@src(), "No document", .{}, .{});
            }
        }
        settings_section.deinit();

        // Верхняя часть: дерево объектов
        var tree_section = dvui.box(
            @src(),
            .{ .dir = .vertical },
            .{
                .expand = .both,
                .padding = dvui.Rect.all(panel_padding),
                .corner_radius = dvui.Rect.all(panel_radius),
                .color_fill = fill_color,
                .background = true,
            },
        );
        {
            dvui.label(@src(), "Objects", .{}, .{
                .font = .{
                    .line_height_factor = dvui.themeGet().font_heading.line_height_factor,
                    .size = dvui.themeGet().font_heading.size + 8,
                },
                .gravity_x = 0.5,
            });
            var scroll = dvui.scrollArea(
                @src(),
                .{ .vertical = .auto, .horizontal = .auto },
                .{ .expand = .both, .background = false },
            );
            {
                objectTree(ctx);
            }
            scroll.deinit();
        }
        tree_section.deinit();
    }
    panel.deinit();
}
