//! Android backend — NDK + JNI bridge.
//!
//! Architecture: correct and complete. JNI calls are stubs marked TODO.
//!
//! Each `PlatformNode` maps to an Android View:
//!   element("div")    → LinearLayout / FrameLayout
//!   element("span")   → TextView (inline)
//!   element("button") → Button
//!   element("input")  → EditText
//!   text("...")       → TextView
//!
//! Event binding:
//!   "click"  → setOnClickListener
//!   "input"  → addTextChangedListener
//!   "change" → setOnCheckedChangeListener

use crate::{EventHandler, PlatformBackend, PlatformError, PlatformNode, PlatformResult};

pub struct AndroidBackend;

impl AndroidBackend {
    pub fn new() -> Self {
        Self
    }

    fn android_view_class(tag: &str) -> &'static str {
        match tag {
            "button" => "android.widget.Button",
            "input" => "android.widget.EditText",
            "textarea" => "android.widget.EditText",
            "img" => "android.widget.ImageView",
            "ul" | "ol" => "android.widget.ListView",
            "li" => "android.view.View",
            "nav" => "androidx.appcompat.widget.Toolbar",
            "div" | "section" | "main" | "article" => "android.widget.FrameLayout",
            "span" | "p" | "h1" | "h2" | "h3" | "h4" | "h5" | "h6" => {
                "android.widget.TextView"
            }
            _ => "android.view.View",
        }
    }

    fn android_event_listener(event: &str) -> &'static str {
        match event {
            "click" => "setOnClickListener",
            "input" | "change" => "addTextChangedListener",
            "focus" => "setOnFocusChangeListener",
            _ => "setOnTouchListener",
        }
    }
}

impl Default for AndroidBackend {
    fn default() -> Self {
        Self::new()
    }
}

impl PlatformBackend for AndroidBackend {
    fn name(&self) -> &'static str {
        "android"
    }

    fn create_element(&self, tag: &str) -> PlatformResult<PlatformNode> {
        let mut node = PlatformNode::element(tag);
        // TODO: JNI call to create the Android view:
        //   env.call_static_method(activity_class, "createElement", "(Ljava/lang/String;)J", &[...])
        node.attributes.push(crate::Attribute::new(
            "data-android-class",
            Self::android_view_class(tag),
        ));
        Ok(node)
    }

    fn create_text(&self, content: &str) -> PlatformResult<PlatformNode> {
        let mut node = PlatformNode::text(content);
        // TODO: JNI: create TextView, set text = content
        node.attributes
            .push(crate::Attribute::new("data-android-class", "android.widget.TextView"));
        Ok(node)
    }

    fn set_attribute(
        &self,
        node: &mut PlatformNode,
        name: &str,
        value: &str,
    ) -> PlatformResult<()> {
        // TODO: map attribute to Java property setter via JNI
        //   "class" → setBackground / setTextAppearance
        //   "disabled" → setEnabled(false)
        //   "placeholder" → setHint(value)
        node.attributes.retain(|a| a.name != name);
        node.attributes.push(crate::Attribute::new(name, value));
        Ok(())
    }

    fn remove_attribute(&self, node: &mut PlatformNode, name: &str) -> PlatformResult<()> {
        node.attributes.retain(|a| a.name != name);
        Ok(())
    }

    fn append_child(
        &self,
        parent: &mut PlatformNode,
        child: PlatformNode,
    ) -> PlatformResult<()> {
        // TODO: JNI: ((ViewGroup) parent).addView(child)
        parent.children.push(child);
        Ok(())
    }

    fn remove_child(&self, parent: &mut PlatformNode, child_index: usize) -> PlatformResult<()> {
        if child_index >= parent.children.len() {
            return Err(PlatformError::Render(format!(
                "android: child index {} out of bounds",
                child_index
            )));
        }
        // TODO: JNI: ((ViewGroup) parent).removeViewAt(child_index)
        parent.children.remove(child_index);
        Ok(())
    }

    fn replace_child(
        &self,
        parent: &mut PlatformNode,
        index: usize,
        new_child: PlatformNode,
    ) -> PlatformResult<()> {
        if index >= parent.children.len() {
            return Err(PlatformError::Render(
                "android: replace_child out of bounds".into(),
            ));
        }
        // TODO: JNI: remove old view, add new view at index
        parent.children[index] = new_child;
        Ok(())
    }

    fn bind_event(
        &self,
        node: &mut PlatformNode,
        event: &str,
        _handler: EventHandler,
    ) -> PlatformResult<()> {
        let listener = Self::android_event_listener(event);
        // TODO: JNI: view.setOnClickListener(new View.OnClickListener() { ... })
        node.attributes.push(crate::Attribute::new(
            format!("data-android-event-{}", event),
            listener,
        ));
        Ok(())
    }

    fn render_to_string(&self, node: &PlatformNode) -> PlatformResult<String> {
        Ok(node.to_html())
    }

    fn mount(&self, _root: PlatformNode, _container_id: &str) -> PlatformResult<()> {
        // TODO: get Activity by container_id, set root as content view
        Ok(())
    }

    fn patch(&self, _old: &PlatformNode, _new: &PlatformNode) -> PlatformResult<()> {
        // TODO: diff and apply JNI mutations
        Ok(())
    }
}
