//! Vue Component Loader - Load and parse Vue SFC with component imports
//! Vue 组件加载器 - 加载和解析包含组件导入的 Vue SFC

use std::collections::HashMap;
use std::path::{Path, PathBuf};
use tracing::{debug, info};

/// Vue SFC 解析结果（包含展开的子组件和动态特性）
pub struct ParsedVueSFC {
    /// 组件名称
    pub name: String,
    /// Template HTML（已展开子组件 + 添加 _iris 后缀）
    pub template_html: String,
    /// Script 内容（已注入动态特性）
    pub script_content: String,
    /// 原始 HTML（未加后缀）
    pub original_html: String,
    /// CSS 样式列表
    pub styles: Vec<String>,
    /// 子组件映射
    pub child_components: HashMap<String, ParsedVueSFC>,
}

/// Vue 组件加载器
pub struct VueComponentLoader {
    /// 组件注册表（用于下载开源组件）
    registry: Option<ComponentRegistry>,
/// 基础路径（用于解析相对导入）
    #[allow(dead_code)]
    base_path: PathBuf,
}

impl VueComponentLoader {
    /// 创建新的加载器
    pub fn new(base_path: PathBuf) -> Self {
        Self {
            registry: None,
            base_path,
        }
    }
    
    /// 设置组件注册表
    pub fn with_registry(mut self, registry: ComponentRegistry) -> Self {
        self.registry = Some(registry);
        self
    }
    
    /// 加载并解析 Vue SFC 文件（递归展开子组件）
    pub fn load_and_parse<P: AsRef<Path>>(&mut self, vue_path: P) -> Result<ParsedVueSFC, String> {
        let vue_path = vue_path.as_ref();
        info!(path = ?vue_path, "Loading Vue SFC...");
        
        // 1. 读取源文件
        let source = std::fs::read_to_string(vue_path)
            .map_err(|e| format!("Failed to read Vue file: {}", e))?;
        
        // 2. 解析 SFC
        self.parse_sfc(&source, vue_path, &mut HashMap::new())
    }
    
    /// 解析 SFC（递归展开子组件）
    fn parse_sfc(
        &mut self,
        source: &str,
        current_path: &Path,
        loaded_components: &mut HashMap<String, ParsedVueSFC>,
    ) -> Result<ParsedVueSFC, String> {
        // 1. 提取各个部分
        let template = Self::extract_section(source, "template")
            .unwrap_or_default();
        let script = Self::extract_section(source, "script")
            .unwrap_or_default();
        let styles = Self::extract_all_sections(source, "style");
        
        // 2. 提取组件名
        let name = Self::extract_component_name(&script)
            .unwrap_or_else(|| {
                current_path.file_stem()
                    .and_then(|s| s.to_str())
                    .unwrap_or("Anonymous")
                    .to_string()
            });
        
        // 3. 解析 import 语句
        let imports = Self::parse_imports(&script, current_path);
        debug!(component = name, imports_count = imports.len(), "Found imports");
        
        // 4. 递归加载子组件
        let mut child_components = HashMap::new();
        for (component_name, component_path) in imports {
            if loaded_components.contains_key(&component_name) {
                debug!(component = component_name, "Already loaded, skipping");
                continue;
            }
            
            info!(component = component_name, path = ?component_path, "Loading child component");
            
            // 尝试从注册表下载或读取本地文件
            let child_source = if let Some(ref mut registry) = self.registry {
                match registry.fetch_component_source(&component_name) {
                    Ok(source) => source,
                    Err(_) => {
                        // 回退到本地文件
                        std::fs::read_to_string(&component_path)
                            .map_err(|e| format!("Failed to read component {}: {}", component_path.display(), e))?
                    }
                }
            } else {
                std::fs::read_to_string(&component_path)
                    .map_err(|e| format!("Failed to read component {}: {}", component_path.display(), e))?
            };
            
            // 递归解析子组件
            let child_sfc = self.parse_sfc(&child_source, &component_path, loaded_components)?;
            child_components.insert(component_name.clone(), child_sfc);
        }
        
        // 5. 展开 template 中的子组件标签
        let expanded_template = Self::expand_components_in_template(&template, &child_components);
        
        // 6. 应用动态特性注入
        // 所有子组件都已成功加载并展开，没有未解析的组件
        // 未来如果有无法解析的组件，在这里添加异常标记
        let unresolved_components: Vec<(String, String)> = vec![];
        
        let (enhanced_html, enhanced_script) = crate::vue_dynamic::enhance_vue_sfc(
            &expanded_template,
            &script,
            &unresolved_components,
        );
        
        // 7. 缓存
        loaded_components.insert(name.clone(), ParsedVueSFC {
            name: name.clone(),
            template_html: enhanced_html.clone(),
            script_content: enhanced_script.clone(),
            original_html: expanded_template.clone(),
            styles: styles.clone(),
            child_components: HashMap::new(), // 子组件已展开，不需要再存储
        });
        
        Ok(ParsedVueSFC {
            name,
            template_html: enhanced_html,
            script_content: enhanced_script,
            original_html: expanded_template,
            styles,
            child_components,
        })
    }
    
