//! Blacksite editor visual system for egui and egui_dock chrome.

use bevy_egui::egui::{self, Color32, CornerRadius, FontId, Stroke, Visuals};
use egui_dock::{Style as DockStyle, TabInteractionStyle, TabStyle};

pub const CANVAS_BG: Color32 = Color32::from_rgb(7, 8, 10);
pub const PANEL_BG: Color32 = Color32::from_rgb(13, 15, 18);
pub const PANEL_BG_DARK: Color32 = Color32::from_rgb(9, 11, 13);
pub const WIDGET_BG: Color32 = Color32::from_rgb(21, 24, 28);
pub const ELEVATED_BG: Color32 = Color32::from_rgb(31, 35, 40);
pub const ACCENT: Color32 = Color32::from_rgb(229, 164, 51);
pub const ACCENT_HOVER: Color32 = Color32::from_rgb(249, 193, 79);
pub const SELECTION: Color32 = Color32::from_rgb(65, 198, 207);
pub const SELECTION_SECONDARY: Color32 = Color32::from_rgb(84, 139, 155);
pub const SELECTION_BG: Color32 = Color32::from_rgb(22, 72, 78);
pub const SELECTION_BG_MUTED: Color32 = Color32::from_rgb(23, 48, 54);
pub const TEXT: Color32 = Color32::from_rgb(220, 225, 229);
pub const TEXT_SELECTED: Color32 = Color32::from_rgb(250, 251, 252);
pub const TEXT_DIM: Color32 = Color32::from_rgb(155, 163, 171);
pub const TEXT_MUTED: Color32 = Color32::from_rgb(96, 105, 114);
pub const BORDER: Color32 = Color32::from_rgb(38, 43, 49);
pub const BORDER_STRONG: Color32 = Color32::from_rgb(64, 71, 79);
pub const SUCCESS: Color32 = Color32::from_rgb(84, 190, 127);
pub const WARNING: Color32 = Color32::from_rgb(235, 180, 72);
pub const ERROR: Color32 = Color32::from_rgb(226, 94, 94);
pub const AXIS_X: Color32 = Color32::from_rgb(232, 83, 105);
pub const AXIS_Y: Color32 = Color32::from_rgb(91, 201, 130);
pub const AXIS_Z: Color32 = Color32::from_rgb(77, 147, 235);
pub const VIEWPORT_OVERLAY: Color32 = Color32::from_rgba_premultiplied(7, 9, 11, 240);

pub fn apply_editor_theme(ctx: &egui::Context) {
    let mut visuals = Visuals::dark();
    visuals.panel_fill = PANEL_BG;
    visuals.window_fill = WIDGET_BG;
    visuals.extreme_bg_color = CANVAS_BG;
    visuals.faint_bg_color = Color32::from_rgb(17, 19, 22);
    visuals.code_bg_color = PANEL_BG_DARK;
    visuals.text_edit_bg_color = Some(CANVAS_BG);
    visuals.weak_text_color = Some(TEXT_MUTED);
    visuals.widgets.noninteractive.bg_fill = PANEL_BG;
    visuals.widgets.noninteractive.bg_stroke = Stroke::new(1.0, BORDER);
    visuals.widgets.noninteractive.fg_stroke = Stroke::new(1.0, TEXT_DIM);
    visuals.widgets.inactive.bg_fill = WIDGET_BG;
    visuals.widgets.inactive.weak_bg_fill = Color32::from_rgb(24, 27, 31);
    visuals.widgets.inactive.bg_stroke = Stroke::new(1.0, BORDER);
    visuals.widgets.inactive.fg_stroke = Stroke::new(1.0, TEXT);
    visuals.widgets.hovered.bg_fill = ELEVATED_BG;
    visuals.widgets.hovered.weak_bg_fill = ELEVATED_BG;
    visuals.widgets.hovered.bg_stroke = Stroke::new(1.0, BORDER_STRONG);
    visuals.widgets.hovered.fg_stroke = Stroke::new(1.0, TEXT_SELECTED);
    visuals.widgets.active.bg_fill = Color32::from_rgb(38, 42, 47);
    visuals.widgets.active.weak_bg_fill = Color32::from_rgb(38, 42, 47);
    visuals.widgets.active.bg_stroke = Stroke::new(1.0, ACCENT);
    visuals.widgets.active.fg_stroke = Stroke::new(1.0, TEXT_SELECTED);
    visuals.widgets.open.bg_fill = ELEVATED_BG;
    visuals.widgets.open.weak_bg_fill = ELEVATED_BG;
    visuals.widgets.open.bg_stroke = Stroke::new(1.0, BORDER_STRONG);
    visuals.widgets.open.fg_stroke = Stroke::new(1.0, TEXT_SELECTED);
    visuals.selection.bg_fill = SELECTION_BG;
    visuals.selection.stroke = Stroke::new(1.0, SELECTION);
    visuals.hyperlink_color = SELECTION;
    visuals.warn_fg_color = WARNING;
    visuals.error_fg_color = ERROR;
    visuals.window_stroke = Stroke::new(1.0, BORDER);
    visuals.window_corner_radius = CornerRadius::same(4);
    visuals.menu_corner_radius = CornerRadius::same(3);
    visuals.window_shadow = egui::epaint::Shadow {
        offset: [0, 8],
        blur: 28,
        spread: 2,
        color: Color32::from_black_alpha(190),
    };
    visuals.popup_shadow = egui::epaint::Shadow {
        offset: [0, 5],
        blur: 18,
        spread: 1,
        color: Color32::from_black_alpha(205),
    };
    visuals.button_frame = true;
    visuals.collapsing_header_frame = false;
    visuals.indent_has_left_vline = true;
    visuals.striped = true;
    visuals.slider_trailing_fill = true;
    visuals.interact_cursor = Some(egui::CursorIcon::PointingHand);

    let mut style = (*ctx.global_style()).clone();
    style.visuals = visuals;
    style.spacing.item_spacing = egui::vec2(8.0, 7.0);
    style.spacing.button_padding = egui::vec2(10.0, 5.0);
    style.spacing.interact_size = egui::vec2(40.0, 28.0);
    style.spacing.window_margin = egui::Margin::same(10);
    style.spacing.menu_margin = egui::Margin::same(8);
    style.spacing.indent = 17.0;
    style.interaction.tooltip_delay = 0.32;
    style.interaction.tooltip_grace_time = 0.18;
    style.animation_time = 0.12;
    style.compact_menu_style = true;
    style.text_styles.insert(
        egui::TextStyle::Body,
        FontId::new(14.0, egui::FontFamily::Proportional),
    );
    style.text_styles.insert(
        egui::TextStyle::Button,
        FontId::new(13.0, egui::FontFamily::Proportional),
    );
    style.text_styles.insert(
        egui::TextStyle::Heading,
        FontId::new(16.0, egui::FontFamily::Proportional),
    );
    style.text_styles.insert(
        egui::TextStyle::Small,
        FontId::new(12.0, egui::FontFamily::Proportional),
    );
    ctx.set_global_style(style);
}

