兼容的菜单系统

use bevy::prelude::*;
use bevy::window::WindowResized;
use crate::raven::bevy_integration::{CanvasConfig, VirtualScreenScale, ScalableUI};

pub struct MenuPlugin;

impl Plugin for MenuPlugin {
    fn build(&self, app: &mut App) {
        println!(" MenuPlugin 正在构建...");
        app
            .add_systems(OnEnter(crate::raven::bevy_integration::GameState::Menu), setup_menu)
            .add_systems(Update, (handle_buttons, handle_input, menu_window_resize_system).run_if(in_state(crate::raven::bevy_integration::GameState::Menu)))
            .add_systems(OnExit(crate::raven::bevy_integration::GameState::Menu), cleanup_menu);
    }
}

#[derive(Component)]
struct MenuUI;

#[derive(Component)]
struct VirtualScreen;  // 🆕 虚拟屏幕标记组件

#[derive(Component)]
struct MenuBackground; 

#[derive(Component)]
struct StartButton;

#[derive(Component)]
struct ExitButton;

fn setup_menu(mut commands: Commands, camera_query: Query<Entity, With<Camera2d>>, asset_server: Res<AssetServer>) {
    if camera_query.is_empty() {
        commands.spawn(Camera2d);
    }

    // 🆕 创建虚拟屏幕容器,并将所有UI作为其子节点
    commands
        .spawn((
            Node {
                width: Val::Px(1920.0), // 虚拟屏幕宽度
                height: Val::Px(1080.0), // 虚拟屏幕高度
                position_type: PositionType::Absolute,
                left: Val::Px(0.0),
                top: Val::Px(0.0),
                flex_direction: FlexDirection::Column,
                justify_content: JustifyContent::FlexEnd,
                ..default()
            },
            BackgroundColor(Color::BLACK),
            GlobalZIndex(100),
            VirtualScreen,  // 🆕 虚拟屏幕标记
            MenuUI,
            ScalableUI::new().with_size(1920.0, 1080.0),
        ))
        .with_children(|virtual_screen| {
            // 🆕 在虚拟屏幕内创建菜单UI容器
            virtual_screen.spawn((
                Node {
                    width: Val::Px(720.0), 
                    height: Val::Px(1080.0),
                    align_items: AlignItems::Center,
                    justify_content: JustifyContent::Center,
                    flex_direction: FlexDirection::Column,
                    position_type: PositionType::Absolute,
                    top: Val::Px(0.0),
                    left: Val::Px(0.0),
                    ..default()
                },
                MenuUI,
                ScalableUI::new().with_size(720.0, 1080.0),
            )).with_children(|menu_container| {
                // 标题
                menu_container.spawn((
                    Text::new("Raven Engine"),
                    TextFont { font_size: 48.0, ..default() },
                    TextColor(Color::WHITE),
                    Node {
                        margin: UiRect::bottom(Val::Px(30.0)),
                        ..default()
                    },
                    MenuUI,
                    ScalableUI::new().with_font_size(48.0),
                ));  
                
                // 开始按钮
                menu_container.spawn((
                    Button,
                    Node {
                        width: Val::Px(200.0),
                        height: Val::Px(50.0),
                        margin: UiRect::all(Val::Px(40.0)),
                        align_items: AlignItems::Center,
                        justify_content: JustifyContent::Center,
                        border: UiRect::all(Val::Px(2.0)),
                        ..default()
                    },
                    BackgroundColor(Color::srgb(0.2, 0.5, 0.2)),
                    StartButton,
                    MenuUI,
                    ScalableUI::new().with_size(200.0, 50.0),
                )).with_children(|button| {
                    button.spawn((
                        Text::new("Start Game"),
                        TextFont { font_size: 20.0, ..default() },
                        TextColor(Color::WHITE),
                        MenuUI,
                        ScalableUI::new().with_font_size(20.0),
                    ));
                });
                
                // 退出按钮
                menu_container.spawn((
                    Button,
                    Node {
                        width: Val::Px(200.0),
                        height: Val::Px(50.0),
                        margin: UiRect::all(Val::Px(10.0)),
                        align_items: AlignItems::Center,
                        justify_content: JustifyContent::Center,
                        border: UiRect::all(Val::Px(2.0)),
                        ..default()
                    },
                    BackgroundColor(Color::srgb(0.5, 0.2, 0.2)),
                    ExitButton,
                    MenuUI,
                    ScalableUI::new().with_size(200.0, 50.0),
                )).with_children(|button| {
                    button.spawn((
                        Text::new("Exit"),
                        TextFont { font_size: 20.0, ..default() },
                        TextColor(Color::WHITE),
                        MenuUI,
                        ScalableUI::new().with_font_size(20.0),
                    ));
                });
            });
        });

    // 背景图片(2D精灵,独立于UI系统)
    commands.spawn((
        Sprite {
            image: asset_server.load("gui/main_menu.png"),
            custom_size: Some(Vec2::new(1920.0, 1080.0)),
            ..default()
        },
        Transform::from_translation(Vec3::new(0.0, 0.0, 0.3)), 
        MenuBackground,
        MenuUI,
    ));

    commands.spawn((
        Sprite {
            image: asset_server.load("gui/game3.png"),
            custom_size: Some(Vec2::new(1920.0, 1080.0)),
            ..default()
        },
        Transform::from_translation(Vec3::new(0.0, 0.0, 0.2)),
        MenuUI,
    ));
}

