use nalgebra_glm::{Vec2, Vec4};

use crate::ecs::text::components::TextProperties;
use crate::render::wgpu::passes::geometry::{UiLayer, UiRect};

use super::super::layout::Layout;
use super::super::types::{DockPosition, Rect, ResizeEdge, UiId, UiResponse};
use super::types::{ImmediateUi, UiWidget};

impl ImmediateUi {
    pub fn begin_panel(&mut self, title: &str, default_rect: Rect) {
        let padding = self.style.padding;
        let header_height = self.style.panel_header_height;
        let resize_margin = 6.0;
        let min_panel_width = 100.0;
        let min_panel_height = header_height + padding * 2.0;
        let default_dock_size = 300.0;

        let panel_id = self.make_id(title);
        let resize_id = UiId::with_parent(panel_id, "_resize");
        self.push_id(title);

        let is_new_panel = !self.widget_states.contains_key(&panel_id);
        let mut state = self.get_state(panel_id);
        if is_new_panel {
            state.focus_order = self.next_focus_order;
            self.next_focus_order += 1;
            self.set_state(panel_id, state);
        }
        let collapsed = state.collapsed;
        let dock_position = state.dock_position;

        self.current_panel_z_base = state.focus_order * 1000;
        self.next_z_index = 0;

        let reserved = self.reserved_areas;
        let (panel_position, panel_size, reserve_update) = match dock_position {
            DockPosition::None => {
                let pos = state.panel_position.unwrap_or(default_rect.min);
                let size = state.panel_size.unwrap_or(default_rect.size());
                (pos, size, None)
            }
            DockPosition::Left => {
                let width = state.panel_size.map(|s| s.x).unwrap_or(default_dock_size);
                let available_height = self.screen_size.y - reserved.top - reserved.bottom;
                (
                    Vec2::new(reserved.left, reserved.top),
                    Vec2::new(width, available_height),
                    Some((DockPosition::Left, width)),
                )
            }
            DockPosition::Right => {
                let width = state.panel_size.map(|s| s.x).unwrap_or(default_dock_size);
                let available_height = self.screen_size.y - reserved.top - reserved.bottom;
                (
                    Vec2::new(self.screen_size.x - reserved.right - width, reserved.top),
                    Vec2::new(width, available_height),
                    Some((DockPosition::Right, width)),
                )
            }
            DockPosition::Top => {
                let height = state.panel_size.map(|s| s.y).unwrap_or(default_dock_size);
                let available_width = self.screen_size.x - reserved.left - reserved.right;
                (
                    Vec2::new(reserved.left, reserved.top),
                    Vec2::new(available_width, height),
                    Some((DockPosition::Top, height)),
                )
            }
            DockPosition::Bottom => {
                let height = state.panel_size.map(|s| s.y).unwrap_or(default_dock_size);
                let available_width = self.screen_size.x - reserved.left - reserved.right;
                (
                    Vec2::new(reserved.left, self.screen_size.y - reserved.bottom - height),
                    Vec2::new(available_width, height),
                    Some((DockPosition::Bottom, height)),
                )
            }
        };

        if let Some((dock, size)) = reserve_update {
            match dock {
                DockPosition::Left => self.reserved_areas.left += size,
                DockPosition::Right => self.reserved_areas.right += size,
                DockPosition::Top => self.reserved_areas.top += size,
                DockPosition::Bottom => self.reserved_areas.bottom += size,
                DockPosition::None => {}
            }
        }

        self.current_layer = if dock_position == DockPosition::None {
            UiLayer::FloatingPanels
        } else {
            UiLayer::DockedPanels
        };

        let actual_height = if collapsed {
            header_height
        } else {
            panel_size.y
        };
        let rect = Rect::new(
            panel_position.x,
            panel_position.y,
            panel_size.x,
            actual_height,
        );

        let detect_resize_edge =
            |mouse: Vec2, panel_rect: Rect, dock: DockPosition| -> ResizeEdge {
                if collapsed {
                    return ResizeEdge::None;
                }
                let left = (mouse.x - panel_rect.min.x).abs() < resize_margin;
                let right = (mouse.x - panel_rect.max.x).abs() < resize_margin;
                let top = (mouse.y - panel_rect.min.y).abs() < resize_margin;
                let bottom = (mouse.y - panel_rect.max.y).abs() < resize_margin;
                let in_x = mouse.x >= panel_rect.min.x - resize_margin
                    && mouse.x <= panel_rect.max.x + resize_margin;
                let in_y = mouse.y >= panel_rect.min.y - resize_margin
                    && mouse.y <= panel_rect.max.y + resize_margin;

                match dock {
                    DockPosition::Left => {
                        if right && in_y {
                            ResizeEdge::Right
                        } else {
                            ResizeEdge::None
                        }
                    }
                    DockPosition::Right => {
                        if left && in_y {
                            ResizeEdge::Left
                        } else {
                            ResizeEdge::None
                        }
                    }
                    DockPosition::Top => {
                        if bottom && in_x {
                            ResizeEdge::Bottom
                        } else {
                            ResizeEdge::None
                        }
                    }
                    DockPosition::Bottom => {
                        if top && in_x {
                            ResizeEdge::Top
                        } else {
                            ResizeEdge::None
                        }
                    }
                    DockPosition::None => {
                        if top && left && in_x && in_y {
                            ResizeEdge::TopLeft
                        } else if top && right && in_x && in_y {
                            ResizeEdge::TopRight
                        } else if bottom && left && in_x && in_y {
                            ResizeEdge::BottomLeft
                        } else if bottom && right && in_x && in_y {
                            ResizeEdge::BottomRight
                        } else if left && in_y {
                            ResizeEdge::Left
                        } else if right && in_y {
                            ResizeEdge::Right
                        } else if top && in_x {
                            ResizeEdge::Top
                        } else if bottom && in_x {
                            ResizeEdge::Bottom
                        } else {
                            ResizeEdge::None
                        }
                    }
                }
            };

        let hovered_edge = if state.resizable {
            detect_resize_edge(self.mouse_pos, rect, dock_position)
        } else {
            ResizeEdge::None
        };
        let resize_state = self.get_state(resize_id);

        if resize_state.resize_edge != ResizeEdge::None
            && self.mouse_down
            && let Some(start_rect) = resize_state.resize_start_rect
            && let Some(drag_start) = resize_state.drag_start
        {
            let delta = self.mouse_pos - drag_start;
            let mut new_size = panel_size;

            match dock_position {
                DockPosition::Left => {
                    new_size.x = (start_rect.width() + delta.x).max(min_panel_width);
                }
                DockPosition::Right => {
                    new_size.x = (start_rect.width() - delta.x).max(min_panel_width);
                }
                DockPosition::Top => {
                    new_size.y = (start_rect.height() + delta.y).max(min_panel_height);
                }
                DockPosition::Bottom => {
                    new_size.y = (start_rect.height() - delta.y).max(min_panel_height);
                }
                DockPosition::None => {
                    let mut new_pos = panel_position;
                    match resize_state.resize_edge {
                        ResizeEdge::Left => {
                            let new_x = start_rect.min.x + delta.x;
                            let new_width = (start_rect.width() - delta.x).max(min_panel_width);
                            if new_width > min_panel_width {
                                new_pos.x = new_x;
                            }
                            new_size.x = new_width;
                        }
                        ResizeEdge::Right => {
                            new_size.x = (start_rect.width() + delta.x).max(min_panel_width);
                        }
                        ResizeEdge::Top => {
                            let new_y = start_rect.min.y + delta.y;
                            let new_height = (start_rect.height() - delta.y).max(min_panel_height);
                            if new_height > min_panel_height {
                                new_pos.y = new_y;
                            }
                            new_size.y = new_height;
                        }
                        ResizeEdge::Bottom => {
                            new_size.y = (start_rect.height() + delta.y).max(min_panel_height);
                        }
                        ResizeEdge::TopLeft => {
                            let new_x = start_rect.min.x + delta.x;
                            let new_y = start_rect.min.y + delta.y;
                            let new_width = (start_rect.width() - delta.x).max(min_panel_width);
                            let new_height = (start_rect.height() - delta.y).max(min_panel_height);
                            if new_width > min_panel_width {
                                new_pos.x = new_x;
                            }
                            if new_height > min_panel_height {
                                new_pos.y = new_y;
                            }
                            new_size.x = new_width;
                            new_size.y = new_height;
                        }
                        ResizeEdge::TopRight => {
                            let new_y = start_rect.min.y + delta.y;
                            let new_height = (start_rect.height() - delta.y).max(min_panel_height);
                            if new_height > min_panel_height {
                                new_pos.y = new_y;
                            }
                            new_size.x = (start_rect.width() + delta.x).max(min_panel_width);
                            new_size.y = new_height;
                        }
                        ResizeEdge::BottomLeft => {
                            let new_x = start_rect.min.x + delta.x;
                            let new_width = (start_rect.width() - delta.x).max(min_panel_width);
                            if new_width > min_panel_width {
                                new_pos.x = new_x;
                            }
                            new_size.x = new_width;
                            new_size.y = (start_rect.height() + delta.y).max(min_panel_height);
                        }
                        ResizeEdge::BottomRight => {
                            new_size.x = (start_rect.width() + delta.x).max(min_panel_width);
                            new_size.y = (start_rect.height() + delta.y).max(min_panel_height);
                        }
                        ResizeEdge::None => {}
                    }
                    let mut new_panel_state = self.get_state(panel_id);
                    new_panel_state.panel_position = Some(new_pos);
                    new_panel_state.panel_size = Some(new_size);
                    self.set_state(panel_id, new_panel_state);
                }
            }

            if dock_position != DockPosition::None {
                let mut new_panel_state = self.get_state(panel_id);
                new_panel_state.panel_size = Some(new_size);
                self.set_state(panel_id, new_panel_state);
            }
        } else if hovered_edge != ResizeEdge::None && self.mouse_just_pressed {
            let mut new_resize_state = resize_state;
            new_resize_state.resize_edge = hovered_edge;
            new_resize_state.drag_start = Some(self.mouse_pos);
            new_resize_state.resize_start_rect = Some(Rect::new(
                panel_position.x,
                panel_position.y,
                panel_size.x,
                panel_size.y,
            ));
            self.set_state(resize_id, new_resize_state);
            self.active_widget = Some(resize_id);
        } else if !self.mouse_down && resize_state.resize_edge != ResizeEdge::None {
            let mut new_resize_state = resize_state;
            new_resize_state.resize_edge = ResizeEdge::None;
            new_resize_state.drag_start = None;
            new_resize_state.resize_start_rect = None;
            self.set_state(resize_id, new_resize_state);
            if self.active_widget == Some(resize_id) {
                self.active_widget = None;
            }
        }

        let header_rect = Rect::new(rect.x(), rect.y(), rect.width(), header_height);
        let is_resizing = resize_state.resize_edge != ResizeEdge::None;
        let header_response = if !is_resizing {
            self.interact(panel_id, header_rect)
        } else {
            UiResponse::none(panel_id, header_rect)
        };

        if header_response.drag_started
            || (self.mouse_just_pressed && rect.contains(self.mouse_pos))
        {
            let mut new_state = self.get_state(panel_id);
            new_state.focus_order = self.next_focus_order;
            self.next_focus_order += 1;
            self.set_state(panel_id, new_state);
            self.current_panel_z_base = new_state.focus_order * 1000;
        }

        let mut dock_preview: Option<DockPosition> = None;

        if header_response.active && !is_resizing {
            if let Some(drag_start) = state.drag_start {
                let drag_offset = self.mouse_pos - drag_start;

                if dock_position != DockPosition::None {
                    let drag_distance = drag_offset.magnitude();
                    if drag_distance > 50.0 && !state.pinned {
                        let mut new_state = self.get_state(panel_id);
                        new_state.dock_position = DockPosition::None;
                        if let Some(undocked) = state.undocked_rect {
                            let center_offset = self.mouse_pos
                                - Vec2::new(undocked.width() * 0.5, header_height * 0.5);
                            new_state.panel_position = Some(center_offset);
                            new_state.panel_size = Some(undocked.size());
                        } else {
                            new_state.panel_position = Some(
                                self.mouse_pos
                                    - Vec2::new(default_rect.width() * 0.5, header_height * 0.5),
                            );
                            new_state.panel_size = Some(default_rect.size());
                        }
                        new_state.drag_start = Some(self.mouse_pos);
                        self.set_state(panel_id, new_state);
                    }
                } else {
                    let new_position = panel_position + drag_offset;
                    let mut new_state = self.get_state(panel_id);
                    new_state.panel_position = Some(new_position);
                    new_state.drag_start = Some(self.mouse_pos);
                    self.set_state(panel_id, new_state);

                    dock_preview = Some(DockPosition::None);
                }
            }
        } else if state.drag_start.is_some()
            && self.mouse_just_released
            && dock_position == DockPosition::None
        {
            let indicator_size = 40.0;
            let indicator_spacing = 4.0;
            let center = self.screen_size * 0.5;
            let dock_buttons = [
                (
                    Rect::from_center_size(
                        Vec2::new(center.x, center.y - indicator_size - indicator_spacing),
                        Vec2::new(indicator_size, indicator_size),
                    ),
                    DockPosition::Top,
                ),
                (
                    Rect::from_center_size(
                        Vec2::new(center.x, center.y + indicator_size + indicator_spacing),
                        Vec2::new(indicator_size, indicator_size),
                    ),
                    DockPosition::Bottom,
                ),
                (
                    Rect::from_center_size(
                        Vec2::new(center.x - indicator_size - indicator_spacing, center.y),
                        Vec2::new(indicator_size, indicator_size),
                    ),
                    DockPosition::Left,
                ),
                (
                    Rect::from_center_size(
                        Vec2::new(center.x + indicator_size + indicator_spacing, center.y),
                        Vec2::new(indicator_size, indicator_size),
                    ),
                    DockPosition::Right,
                ),
            ];
            let mut target_dock = DockPosition::None;
            for (btn_rect, dock_pos) in dock_buttons.iter() {
                if btn_rect.contains(self.mouse_pos) {
                    target_dock = *dock_pos;
                    break;
                }
            }
            if target_dock != DockPosition::None {
                let mut new_state = self.get_state(panel_id);
                new_state.undocked_rect = Some(Rect::new(
                    panel_position.x,
                    panel_position.y,
                    panel_size.x,
                    panel_size.y,
                ));
                new_state.dock_position = target_dock;
                new_state.panel_size = Some(Vec2::new(default_dock_size, default_dock_size));
                self.set_state(panel_id, new_state);
            }
        } else if state.panel_position.is_none() || state.panel_size.is_none() {
            let mut new_state = self.get_state(panel_id);
            if new_state.panel_position.is_none() {
                new_state.panel_position = Some(panel_position);
            }
            if new_state.panel_size.is_none() {
                new_state.panel_size = Some(panel_size);
            }
            self.set_state(panel_id, new_state);
        }

        if dock_preview.is_some() {
            self.render_dock_indicators(rect, panel_id);
        }

        let show_header = dock_position == DockPosition::None;
        let corner_radius = if show_header {
            self.style.corner_radius
        } else {
            0.0
        };

        self.add_rect(UiRect {
            position: rect.min,
            size: rect.size(),
            color: self.style.background_color,
            corner_radius,
            border_width: self.style.border_width,
            border_color: self.style.border_color,
            clip_rect: None,
            ..Default::default()
        });

        if show_header {
            self.render_floating_panel_header(rect, title, panel_id, collapsed, header_response);
        } else {
            self.render_docked_panel_header(rect, panel_id, state.pinned);
        }

        let edge_to_highlight = if is_resizing {
            resize_state.resize_edge
        } else {
            hovered_edge
        };

        if edge_to_highlight != ResizeEdge::None {
            self.render_resize_edge_highlight(rect, edge_to_highlight);
        }

        if collapsed && show_header {
            let zero_rect = Rect::new(-10000.0, -10000.0, 0.0, 0.0);
            self.push_clip(zero_rect);
            self.layout_stack
                .push(Layout::panel(zero_rect, 0.0, self.style.spacing));
        } else {
            let is_horizontal_dock =
                dock_position == DockPosition::Top || dock_position == DockPosition::Bottom;
            let v_padding = if is_horizontal_dock { 2.0 } else { padding };
            let h_padding = padding;

            let content_y_offset = if show_header {
                header_height + v_padding
            } else {
                v_padding
            };
            let content_height_offset = if show_header {
                header_height + v_padding * 2.0
            } else {
                v_padding * 2.0
            };
            let content_rect = Rect::new(
                rect.x() + h_padding,
                rect.y() + content_y_offset,
                rect.width() - h_padding * 2.0,
                rect.height() - content_height_offset,
            );

            self.push_clip(content_rect);
            self.layout_stack
                .push(Layout::panel(content_rect, 0.0, self.style.spacing));
        }
    }

