/// RFC 19 验收 — 事件冒泡
///
/// 布局：外层 Block 包内层 Block 包一个接收点击的 Label
/// 按 `c` 触发 capture 阶段停止，按 `b` 触发 bubble 阶段停止
/// 按 `+` 正常冒泡（三个阶段都执行），按 `q` 退出

use lv_tui::prelude::*;
use lv_tui::Component;
use lv_tui::widgets::{Block, Column, Label};

#[derive(Component)]
struct PhaseLabel {
    label: String,
    #[reactive(paint)]
    last_phase: String,
}

impl PhaseLabel {
fn new(label: impl Into<String>) -> Self {
        Self { label: label.into(), last_phase: "none".into() }
    }
}

impl Component for PhaseLabel {
fn render(&self, cx: &mut RenderCx) {
        cx.line(format!("{} [phase: {}]", self.label, self.last_phase()));
    }
fn event(&mut self, event: &Event, cx: &mut EventCx) {
        if event.is_key(Key::Char('c')) && cx.phase() == EventPhase::Capture {
            cx.stop_propagation();
            self.set_last_phase("CAPTURE(stop)".into(), cx);
            return;
        }
        if event.is_key(Key::Char('b')) && cx.phase() == EventPhase::Bubble {
            cx.stop_propagation();
            self.set_last_phase("BUBBLE(stop)".into(), cx);
            return;
        }
        let phase_name = match cx.phase() {
            EventPhase::Capture => "capture",
            EventPhase::Target => "target",
            EventPhase::Bubble => "bubble",
        };
        self.set_last_phase(phase_name.into(), cx);
    }
}

struct Root { body: Column }

impl Root {
    fn new(body: Column) -> Self { Self { body } }
}

impl Component for Root {
    fn render(&self, cx: &mut RenderCx) { self.body.render(cx); }
    fn layout(&mut self, r: Rect, cx: &mut LayoutCx) { self.body.layout(r, cx); }
    fn focusable(&self) -> bool { false }
    fn event(&mut self, e: &Event, cx: &mut EventCx) {
        if e.is_key(Key::Char('q')) { cx.quit(); }
        if let Event::Key(_) = e { self.body.event(e, cx); }
    }
    fn for_each_child(&self, f: &mut dyn FnMut(&Node)) { self.body.for_each_child(f); }
    fn for_each_child_mut(&mut self, f: &mut dyn FnMut(&mut Node)) { self.body.for_each_child_mut(f); }
}

fn main() -> lv_tui::Result<()> {
    let body = Column::new()
        .padding(1).gap(1)
        .child(Label::new("=== Event Bubbling Demo ==="))
        .child(Label::new("c: stop at capture, b: stop at bubble"))
        .child(
            Block::new(
                Column::new().gap(0)
                    .child(PhaseLabel::new("Outer"))
                    .child(Block::new(PhaseLabel::new("Inner")).padding(1).border(Border::Plain))
            ).border(Border::Rounded).padding(1)
        )
        .child(Label::new("press a key, q to quit"));

    lv_tui::app::App::new(Root::new(body)).run()
}