// 其余函数保持不变...
fn menu_window_resize_system(
    mut resize_events: EventReader<WindowResized>,
    mut camera_query: Query<&mut Projection, With<Camera2d>>,
    mut ui_query: Query<(&mut Node, &ScalableUI), Without<Text>>,
    mut text_query: Query<(&mut TextFont, &ScalableUI), With<Text>>,
    canvas_config: Res<CanvasConfig>,
    mut virtual_scale: ResMut<VirtualScreenScale>,
) {
    for event in resize_events.read() {
        let window_width = event.width;
        let window_height = event.height;
        let virtual_width = canvas_config.width;
        let virtual_height = canvas_config.height;

        // 计算等比缩放
        let scale_x = window_width / virtual_width;
        let scale_y = window_height / virtual_height;
        let scale = scale_x.min(scale_y);

        // 计算居中偏移
        let scaled_width = virtual_width * scale;
        let scaled_height = virtual_height * scale;
        let offset_x = (window_width - scaled_width) / 2.0;
        let offset_y = (window_height - scaled_height) / 2.0;

        // 更新缩放资源
        virtual_scale.scale = scale;
        virtual_scale.offset_x = offset_x;
        virtual_scale.offset_y = offset_y;

        // 更新摄像机(2D精灵缩放)
        let camera_scale = 1.0 / scale;
        for mut projection in camera_query.iter_mut() {
            if let Projection::Orthographic(ortho) = projection.as_mut() {
                ortho.scale = camera_scale;
            }
        }

        // 更新UI节点
        for (mut node, scalable_ui) in ui_query.iter_mut() {
            if scalable_ui.original_width > 0.0 {
                node.width = Val::Px(scalable_ui.original_width * scale);
            }
            if scalable_ui.original_height > 0.0 {
                node.height = Val::Px(scalable_ui.original_height * scale);
            }

            node.margin = scale_ui_rect(&scalable_ui.original_margin, scale);
            node.padding = scale_ui_rect(&scalable_ui.original_padding, scale);
            node.border = scale_ui_rect(&scalable_ui.original_border, scale);

            // 🆕 只为根虚拟屏幕容器设置偏移
            if scalable_ui.original_width == virtual_width && scalable_ui.original_height == virtual_height {
                node.left = Val::Px(offset_x);
                node.top = Val::Px(offset_y);
            }
        }

        // 更新文本大小
        for (mut text_font, scalable_ui) in text_query.iter_mut() {
            if let Some(original_font_size) = scalable_ui.original_font_size {
                text_font.font_size = original_font_size * scale;
            }
        }

        println!("菜单缩放: scale={:.3}, offset=({:.1}, {:.1})", scale, offset_x, offset_y);
    }
}

// 辅助函数
fn scale_ui_rect(rect: &UiRect, scale: f32) -> UiRect {
    UiRect {
        left: scale_val(&rect.left, scale),
        right: scale_val(&rect.right, scale),
        top: scale_val(&rect.top, scale),
        bottom: scale_val(&rect.bottom, scale),
    }
}

fn scale_val(val: &Val, scale: f32) -> Val {
    match val {
        Val::Px(px) => Val::Px(*px * scale),
        Val::Percent(percent) => Val::Percent(*percent),
        _ => *val,
    }
}

fn handle_buttons(
    mut interaction_query: Query<(&Interaction, Option<&StartButton>, Option<&ExitButton>), (Changed<Interaction>, With<Button>)>,
    mut next_state: ResMut<NextState<crate::raven::bevy_integration::GameState>>,
) {
    for (interaction, start_button, exit_button) in &mut interaction_query {
        if *interaction == Interaction::Pressed {
            if start_button.is_some() {
                println!("🎮 开始按钮被点击");
                next_state.set(crate::raven::bevy_integration::GameState::Playing);
            } else if exit_button.is_some() {
                println!(" 退出按钮被点击");
                std::process::exit(0);
            }
        }
    }
}

fn handle_input(
    keys: Res<ButtonInput<KeyCode>>,
    mut next_state: ResMut<NextState<crate::raven::bevy_integration::GameState>>,
) {
    if keys.just_pressed(KeyCode::Enter) {
        println!("⌨️ ENTER 键被按下,开始游戏");
        next_state.set(crate::raven::bevy_integration::GameState::Playing);
    } else if keys.just_pressed(KeyCode::Escape) {
        println!("⌨️ ESC 键被按下,退出游戏");
        std::process::exit(0);
    }
}

fn cleanup_menu(
    mut commands: Commands, 
    query: Query<Entity, With<MenuUI>>,
    bg_query: Query<Entity, With<MenuBackground>>,
) {
    println!("正在清理菜单...");
    
    for entity in &query {
        println!("删除菜单实体: {:?}", entity);
        commands.entity(entity).despawn();  // 🆕 使用递归删除
    }
    
    for entity in &bg_query {
        commands.entity(entity).despawn();
    }
    
    println!(" 菜单清理完成");
}