    fn render_dock_indicators(&mut self, _rect: Rect, _panel_id: UiId) {
        let indicator_size = 40.0;
        let indicator_spacing = 4.0;
        let center = self.screen_size * 0.5;

        let indicator_bg = Vec4::new(0.15, 0.15, 0.18, 0.95);
        let indicator_btn = Vec4::new(0.25, 0.25, 0.28, 1.0);
        let indicator_hover = Vec4::new(0.3, 0.5, 0.8, 1.0);
        let preview_color = Vec4::new(0.3, 0.5, 0.8, 0.3);

        let total_size = indicator_size * 3.0 + indicator_spacing * 2.0;
        let bg_rect =
            Rect::from_center_size(center, Vec2::new(total_size + 16.0, total_size + 16.0));
        self.deferred_rects.push(UiRect {
            position: bg_rect.min,
            size: bg_rect.size(),
            color: indicator_bg,
            corner_radius: 8.0,
            border_width: 1.0,
            border_color: Vec4::new(0.4, 0.4, 0.45, 1.0),
            clip_rect: None,
            layer: UiLayer::DockIndicator,
            z_index: 0,
        });

        let buttons = [
            (
                Vec2::new(center.x, center.y - indicator_size - indicator_spacing),
                DockPosition::Top,
            ),
            (
                Vec2::new(center.x, center.y + indicator_size + indicator_spacing),
                DockPosition::Bottom,
            ),
            (
                Vec2::new(center.x - indicator_size - indicator_spacing, center.y),
                DockPosition::Left,
            ),
            (
                Vec2::new(center.x + indicator_size + indicator_spacing, center.y),
                DockPosition::Right,
            ),
            (center, DockPosition::None),
        ];

        let mut hovered_dock: Option<DockPosition> = None;

        for (btn_center, dock_pos) in buttons.iter() {
            let btn_rect =
                Rect::from_center_size(*btn_center, Vec2::new(indicator_size, indicator_size));
            let is_hovered = btn_rect.contains(self.mouse_pos);

            if is_hovered {
                hovered_dock = Some(*dock_pos);
            }

            let btn_color = if is_hovered {
                indicator_hover
            } else {
                indicator_btn
            };

            self.deferred_rects.push(UiRect {
                position: btn_rect.min,
                size: btn_rect.size(),
                color: btn_color,
                corner_radius: 4.0,
                border_width: 1.0,
                border_color: Vec4::new(0.5, 0.5, 0.55, 1.0),
                clip_rect: None,
                layer: UiLayer::DockIndicator,
                z_index: 1,
            });

            let symbol = match dock_pos {
                DockPosition::Top => "^",
                DockPosition::Bottom => "v",
                DockPosition::Left => "<",
                DockPosition::Right => ">",
                DockPosition::None => "+",
            };

            let symbol_size = indicator_size * 0.5;
            self.deferred_widgets.push(UiWidget {
                text: symbol.to_string(),
                position: Vec2::new(
                    btn_center.x - symbol_size * 0.25,
                    btn_center.y - symbol_size * 0.5,
                ),
                properties: TextProperties {
                    font_size: symbol_size,
                    color: self.style.text_color,
                    ..Default::default()
                },
                clip_rect: None,
                layer: UiLayer::DockIndicator,
                z_index: 2,
            });
        }

        if let Some(hover_dock) = hovered_dock
            && hover_dock != DockPosition::None
        {
            let reserved = self.reserved_areas;
            let preview_dock_size = 300.0;
            let preview_rect = match hover_dock {
                DockPosition::Left => {
                    let h = self.screen_size.y - reserved.top - reserved.bottom;
                    Rect::new(reserved.left, reserved.top, preview_dock_size, h)
                }
                DockPosition::Right => {
                    let h = self.screen_size.y - reserved.top - reserved.bottom;
                    Rect::new(
                        self.screen_size.x - reserved.right - preview_dock_size,
                        reserved.top,
                        preview_dock_size,
                        h,
                    )
                }
                DockPosition::Top => {
                    let w = self.screen_size.x - reserved.left - reserved.right;
                    Rect::new(reserved.left, reserved.top, w, preview_dock_size)
                }
                DockPosition::Bottom => {
                    let w = self.screen_size.x - reserved.left - reserved.right;
                    Rect::new(
                        reserved.left,
                        self.screen_size.y - reserved.bottom - preview_dock_size,
                        w,
                        preview_dock_size,
                    )
                }
                DockPosition::None => Rect::default(),
            };
            self.add_rect(UiRect {
                position: preview_rect.min,
                size: preview_rect.size(),
                color: preview_color,
                corner_radius: 0.0,
                border_width: 2.0,
                border_color: Vec4::new(0.4, 0.6, 1.0, 0.8),
                clip_rect: None,
                ..Default::default()
            });
        }
    }