pub fn editor_dock_style(ctx: &egui::Context) -> DockStyle {
    let mut style = DockStyle::from_egui(ctx.global_style().as_ref());
    style.dock_area_padding = Some(egui::Margin::same(1));
    style.main_surface_border_stroke = Stroke::new(1.0, BORDER);
    style.main_surface_border_rounding = CornerRadius::ZERO;
    style.separator.width = 2.0;
    style.separator.extra_interact_width = 5.0;
    style.separator.color_idle = BORDER;
    style.separator.color_hovered = BORDER_STRONG;
    style.separator.color_dragged = ACCENT_HOVER;

    style.tab_bar.bg_fill = PANEL_BG_DARK;
    style.tab_bar.height = 30.0;
    style.tab_bar.inner_margin = egui::Margin::symmetric(2, 1);
    style.tab_bar.hline_color = ACCENT;
    style.tab_bar.corner_radius = CornerRadius::ZERO;

    let active = TabInteractionStyle {
        outline_color: ACCENT,
        bg_fill: PANEL_BG,
        text_color: TEXT_SELECTED,
        corner_radius: CornerRadius::same(1),
    };
    let inactive = TabInteractionStyle {
        outline_color: Color32::TRANSPARENT,
        bg_fill: Color32::TRANSPARENT,
        text_color: TEXT_DIM,
        corner_radius: CornerRadius::same(1),
    };
    let hovered = TabInteractionStyle {
        outline_color: BORDER_STRONG,
        bg_fill: ELEVATED_BG,
        text_color: TEXT,
        corner_radius: CornerRadius::same(1),
    };

    style.tab = TabStyle {
        active: active.clone(),
        inactive: inactive.clone(),
        focused: active.clone(),
        hovered,
        inactive_with_kb_focus: inactive.clone(),
        active_with_kb_focus: active.clone(),
        focused_with_kb_focus: active,
        hline_below_active_tab_name: true,
        spacing: 2.0,
        ..style.tab
    };
    style.tab.tab_body.inner_margin = egui::Margin::same(4);
    style.tab.tab_body.bg_fill = PANEL_BG;
    style.tab.tab_body.stroke = Stroke::new(1.0, BORDER);
    style.overlay.selection_color = SELECTION_BG;
    style.overlay.button_color = SELECTION;
    style.overlay.button_border_stroke = Stroke::new(1.0, SELECTION);

    style
}

pub fn panel_heading(text: &str) -> egui::RichText {
    egui::RichText::new(text).strong().color(TEXT)
}

pub fn status_bar_frame() -> egui::Frame {
    egui::Frame::new()
        .fill(PANEL_BG_DARK)
        .inner_margin(egui::Margin::symmetric(10, 3))
        .stroke(Stroke::new(1.0, BORDER))
}

pub fn brand_mark_frame() -> egui::Frame {
    egui::Frame::new()
        .fill(CANVAS_BG)
        .corner_radius(CornerRadius::same(2))
        .inner_margin(egui::Margin::symmetric(8, 4))
        .stroke(Stroke::new(1.0, BORDER_STRONG))
}

pub fn viewport_toolbar_frame() -> egui::Frame {
    egui::Frame::new()
        .fill(VIEWPORT_OVERLAY)
        .corner_radius(CornerRadius::same(3))
        .inner_margin(egui::Margin::same(5))
        .stroke(Stroke::new(1.0, BORDER_STRONG))
        .shadow(egui::epaint::Shadow {
            offset: [0, 3],
            blur: 12,
            spread: 0,
            color: Color32::from_black_alpha(110),
        })
}

pub fn overlay_chip_frame() -> egui::Frame {
    egui::Frame::new()
        .fill(VIEWPORT_OVERLAY)
        .corner_radius(CornerRadius::same(3))
        .inner_margin(egui::Margin::symmetric(8, 5))
        .stroke(Stroke::new(1.0, BORDER_STRONG))
}

pub fn toolbar_group_frame() -> egui::Frame {
    egui::Frame::new()
        .fill(PANEL_BG_DARK)
        .corner_radius(CornerRadius::same(3))
        .inner_margin(egui::Margin::symmetric(5, 3))
        .stroke(Stroke::new(1.0, BORDER))
}
