//! Non-interactive Penpot v2.3.1 renderer-control preview.

use egui;
use egui_phosphor_icons::icons;

use crate::design_system::typography::TypeRole;
use crate::design_system::{self, ADVANCED_COLLAPSED_HEIGHT, ADVANCED_EXPANDED_HEIGHT};

const PLANNED_TOOLTIP: &str = "Planned — renderer support pending";

pub(super) fn unsupported_advanced_preview(ui: &mut egui::Ui) {
    let open_id = ui.make_persistent_id("material_unsupported_advanced_open");
    let reveal_id = open_id.with("reveal_complete_body");
    let mut open = ui
        .ctx()
        .data_mut(|data| data.get_persisted::<bool>(open_id))
        .unwrap_or(false);
    let width = ui.available_width().max(1.0);
    let mode = super::layout::ResponsiveMaterialLayout::for_width(width);
    let height = if open {
        if mode == super::layout::ResponsiveMaterialLayout::Transient {
            254.0
        } else {
            ADVANCED_EXPANDED_HEIGHT
        }
    } else {
        ADVANCED_COLLAPSED_HEIGHT
    };
    let palette = design_system::palette(ui);
    let (rect, _) = ui.allocate_exact_size(egui::vec2(width, height), egui::Sense::hover());
    ui.painter().rect(
        rect,
        5.0,
        palette.panel,
        egui::Stroke::new(1.0_f32, palette.border),
        egui::StrokeKind::Inside,
    );
    let header = egui::Rect::from_min_size(rect.min, egui::vec2(rect.width(), 30.0));
    ui.painter().rect_filled(header, 4.0, palette.panel);
    let header_response = ui.interact(header, open_id.with("header"), egui::Sense::click());
    if header_response.clicked() {
        open = !open;
        ui.ctx().data_mut(|data| data.insert_temp(reveal_id, open));
    }
    header_response.on_hover_text(if open {
        "Collapse Advanced preview"
    } else {
        "Expand Advanced preview"
    });
    ui.painter().text(
        header.left_center() + egui::vec2(12.0, 0.0),
        egui::Align2::LEFT_CENTER,
        if open {
            icons::CARET_DOWN.as_str()
        } else {
            icons::CARET_RIGHT.as_str()
        },
        egui::FontId::new(10.0, egui::FontFamily::Name("phosphor-bold".into())),
        palette.text_secondary,
    );
    ui.painter().text(
        header.left_center() + egui::vec2(26.0, 0.0),
        egui::Align2::LEFT_CENTER,
        "Advanced",
        TypeRole::Section.font(),
        palette.text_secondary,
    );
    if !open && rect.width() >= 300.0 {
        ui.painter().hline(
            (header.left() + 82.0)..=(header.right() - 158.0),
            header.center().y,
            egui::Stroke::new(1.0_f32, palette.border),
        );
        ui.painter().text(
            header.right_center() - egui::vec2(12.0, 0.0),
            egui::Align2::RIGHT_CENTER,
            PLANNED_TOOLTIP,
            TypeRole::Small.font(),
            palette.text_muted,
        );
    }
    if open {
        match mode {
            super::layout::ResponsiveMaterialLayout::Reference => reference_controls(ui, rect),
            super::layout::ResponsiveMaterialLayout::Compact => {
                compact_reference_controls(ui, rect)
            }
            super::layout::ResponsiveMaterialLayout::Transient => compact_controls(ui, rect),
        }
    }
    let reveal_complete_body = ui
        .ctx()
        .data_mut(|data| data.get_temp::<bool>(reveal_id))
        .unwrap_or(false);
    if open && reveal_complete_body && rect.height() > ADVANCED_COLLAPSED_HEIGHT {
        ui.scroll_to_rect(rect, Some(egui::Align::BOTTOM));
        ui.ctx().data_mut(|data| data.remove::<bool>(reveal_id));
    }
    ui.ctx()
        .data_mut(|data| data.insert_persisted(open_id, open));
}

fn reference_controls(ui: &mut egui::Ui, rect: egui::Rect) {
    disabled_field(ui, rect, 28.0, 42.0, "Culling", "Back");
    disabled_field(ui, rect, 28.0, 76.0, "Render Queue", "From Shader");
    disabled_toggle(ui, rect, 328.0, 42.0, "Depth Write", true);
    disabled_toggle(ui, rect, 328.0, 76.0, "Receive Shadows", true);
    planned_note(ui, rect, 28.0, 124.0);
}

fn compact_reference_controls(ui: &mut egui::Ui, rect: egui::Rect) {
    disabled_field_at(ui, rect, 20.0, 90.0, 90.0, 42.0, "Culling", "Back");
    disabled_field_at(
        ui,
        rect,
        20.0,
        90.0,
        90.0,
        76.0,
        "Render Queue",
        "From Shader",
    );
    disabled_toggle_at(
        ui,
        rect,
        196.0,
        rect.width() - 38.0,
        42.0,
        "Depth Write",
        true,
    );
    disabled_toggle_at(
        ui,
        rect,
        196.0,
        rect.width() - 38.0,
        76.0,
        "Receive Shadows",
        true,
    );
    planned_note(ui, rect, 20.0, 124.0);
}