    /// 展开 template 中的子组件标签
    fn expand_components_in_template(
        template: &str,
        child_components: &HashMap<String, ParsedVueSFC>,
    ) -> String {
        let mut result = template.to_string();
        
        // 对每个子组件，替换其标签
        for (component_name, child_sfc) in child_components {
            // 匹配 <ComponentName .../> 或 <ComponentName ...>...</ComponentName>
            let patterns = vec![
                // 自闭合标签: <ElButton type="primary" />
                format!(r"<{}\s+([^>]*)/\\s*>", component_name),
                format!(r"<{}\s*/\\s*>", component_name),
                // 非自闭合标签: <ElButton>...</ElButton>
                format!(r"<{}\s+[^>]*>(.*?)</{}\\s*>", component_name, component_name),
                format!(r"<{}>(.*?)</{}\\s*>", component_name, component_name),
            ];
            
            for pattern in patterns {
                if let Ok(re) = regex::Regex::new(&pattern) {
                    let replacement = format!("<div class=\"component-{}\">{}</div>", 
                        component_name.to_lowercase(), 
                        child_sfc.template_html);
                    result = re.replace_all(&result, &replacement).to_string();
                }
            }
        }
        
        result
    }
    
    /// 提取 section
    fn extract_section(source: &str, tag: &str) -> Result<String, String> {
        let start_tag = format!("<{}", tag);
        let end_tag = format!("</{}>", tag);
        
        let start = source.find(&start_tag)
            .ok_or_else(|| format!("Missing <{}> tag", tag))?;
        
        let content_start = source[start..].find('>')
            .map(|i| start + i + 1)
            .ok_or_else(|| format!("Invalid <{}> tag", tag))?;
        
        let end = source.find(&end_tag)
            .ok_or_else(|| format!("Missing </{}> tag", tag))?;
        
        Ok(source[content_start..end].to_string())
    }
    
    /// 提取所有 sections
    fn extract_all_sections(source: &str, tag: &str) -> Vec<String> {
        let mut results = Vec::new();
        let mut remaining = source;
        
        while let Ok(section) = Self::extract_section(remaining, tag) {
            results.push(section);
            if let Some(pos) = remaining.find(&format!("</{}>", tag)) {
                remaining = &remaining[pos + format!("</{}>", tag).len()..];
            } else {
                break;
            }
        }
        
        results
    }
    
    /// 解析 import 语句
    fn parse_imports(script: &str, base_path: &Path) -> Vec<(String, PathBuf)> {
        let mut imports = Vec::new();
        
        // 匹配: import ComponentName from './path/to/component.vue'
        let import_re = regex::Regex::new(
            r#"import\s+(\w+)\s+from\s+['"]([^'"]+\.vue)['"]"#
        ).expect("Invalid regex");
        
        for cap in import_re.captures_iter(script) {
            let component_name = cap[1].to_string();
            let relative_path = &cap[2];
            
            // 解析相对路径
            let component_path = base_path.parent()
                .unwrap_or(Path::new("."))
                .join(relative_path);
            
            imports.push((component_name, component_path));
        }
        
        imports
    }
    
    /// 提取组件名
    fn extract_component_name(script: &str) -> Option<String> {
        // 尝试从 defineComponent 或 export default 中提取
        let re = regex::Regex::new("name:\\s*['\"](\\w+)['\"]").ok()?;
        re.captures(script).map(|cap| cap[1].to_string())
    }
}

/// 组件注册表（从 iris-engine 迁移过来）
pub struct ComponentRegistry {
    registry: HashMap<String, String>, // component_name -> source_url
    cache_dir: PathBuf,
    client: reqwest::blocking::Client,
}

impl ComponentRegistry {
    /// 创建新的注册表
    pub fn new(cache_dir: PathBuf) -> Result<Self, String> {
        std::fs::create_dir_all(&cache_dir)
            .map_err(|e| format!("Failed to create cache dir: {}", e))?;
        
        Ok(Self {
            registry: HashMap::new(),
            cache_dir,
            client: reqwest::blocking::Client::builder()
                .timeout(std::time::Duration::from_secs(30))
                .build()
                .map_err(|e| format!("Failed to create HTTP client: {}", e))?,
        })
    }
    
    /// 加载注册表文件
    pub fn load_from_file<P: AsRef<Path>>(&mut self, path: P) -> Result<(), String> {
        let content = std::fs::read_to_string(path)
            .map_err(|e| format!("Failed to read registry: {}", e))?;
        
        let json: serde_json::Value = serde_json::from_str(&content)
            .map_err(|e| format!("Failed to parse JSON: {}", e))?;
        
        if let Some(libraries) = json.get("libraries") {
            for (_, lib_data) in libraries.as_object().unwrap_or(&serde_json::Map::new()) {
                if let Some(components) = lib_data.get("components") {
                    for (comp_name, comp_data) in components.as_object().unwrap_or(&serde_json::Map::new()) {
                        if let Some(url) = comp_data.get("source_url").and_then(|v| v.as_str()) {
                            self.registry.insert(comp_name.clone(), url.to_string());
                        }
                    }
                }
            }
        }
        
        Ok(())
    }
    
    /// 获取组件源码
    pub fn fetch_component_source(&mut self, component_name: &str) -> Result<String, String> {
        // 1. 检查缓存
        let cache_path = self.cache_dir.join(format!("{}.vue", component_name));
        if cache_path.exists() {
            return std::fs::read_to_string(&cache_path)
                .map_err(|e| format!("Failed to read cache: {}", e));
        }
        
        // 2. 从注册表获取 URL
        let url = self.registry.get(component_name)
            .ok_or_else(|| format!("Component '{}' not in registry", component_name))?
            .clone();
        
        // 3. 下载
        let response = self.client.get(&url)
            .send()
            .map_err(|e| format!("HTTP request failed: {}", e))?;
        
        if !response.status().is_success() {
            return Err(format!("HTTP {} for {}", response.status(), url));
        }
        
        let source = response.text()
            .map_err(|e| format!("Failed to read response: {}", e))?;
        
        // 4. 缓存
        std::fs::write(&cache_path, &source)
            .map_err(|e| format!("Failed to cache: {}", e))?;
        
        Ok(source)
    }
}
