// Copyright © onWidget <https://github.com/onwidget>
// SPDX-License-Identifier: MIT
import {
    isUnpicCompatible,
    unpicOptimizer,
    astroAssetsOptimizer,
} from "./images-optimization";
import type { ImageMetadata } from "astro";
import type { OpenGraph } from "@astrolib/seo";

const load = function () {
    let images: Record<string, () => Promise<unknown>> | undefined = undefined;
    try {
        images = import.meta.glob(
            "~/assets/images/**/*.{jpeg,jpg,png,tiff,webp,gif,svg,JPEG,JPG,PNG,TIFF,WEBP,GIF,SVG}",
        );
        // eslint-disable-next-line @typescript-eslint/no-unused-vars
    } catch (error) {
        // continue regardless of error
    }
    return images;
};

let _images: Record<string, () => Promise<unknown>> | undefined = undefined;

/** */
export const fetchLocalImages = () => {
    _images = _images || load();
    return _images;
};

/** */
export const findImage = async (
    imagePath?: string | ImageMetadata | null,
): Promise<string | ImageMetadata | undefined | null> => {
    // Not string
    if (typeof imagePath !== "string") {
        return imagePath;
    }

    // Absolute paths
    if (
        imagePath.startsWith("http://") ||
        imagePath.startsWith("https://") ||
        imagePath.startsWith("/")
    ) {
        return imagePath;
    }

    // Relative paths or not "~/assets/"
    if (!imagePath.startsWith("~/assets/images")) {
        return imagePath;
    }

    const images = fetchLocalImages();
    const key = imagePath.replace("~/", "/src/");

    return images && typeof images[key] === "function"
        ? ((await images[key]()) as { default: ImageMetadata })["default"]
        : null;
};

/** */
export const adaptOpenGraphImages = async (
    openGraph: OpenGraph = {},
    astroSite: URL | undefined = new URL(""),
): Promise<OpenGraph> => {
    if (!openGraph?.images?.length) {
        return openGraph;
    }

    const images = openGraph.images;
    const defaultWidth = 1200;
    const defaultHeight = 626;

    const adaptedImages = await Promise.all(
        images.map(async (image) => {
            if (image?.url) {
                const resolvedImage = (await findImage(image.url)) as
                    | ImageMetadata
                    | string
                    | undefined;
                if (!resolvedImage) {
                    return {
                        url: "",
                    };
                }

                let _image:
                    | {
                          url: string;
                          width?: number;
                          height?: number;
                      }
                    | undefined;

                if (
                    typeof resolvedImage === "string" &&
                    (resolvedImage.startsWith("http://") ||
                        resolvedImage.startsWith("https://")) &&
                    isUnpicCompatible(resolvedImage)
                ) {
                    const optimized = (
                        await unpicOptimizer(
                            resolvedImage,
                            [defaultWidth],
                            defaultWidth,
                            defaultHeight,
                            "jpg",
                        )
                    )[0];
                    _image = {
                        url: optimized.src,
                        width: optimized.width,
                        height: defaultHeight,
                    };
                } else if (resolvedImage) {
                    const dimensions =
                        typeof resolvedImage !== "string" &&
                        resolvedImage?.width <= defaultWidth
                            ? [resolvedImage?.width, resolvedImage?.height]
                            : [defaultWidth, defaultHeight];
                    const optimized = (
                        await astroAssetsOptimizer(
                            resolvedImage,
                            [dimensions[0]],
                            dimensions[0],
                            dimensions[1],
                            "jpg",
                        )
                    )[0];
                    _image = {
                        url: optimized.src,
                        width: optimized.width,
                        height: dimensions[1],
                    };
                }

                if (typeof _image === "object") {
                    return {
                        url:
                            "url" in _image && typeof _image.url === "string"
                                ? String(new URL(_image.url, astroSite))
                                : "",
                        width:
                            "width" in _image &&
                            typeof _image.width === "number"
                                ? _image.width
                                : undefined,
                        height:
                            "height" in _image &&
                            typeof _image.height === "number"
                                ? _image.height
                                : undefined,
                    };
                }
                return {
                    url: "",
                };
            }

            return {
                url: "",
            };
        }),
    );

    return {
        ...openGraph,
        ...(adaptedImages ? { images: adaptedImages } : {}),
    };
};
