/*
 * Copyright (c) 2015-2018, IGN France.
 * Copyright (c) 2018-2026, Giro3D team.
 * SPDX-License-Identifier: MIT
 */

import type { Feature } from 'ol';
import type { Color as OLColor } from 'ol/color';
import type { ColorLike } from 'ol/colorlike';
import type { Extent as OLExtent } from 'ol/extent';

import { Color } from 'three';

import type CoordinateSystem from '../core/geographic/CoordinateSystem';

import Extent from '../core/geographic/Extent';

function fromOLExtent(extent: OLExtent, coordinateSystem: CoordinateSystem): Extent {
    return new Extent(coordinateSystem, extent[0], extent[2], extent[1], extent[3]);
}

function toOLExtent(extent: Extent, margin = 0): OLExtent {
    return [extent.minX - margin, extent.minY - margin, extent.maxX + margin, extent.maxY + margin];
}

function parseAlpha(css: string): number {
    let color: RegExpExecArray | null;

    const parse = (s: string): number => {
        if (!s) {
            return 1;
        }

        return parseFloat(s);
    };

    // rgb(255,0,0) rgba(255,0,0,0.5)
    if ((color = /^\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec(css))) {
        return parse(color[4]);
    }
    // rgb(100%,0%,0%) rgba(100%,0%,0%,0.5)
    if ((color = /^\s*(\d+)%\s*,\s*(\d+)%\s*,\s*(\d+)%\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec(css))) {
        return parse(color[4]);
    }

    return 1;
}

function fromOLColor(input: OLColor | ColorLike): { color: Color; opacity: number } {
    if (typeof input === 'string') {
        const color = new Color().setStyle(input);
        const opacity = parseAlpha(input);

        return { color, opacity };
    } else if (Array.isArray(input)) {
        const [r, g, b, a] = input;

        return { color: new Color(r / 255, g / 255, b / 255), opacity: a };
    } else {
        throw new Error('unsupported color: ' + input);
    }
}

function getFeatureExtent(feature: Feature, crs: CoordinateSystem): Extent | undefined {
    const geometry = feature.getGeometry();
    if (!geometry) {
        return undefined;
    }
    const olExtent = geometry.getExtent();
    return fromOLExtent(olExtent, crs);
}

export default {
    fromOLExtent,
    toOLExtent,
    fromOLColor,
    getFeatureExtent,
};