    fn render_floating_panel_header(
        &mut self,
        rect: Rect,
        title: &str,
        panel_id: UiId,
        collapsed: bool,
        header_response: UiResponse,
    ) {
        let header_z_offset = 500;
        let padding = self.style.padding;
        let header_height = self.style.panel_header_height;
        let font_size = self.style.font_size;
        let corner_radius = self.style.corner_radius;
        let collapse_id = UiId::with_parent(panel_id, "_collapse");

        let header_color = if header_response.active {
            Vec4::new(0.3, 0.3, 0.35, 1.0)
        } else if header_response.hovered {
            Vec4::new(0.25, 0.25, 0.28, 1.0)
        } else {
            Vec4::new(0.2, 0.2, 0.22, 1.0)
        };

        self.frame_rects.push(UiRect {
            position: rect.min,
            size: Vec2::new(rect.width(), header_height),
            color: header_color,
            corner_radius,
            border_width: 0.0,
            border_color: Vec4::new(0.0, 0.0, 0.0, 0.0),
            clip_rect: None,
            layer: self.current_layer,
            z_index: self.current_panel_z_base + header_z_offset,
        });

        let button_size = header_height - 8.0;
        let button_y = rect.y() + 4.0;

        let collapse_button_x = rect.max.x - button_size - 4.0;
        let collapse_button_rect = Rect::new(collapse_button_x, button_y, button_size, button_size);
        let collapse_response = self.interact(collapse_id, collapse_button_rect);

        let collapse_bg_color = if collapse_response.active {
            Vec4::new(0.5, 0.5, 0.55, 1.0)
        } else if collapse_response.hovered {
            Vec4::new(0.4, 0.4, 0.45, 1.0)
        } else {
            Vec4::new(0.3, 0.3, 0.35, 1.0)
        };

        self.frame_rects.push(UiRect {
            position: Vec2::new(collapse_button_x, button_y),
            size: Vec2::new(button_size, button_size),
            color: collapse_bg_color,
            corner_radius: 2.0,
            border_width: 0.0,
            border_color: Vec4::new(0.0, 0.0, 0.0, 0.0),
            clip_rect: None,
            layer: self.current_layer,
            z_index: self.current_panel_z_base + header_z_offset + 1,
        });

        let collapse_symbol = if collapsed { "+" } else { "-" };
        let symbol_font_size = button_size * 0.8;
        let symbol_x = collapse_button_x + (button_size - symbol_font_size * 0.5) * 0.5;
        let symbol_y = button_y + (button_size - symbol_font_size) * 0.5;

        self.frame_widgets.push(UiWidget {
            text: collapse_symbol.to_string(),
            position: Vec2::new(symbol_x, symbol_y),
            properties: TextProperties {
                font_size: symbol_font_size,
                color: self.style.text_color,
                ..Default::default()
            },
            clip_rect: None,
            layer: self.current_layer,
            z_index: self.current_panel_z_base + header_z_offset + 2,
        });

        if collapse_response.clicked {
            let mut new_state = self.get_state(panel_id);
            new_state.collapsed = !collapsed;
            self.set_state(panel_id, new_state);
        }

        let title_x = rect.x() + padding;
        let title_y = rect.y() + (header_height - font_size) * 0.5;

        let props = TextProperties {
            font_size,
            color: self.style.text_color,
            ..Default::default()
        };

        self.frame_widgets.push(UiWidget {
            text: title.to_string(),
            position: Vec2::new(title_x, title_y),
            properties: props,
            clip_rect: None,
            layer: self.current_layer,
            z_index: self.current_panel_z_base + header_z_offset + 3,
        });
    }

