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

use crate::engine::EngineResult;

#[derive(Debug, Clone, Copy)]
pub(crate) struct BundledSiteAsset {
    pub relative_path: &'static str,
    pub bytes: &'static [u8],
}

const BUNDLED_SITE_ASSETS: &[BundledSiteAsset] = &[
    BundledSiteAsset {
        relative_path: "assets/bds.css",
        bytes: include_bytes!(
            "../../../../fixtures/golden-generated-sites/rfc1437-sample/assets/bds.css"
        ),
    },
    BundledSiteAsset {
        relative_path: "assets/calendar-runtime.js",
        bytes: include_bytes!(
            "../../../../fixtures/golden-generated-sites/rfc1437-sample/assets/calendar-runtime.js"
        ),
    },
    BundledSiteAsset {
        relative_path: "assets/code-enhancements.js",
        bytes: include_bytes!(
            "../../../../fixtures/golden-generated-sites/rfc1437-sample/assets/code-enhancements.js"
        ),
    },
    BundledSiteAsset {
        relative_path: "assets/d3.layout.cloud.js",
        bytes: include_bytes!(
            "../../../../fixtures/golden-generated-sites/rfc1437-sample/assets/d3.layout.cloud.js"
        ),
    },
    BundledSiteAsset {
        relative_path: "assets/highlight.min.css",
        bytes: include_bytes!(
            "../../../../fixtures/golden-generated-sites/rfc1437-sample/assets/highlight.min.css"
        ),
    },
    BundledSiteAsset {
        relative_path: "assets/highlight.min.js",
        bytes: include_bytes!(
            "../../../../fixtures/golden-generated-sites/rfc1437-sample/assets/highlight.min.js"
        ),
    },
    BundledSiteAsset {
        relative_path: "assets/lightbox.min.css",
        bytes: include_bytes!(
            "../../../../fixtures/golden-generated-sites/rfc1437-sample/assets/lightbox.min.css"
        ),
    },
    BundledSiteAsset {
        relative_path: "assets/lightbox.min.js",
        bytes: include_bytes!(
            "../../../../fixtures/golden-generated-sites/rfc1437-sample/assets/lightbox.min.js"
        ),
    },
    BundledSiteAsset {
        relative_path: "assets/pico.amber.min.css",
        bytes: include_bytes!(
            "../../../../fixtures/golden-generated-sites/rfc1437-sample/assets/pico.amber.min.css"
        ),
    },
    BundledSiteAsset {
        relative_path: "assets/pico.blue.min.css",
        bytes: include_bytes!(
            "../../../../fixtures/golden-generated-sites/rfc1437-sample/assets/pico.blue.min.css"
        ),
    },
    BundledSiteAsset {
        relative_path: "assets/pico.cyan.min.css",
        bytes: include_bytes!(
            "../../../../fixtures/golden-generated-sites/rfc1437-sample/assets/pico.cyan.min.css"
        ),
    },
    BundledSiteAsset {
        relative_path: "assets/pico.fuchsia.min.css",
        bytes: include_bytes!(
            "../../../../fixtures/golden-generated-sites/rfc1437-sample/assets/pico.fuchsia.min.css"
        ),
    },
    BundledSiteAsset {
        relative_path: "assets/pico.green.min.css",
        bytes: include_bytes!(
            "../../../../fixtures/golden-generated-sites/rfc1437-sample/assets/pico.green.min.css"
        ),
    },
    BundledSiteAsset {
        relative_path: "assets/pico.grey.min.css",
        bytes: include_bytes!(
            "../../../../fixtures/golden-generated-sites/rfc1437-sample/assets/pico.grey.min.css"
        ),
    },
    BundledSiteAsset {
        relative_path: "assets/pico.indigo.min.css",
        bytes: include_bytes!(
            "../../../../fixtures/golden-generated-sites/rfc1437-sample/assets/pico.indigo.min.css"
        ),
    },
    BundledSiteAsset {
        relative_path: "assets/pico.jade.min.css",
        bytes: include_bytes!(
            "../../../../fixtures/golden-generated-sites/rfc1437-sample/assets/pico.jade.min.css"
        ),
    },
    BundledSiteAsset {
        relative_path: "assets/pico.lime.min.css",
        bytes: include_bytes!(
            "../../../../fixtures/golden-generated-sites/rfc1437-sample/assets/pico.lime.min.css"
        ),
    },
    BundledSiteAsset {
        relative_path: "assets/pico.min.css",
        bytes: include_bytes!(
            "../../../../fixtures/golden-generated-sites/rfc1437-sample/assets/pico.min.css"
        ),
    },
    BundledSiteAsset {
        relative_path: "assets/pico.orange.min.css",
        bytes: include_bytes!(
            "../../../../fixtures/golden-generated-sites/rfc1437-sample/assets/pico.orange.min.css"
        ),
    },
    BundledSiteAsset {
        relative_path: "assets/pico.pink.min.css",
        bytes: include_bytes!(
            "../../../../fixtures/golden-generated-sites/rfc1437-sample/assets/pico.pink.min.css"
        ),
    },
    BundledSiteAsset {
        relative_path: "assets/pico.pumpkin.min.css",
        bytes: include_bytes!(
            "../../../../fixtures/golden-generated-sites/rfc1437-sample/assets/pico.pumpkin.min.css"
        ),
    },
    BundledSiteAsset {
        relative_path: "assets/pico.purple.min.css",
        bytes: include_bytes!(
            "../../../../fixtures/golden-generated-sites/rfc1437-sample/assets/pico.purple.min.css"
        ),
    },
    BundledSiteAsset {
        relative_path: "assets/pico.red.min.css",
        bytes: include_bytes!(
            "../../../../fixtures/golden-generated-sites/rfc1437-sample/assets/pico.red.min.css"
        ),
    },
    BundledSiteAsset {
        relative_path: "assets/pico.sand.min.css",
        bytes: include_bytes!(
            "../../../../fixtures/golden-generated-sites/rfc1437-sample/assets/pico.sand.min.css"
        ),
    },
    BundledSiteAsset {
        relative_path: "assets/pico.slate.min.css",
        bytes: include_bytes!(
            "../../../../fixtures/golden-generated-sites/rfc1437-sample/assets/pico.slate.min.css"
        ),
    },
    BundledSiteAsset {
        relative_path: "assets/pico.violet.min.css",
        bytes: include_bytes!(
            "../../../../fixtures/golden-generated-sites/rfc1437-sample/assets/pico.violet.min.css"
        ),
    },
    BundledSiteAsset {
        relative_path: "assets/pico.yellow.min.css",
        bytes: include_bytes!(
            "../../../../fixtures/golden-generated-sites/rfc1437-sample/assets/pico.yellow.min.css"
        ),
    },
    BundledSiteAsset {
        relative_path: "assets/pico.zinc.min.css",
        bytes: include_bytes!(
            "../../../../fixtures/golden-generated-sites/rfc1437-sample/assets/pico.zinc.min.css"
        ),
    },
    BundledSiteAsset {
        relative_path: "assets/search-runtime.js",
        bytes: include_bytes!(
            "../../../../fixtures/golden-generated-sites/rfc1437-sample/assets/search-runtime.js"
        ),
    },
    BundledSiteAsset {
        relative_path: "assets/tag-cloud.js",
        bytes: include_bytes!(
            "../../../../fixtures/golden-generated-sites/rfc1437-sample/assets/tag-cloud.js"
        ),
    },
    BundledSiteAsset {
        relative_path: "assets/vanilla-calendar.min.css",
        bytes: include_bytes!(
            "../../../../fixtures/golden-generated-sites/rfc1437-sample/assets/vanilla-calendar.min.css"
        ),
    },
    BundledSiteAsset {
        relative_path: "assets/vanilla-calendar.min.js",
        bytes: include_bytes!(
            "../../../../fixtures/golden-generated-sites/rfc1437-sample/assets/vanilla-calendar.min.js"
        ),
    },
    BundledSiteAsset {
        relative_path: "images/close.png",
        bytes: include_bytes!(
            "../../../../fixtures/golden-generated-sites/rfc1437-sample/images/close.png"
        ),
    },
    BundledSiteAsset {
        relative_path: "images/loading.gif",
        bytes: include_bytes!(
            "../../../../fixtures/golden-generated-sites/rfc1437-sample/images/loading.gif"
        ),
    },
    BundledSiteAsset {
        relative_path: "images/next.png",
        bytes: include_bytes!(
            "../../../../fixtures/golden-generated-sites/rfc1437-sample/images/next.png"
        ),
    },
    BundledSiteAsset {
        relative_path: "images/prev.png",
        bytes: include_bytes!(
            "../../../../fixtures/golden-generated-sites/rfc1437-sample/images/prev.png"
        ),
    },
];

