//! JavaScript/TypeScript import statement processing.
//! Parses `import … from '…'`, `import * as ns`, `import { a as b }`,
//! and emits Imports edges plus alias map entries for call resolution.

use tree_sitter::Node;

use crate::util::text;
use super::Ctx;

/// Parse `import { a, b as c } from 'lib'`, `import x from 'lib'`,
/// `import * as ns from 'lib'`, `import 'lib'` (side-effect — emits
/// only the Imports edge, no aliases).
pub(crate) fn add_import_aliases(ctx: &mut Ctx<'_>, n: Node<'_>, src: &str) {
    use ckg_core::{Edge, EdgeKind};

    let Some(source_node) = n.child_by_field_name("source") else {
        return;
    };
    let module_path = text(source_node, src).trim_matches(['"', '\'']).to_string();

    // Imports edge from this file's module to the source module.
    ctx.out.edges.push(Edge {
        kind: EdgeKind::Imports,
        src: ctx.module.clone(),
        dst: module_path.clone(),
        confidence: 1.0,
    });

    // Walk import_clause / named_imports / namespace_import for aliases.
    let mut cursor = n.walk();
    for child in n.children(&mut cursor) {
        if child.kind() == "import_clause" {
            walk_import_clause(ctx, child, &module_path, src);
        }
    }
}

pub(crate) fn walk_import_clause(ctx: &mut Ctx<'_>, clause: Node<'_>, module_path: &str, src: &str) {
    let mut cursor = clause.walk();
    for child in clause.children(&mut cursor) {
        match child.kind() {
            "identifier" => {
                // `import Foo from 'lib'` — default import.
                let alias = text(child, src).to_string();
                ctx.aliases.insert(alias, module_path.to_string());
            }
            "namespace_import" => {
                // `import * as ns from 'lib'`
                let mut c = child.walk();
                if let Some(id) = child.children(&mut c).find(|x| x.kind() == "identifier") {
                    ctx.aliases
                        .insert(text(id, src).to_string(), module_path.to_string());
                }
            }
            "named_imports" => {
                let mut c = child.walk();
                for spec in child.children(&mut c) {
                    if spec.kind() != "import_specifier" {
                        continue;
                    }
                    let imported = spec
                        .child_by_field_name("name")
                        .map(|n| text(n, src).to_string());
                    let alias_node = spec.child_by_field_name("alias");
                    let alias = alias_node
                        .map(|n| text(n, src).to_string())
                        .or_else(|| imported.clone());
                    if let (Some(a), Some(i)) = (alias, imported) {
                        ctx.aliases.insert(a, format!("{module_path}.{i}"));
                    }
                }
            }
            _ => {}
        }
    }
}