    fn render_docked_panel_header(&mut self, rect: Rect, panel_id: UiId, pinned: bool) {
        let header_z_offset = 500;

        let pin_button_size = 20.0;
        let pin_button_margin = 4.0;
        let pin_button_x = rect.max.x - pin_button_size - pin_button_margin;
        let pin_button_y = rect.y() + pin_button_margin;
        let pin_button_rect =
            Rect::new(pin_button_x, pin_button_y, pin_button_size, pin_button_size);

        let pin_id = UiId::with_parent(panel_id, "pin_button");
        let pin_response = self.interact(pin_id, pin_button_rect);

        let pin_bg_color = if pin_response.active {
            Vec4::new(0.5, 0.5, 0.55, 1.0)
        } else if pin_response.hovered {
            Vec4::new(0.4, 0.4, 0.45, 1.0)
        } else {
            Vec4::new(0.25, 0.25, 0.28, 1.0)
        };

        self.frame_rects.push(UiRect {
            position: Vec2::new(pin_button_x, pin_button_y),
            size: Vec2::new(pin_button_size, pin_button_size),
            color: pin_bg_color,
            corner_radius: 2.0,
            border_width: 0.0,
            border_color: Vec4::new(0.0, 0.0, 0.0, 0.0),
            clip_rect: None,
            layer: self.current_layer,
            z_index: self.current_panel_z_base + header_z_offset,
        });

        let pin_symbol = if pinned { "P" } else { "U" };
        let symbol_font_size = pin_button_size * 0.7;
        let symbol_x = pin_button_x + (pin_button_size - symbol_font_size * 0.5) * 0.5;
        let symbol_y = pin_button_y + (pin_button_size - symbol_font_size) * 0.5;

        self.frame_widgets.push(UiWidget {
            text: pin_symbol.to_string(),
            position: Vec2::new(symbol_x, symbol_y),
            properties: TextProperties {
                font_size: symbol_font_size,
                color: if pinned {
                    Vec4::new(0.4, 0.8, 0.4, 1.0)
                } else {
                    self.style.text_color
                },
                ..Default::default()
            },
            clip_rect: None,
            layer: self.current_layer,
            z_index: self.current_panel_z_base + header_z_offset + 1,
        });

        if pin_response.clicked {
            let mut new_state = self.get_state(panel_id);
            new_state.pinned = !pinned;
            self.set_state(panel_id, new_state);
        }
    }