pub(crate) fn bundled_site_asset(relative_path: &str) -> Option<&'static [u8]> {
    BUNDLED_SITE_ASSETS
        .iter()
        .find(|asset| asset.relative_path == relative_path)
        .map(|asset| asset.bytes)
}

pub(crate) fn bundled_site_assets() -> &'static [BundledSiteAsset] {
    BUNDLED_SITE_ASSETS
}

pub(crate) fn copy_bundled_site_assets(project_dir: &Path) -> EngineResult<()> {
    for asset in BUNDLED_SITE_ASSETS {
        let target = project_dir.join(asset.relative_path);
        if target.exists() {
            continue;
        }
        if let Some(parent) = target.parent() {
            fs::create_dir_all(parent)?;
        }
        fs::write(target, asset.bytes)?;
    }
    Ok(())
}

#[cfg(test)]
mod tests {
    use super::bundled_site_asset;

    fn bundled_text(path: &str) -> &'static str {
        std::str::from_utf8(bundled_site_asset(path).unwrap()).unwrap()
    }

    #[test]
    fn calendar_heatmap_marks_only_populated_periods_with_one_accent() {
        let runtime = bundled_text("assets/calendar-runtime.js");
        let styles = bundled_text("assets/bds.css");

        assert!(runtime.contains("--blog-calendar-heat-strength"));
        assert!(!runtime.contains("--blog-calendar-heat-hue"));
        assert!(styles.contains(
            "[data-vc-date]:not([data-blog-calendar-has-posts='true']) [data-vc-date-btn]"
        ));
        assert!(styles.contains("background-color: transparent !important;"));
        assert!(styles.contains("border-color: transparent !important;"));
        assert!(styles.contains("color-mix(in srgb, var(--pico-primary"));
        assert!(styles.contains("var(--blog-calendar-heat-strength"));
        assert!(styles.contains("transparent) !important;"));
        assert!(!styles.contains("hsl(var(--blog-calendar-heat-hue"));
    }
}
