//! Resource file integration (assets, content, i18n)

use std::fs;
use std::path::Path;

use anyhow::Result;

use crate::commands::feature::FeatureManifest;

pub struct ResourceIntegrator<'a> {
    project_root: &'a Path,
    features_path: &'a Path,
}

impl<'a> ResourceIntegrator<'a> {
    pub fn new(project_root: &'a Path, features_path: &'a Path) -> Self {
        Self {
            project_root,
            features_path,
        }
    }

    pub fn integrate(&self, manifest: &FeatureManifest) -> Result<()> {
        println!("  📁 Integrating resource files...");

        if let Some(resources) = &manifest.resources {
            // Integrate public resources
            if let Some(public_resources) = &resources.public {
                for resource in public_resources {
                    let src_path = self
                        .features_path
                        .join(&manifest.feature.name)
                        .join(&resource.from);
                    let dest_path = self.project_root.join(&resource.to);

                    self.copy_resource(&src_path, &dest_path)?;
                    println!("    ✓ Integrated public resource: {}", resource.to);
                }
            }

            // Integrate site resources
            if let Some(site) = &resources.site {
                // Content resources
                if let Some(content) = &site.content {
                    for resource in content {
                        let src_path = self
                            .features_path
                            .join(&manifest.feature.name)
                            .join(&resource.from);
                        let dest_path = self.project_root.join(&resource.to);

                        self.copy_resource(&src_path, &dest_path)?;
                        println!("    ✓ Integrated site content: {}", resource.to);
                    }
                }

                // i18n resources
                if let Some(i18n) = &site.i18n {
                    for resource in i18n {
                        let src_path = self
                            .features_path
                            .join(&manifest.feature.name)
                            .join(&resource.from);
                        let dest_path = self.project_root.join(&resource.to);

                        self.copy_resource(&src_path, &dest_path)?;
                        println!("    ✓ Integrated i18n resource: {}", resource.to);
                    }
                }
            }

            println!("    ✅ Resource files integrated successfully");
        } else {
            println!("    ↪ No resources in feature manifest");
        }

        Ok(())
    }

    fn copy_resource(&self, src_path: &Path, dest_path: &Path) -> Result<()> {
        // Create destination directory if it doesn't exist
        if let Some(parent) = dest_path.parent() {
            fs::create_dir_all(parent)?;
        }

        if src_path.exists() {
            if src_path.is_dir() {
                // Recursively copy directory
                copy_dir_all(src_path, dest_path)?;
            } else {
                // Copy single file
                fs::copy(src_path, dest_path)?;
            }
        } else {
            println!("    ⚠️  Source resource not found: {}", src_path.display());
        }

        Ok(())
    }
}

fn copy_dir_all(src: &Path, dst: &Path) -> Result<()> {
    fs::create_dir_all(dst)?;
    for entry in fs::read_dir(src)? {
        let entry = entry?;
        let ty = entry.file_type()?;
        if ty.is_dir() {
            copy_dir_all(&entry.path(), &dst.join(entry.file_name()))?;
        } else {
            fs::copy(entry.path(), dst.join(entry.file_name()))?;
        }
    }
    Ok(())
}