    fn render_resize_edge_highlight(&mut self, rect: Rect, edge: ResizeEdge) {
        let white = Vec4::new(1.0, 1.0, 1.0, 1.0);
        let line_thickness = 2.0;

        match edge {
            ResizeEdge::Left => {
                self.add_rect(UiRect {
                    position: Vec2::new(rect.min.x - line_thickness * 0.5, rect.min.y),
                    size: Vec2::new(line_thickness, rect.height()),
                    color: white,
                    corner_radius: 0.0,
                    border_width: 0.0,
                    border_color: Vec4::new(0.0, 0.0, 0.0, 0.0),
                    clip_rect: None,
                    ..Default::default()
                });
            }
            ResizeEdge::Right => {
                self.add_rect(UiRect {
                    position: Vec2::new(rect.max.x - line_thickness * 0.5, rect.min.y),
                    size: Vec2::new(line_thickness, rect.height()),
                    color: white,
                    corner_radius: 0.0,
                    border_width: 0.0,
                    border_color: Vec4::new(0.0, 0.0, 0.0, 0.0),
                    clip_rect: None,
                    ..Default::default()
                });
            }
            ResizeEdge::Top => {
                self.add_rect(UiRect {
                    position: Vec2::new(rect.min.x, rect.min.y - line_thickness * 0.5),
                    size: Vec2::new(rect.width(), line_thickness),
                    color: white,
                    corner_radius: 0.0,
                    border_width: 0.0,
                    border_color: Vec4::new(0.0, 0.0, 0.0, 0.0),
                    clip_rect: None,
                    ..Default::default()
                });
            }
            ResizeEdge::Bottom => {
                self.add_rect(UiRect {
                    position: Vec2::new(rect.min.x, rect.max.y - line_thickness * 0.5),
                    size: Vec2::new(rect.width(), line_thickness),
                    color: white,
                    corner_radius: 0.0,
                    border_width: 0.0,
                    border_color: Vec4::new(0.0, 0.0, 0.0, 0.0),
                    clip_rect: None,
                    ..Default::default()
                });
            }
            ResizeEdge::TopLeft => {
                self.add_rect(UiRect {
                    position: Vec2::new(rect.min.x - line_thickness * 0.5, rect.min.y),
                    size: Vec2::new(line_thickness, rect.height()),
                    color: white,
                    corner_radius: 0.0,
                    border_width: 0.0,
                    border_color: Vec4::new(0.0, 0.0, 0.0, 0.0),
                    clip_rect: None,
                    ..Default::default()
                });
                self.add_rect(UiRect {
                    position: Vec2::new(rect.min.x, rect.min.y - line_thickness * 0.5),
                    size: Vec2::new(rect.width(), line_thickness),
                    color: white,
                    corner_radius: 0.0,
                    border_width: 0.0,
                    border_color: Vec4::new(0.0, 0.0, 0.0, 0.0),
                    clip_rect: None,
                    ..Default::default()
                });
            }
            ResizeEdge::TopRight => {
                self.add_rect(UiRect {
                    position: Vec2::new(rect.max.x - line_thickness * 0.5, rect.min.y),
                    size: Vec2::new(line_thickness, rect.height()),
                    color: white,
                    corner_radius: 0.0,
                    border_width: 0.0,
                    border_color: Vec4::new(0.0, 0.0, 0.0, 0.0),
                    clip_rect: None,
                    ..Default::default()
                });
                self.add_rect(UiRect {
                    position: Vec2::new(rect.min.x, rect.min.y - line_thickness * 0.5),
                    size: Vec2::new(rect.width(), line_thickness),
                    color: white,
                    corner_radius: 0.0,
                    border_width: 0.0,
                    border_color: Vec4::new(0.0, 0.0, 0.0, 0.0),
                    clip_rect: None,
                    ..Default::default()
                });
            }
            ResizeEdge::BottomLeft => {
                self.add_rect(UiRect {
                    position: Vec2::new(rect.min.x - line_thickness * 0.5, rect.min.y),
                    size: Vec2::new(line_thickness, rect.height()),
                    color: white,
                    corner_radius: 0.0,
                    border_width: 0.0,
                    border_color: Vec4::new(0.0, 0.0, 0.0, 0.0),
                    clip_rect: None,
                    ..Default::default()
                });
                self.add_rect(UiRect {
                    position: Vec2::new(rect.min.x, rect.max.y - line_thickness * 0.5),
                    size: Vec2::new(rect.width(), line_thickness),
                    color: white,
                    corner_radius: 0.0,
                    border_width: 0.0,
                    border_color: Vec4::new(0.0, 0.0, 0.0, 0.0),
                    clip_rect: None,
                    ..Default::default()
                });
            }
            ResizeEdge::BottomRight => {
                self.add_rect(UiRect {
                    position: Vec2::new(rect.max.x - line_thickness * 0.5, rect.min.y),
                    size: Vec2::new(line_thickness, rect.height()),
                    color: white,
                    corner_radius: 0.0,
                    border_width: 0.0,
                    border_color: Vec4::new(0.0, 0.0, 0.0, 0.0),
                    clip_rect: None,
                    ..Default::default()
                });
                self.add_rect(UiRect {
                    position: Vec2::new(rect.min.x, rect.max.y - line_thickness * 0.5),
                    size: Vec2::new(rect.width(), line_thickness),
                    color: white,
                    corner_radius: 0.0,
                    border_width: 0.0,
                    border_color: Vec4::new(0.0, 0.0, 0.0, 0.0),
                    clip_rect: None,
                    ..Default::default()
                });
            }
            ResizeEdge::None => {}
        }
    }