fn compact_controls(ui: &mut egui::Ui, rect: egui::Rect) {
    disabled_field(ui, rect, 20.0, 42.0, "Culling", "Back");
    disabled_field(ui, rect, 20.0, 78.0, "Render Queue", "From Shader");
    disabled_toggle(ui, rect, 20.0, 124.0, "Depth Write", true);
    disabled_toggle(ui, rect, 20.0, 160.0, "Receive Shadows", true);
    planned_note(ui, rect, 20.0, 210.0);
}

fn disabled_field(ui: &mut egui::Ui, rect: egui::Rect, x: f32, y: f32, label: &str, value: &str) {
    disabled_field_at(ui, rect, x, x + 106.0, 150.0, y, label, value);
}

#[expect(
    clippy::too_many_arguments,
    reason = "explicit Penpot preview geometry"
)]
fn disabled_field_at(
    ui: &mut egui::Ui,
    rect: egui::Rect,
    label_x: f32,
    field_x: f32,
    field_width: f32,
    y: f32,
    label: &str,
    value: &str,
) {
    let palette = design_system::palette(ui);
    ui.painter().text(
        rect.min + egui::vec2(label_x, y),
        egui::Align2::LEFT_CENTER,
        label,
        TypeRole::Body.font(),
        palette.text_muted,
    );
    let field = egui::Rect::from_min_size(
        egui::pos2(rect.left() + field_x, rect.top() + y - 7.0),
        egui::vec2(field_width.min(rect.width() - field_x - 8.0).max(1.0), 24.0),
    );
    paint_disabled_field(ui, field, value);
}

fn disabled_toggle(
    ui: &mut egui::Ui,
    rect: egui::Rect,
    x: f32,
    y: f32,
    label: &str,
    enabled: bool,
) {
    disabled_toggle_at(ui, rect, x, x + 106.0, y, label, enabled);
}

fn disabled_toggle_at(
    ui: &mut egui::Ui,
    rect: egui::Rect,
    label_x: f32,
    toggle_x: f32,
    y: f32,
    label: &str,
    enabled: bool,
) {
    let palette = design_system::palette(ui);
    ui.painter().text(
        rect.min + egui::vec2(label_x, y),
        egui::Align2::LEFT_CENTER,
        label,
        TypeRole::Body.font(),
        palette.text_muted,
    );
    let toggle = egui::Rect::from_min_size(
        egui::pos2(rect.left() + toggle_x, rect.top() + y - 8.0),
        egui::vec2(30.0, 16.0),
    );
    ui.painter().rect(
        toggle,
        8.0,
        palette.control,
        egui::Stroke::new(1.0_f32, palette.border),
        egui::StrokeKind::Inside,
    );
    let thumb_x = if enabled {
        toggle.right() - 8.0
    } else {
        toggle.left() + 8.0
    };
    ui.painter().circle_filled(
        egui::pos2(thumb_x, toggle.center().y),
        5.0,
        palette.text_muted,
    );
    ui.interact(
        toggle,
        ui.make_persistent_id(("advanced_toggle", label)),
        egui::Sense::hover(),
    )
    .on_hover_text(PLANNED_TOOLTIP);
}

fn paint_disabled_field(ui: &mut egui::Ui, rect: egui::Rect, value: &str) {
    let palette = design_system::palette(ui);
    ui.painter().rect(
        rect,
        4.0,
        palette.control,
        egui::Stroke::new(1.0_f32, palette.border),
        egui::StrokeKind::Inside,
    );
    ui.painter().text(
        rect.left_center() + egui::vec2(10.0, 0.0),
        egui::Align2::LEFT_CENTER,
        value,
        TypeRole::Body.font(),
        palette.text_muted,
    );
    ui.interact(
        rect,
        ui.make_persistent_id(("advanced_field", value)),
        egui::Sense::hover(),
    )
    .on_hover_text(PLANNED_TOOLTIP);
}

fn planned_note(ui: &egui::Ui, rect: egui::Rect, x: f32, y: f32) {
    let palette = design_system::palette(ui);
    ui.painter().text(
        rect.min + egui::vec2(x, y),
        egui::Align2::LEFT_CENTER,
        PLANNED_TOOLTIP,
        TypeRole::Small.font(),
        palette.text_muted,
    );
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn penpot_advanced_preview_matches_v231_heights() {
        assert_eq!(ADVANCED_COLLAPSED_HEIGHT, 30.0);
        assert_eq!(ADVANCED_EXPANDED_HEIGHT, 178.0);
    }
}