    pub fn end_panel(&mut self) {
        self.layout_stack.pop();
        self.pop_clip();
        self.pop_id();
        self.current_panel_z_base = 0;
        self.next_z_index = 0;
    }

    pub fn begin_left_panel(&mut self, title: &str, default_width: f32) {
        let panel_id = self.make_id(title);
        let state = self.get_state(panel_id);
        if state.dock_position == DockPosition::None && state.panel_position.is_none() {
            let mut new_state = state;
            new_state.dock_position = DockPosition::Left;
            new_state.panel_size = Some(Vec2::new(default_width, self.screen_size.y));
            self.set_state(panel_id, new_state);
        }
        self.begin_panel(title, Rect::new(0.0, 0.0, default_width, 400.0));
    }

    pub fn begin_right_panel(&mut self, title: &str, default_width: f32) {
        let panel_id = self.make_id(title);
        let state = self.get_state(panel_id);
        if state.dock_position == DockPosition::None && state.panel_position.is_none() {
            let mut new_state = state;
            new_state.dock_position = DockPosition::Right;
            new_state.panel_size = Some(Vec2::new(default_width, self.screen_size.y));
            self.set_state(panel_id, new_state);
        }
        self.begin_panel(
            title,
            Rect::new(
                self.screen_size.x - default_width,
                0.0,
                default_width,
                400.0,
            ),
        );
    }

    pub fn begin_top_panel(&mut self, title: &str, default_height: f32) {
        let panel_id = self.make_id(title);
        let state = self.get_state(panel_id);
        if state.dock_position == DockPosition::None && state.panel_position.is_none() {
            let mut new_state = state;
            new_state.dock_position = DockPosition::Top;
            new_state.panel_size = Some(Vec2::new(self.screen_size.x, default_height));
            new_state.resizable = false;
            self.set_state(panel_id, new_state);
        }
        self.begin_panel(title, Rect::new(0.0, 0.0, 400.0, default_height));
    }

    pub fn begin_bottom_panel(&mut self, title: &str, default_height: f32) {
        let panel_id = self.make_id(title);
        let state = self.get_state(panel_id);
        if state.dock_position == DockPosition::None && state.panel_position.is_none() {
            let mut new_state = state;
            new_state.dock_position = DockPosition::Bottom;
            new_state.panel_size = Some(Vec2::new(self.screen_size.x, default_height));
            new_state.resizable = false;
            self.set_state(panel_id, new_state);
        }
        self.begin_panel(
            title,
            Rect::new(
                0.0,
                self.screen_size.y - default_height,
                400.0,
                default_height,
            ),
        );
    }

    pub fn begin_central_panel(&mut self, title: &str) {
        let reserved = self.reserved_areas;
        let panel_rect = Rect::new(
            reserved.left,
            reserved.top,
            self.screen_size.x - reserved.left - reserved.right,
            self.screen_size.y - reserved.top - reserved.bottom,
        );

        let panel_id = self.make_id(title);
        self.push_id(title);

        let is_new_panel = !self.widget_states.contains_key(&panel_id);
        let mut state = self.get_state(panel_id);
        if is_new_panel {
            state.focus_order = self.next_focus_order;
            self.next_focus_order += 1;
            self.set_state(panel_id, state);
        }

        self.current_panel_z_base = state.focus_order * 1000;
        self.next_z_index = 0;
        self.current_layer = UiLayer::DockedPanels;

        self.add_rect(UiRect {
            position: panel_rect.min,
            size: panel_rect.size(),
            color: self.style.background_color,
            corner_radius: 0.0,
            border_width: 0.0,
            border_color: Vec4::new(0.0, 0.0, 0.0, 0.0),
            clip_rect: None,
            ..Default::default()
        });

        let content_rect = panel_rect.shrink(self.style.padding);
        self.push_clip(content_rect);
        self.layout_stack
            .push(Layout::panel(content_rect, 0.0, self.style.spacing));
    }

    pub fn end_central_panel(&mut self) {
        self.layout_stack.pop();
        self.pop_clip();
        self.pop_id();
        self.current_panel_z_base = 0;
        self.next_z_index = 0;
    }
}
