// ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
// ┃ ██████ ██████ ██████       █      █      █      █      █ █▄  ▀███ █       ┃
// ┃ ▄▄▄▄▄█ █▄▄▄▄▄ ▄▄▄▄▄█  ▀▀▀▀▀█▀▀▀▀▀ █ ▀▀▀▀▀█ ████████▌▐███ ███▄  ▀█ █ ▀▀▀▀▀ ┃
// ┃ █▀▀▀▀▀ █▀▀▀▀▀ █▀██▀▀ ▄▄▄▄▄ █ ▄▄▄▄▄█ ▄▄▄▄▄█ ████████▌▐███ █████▄   █ ▄▄▄▄▄ ┃
// ┃ █      ██████ █  ▀█▄       █ ██████      █      ███▌▐███ ███████▄ █       ┃
// ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
// ┃ Copyright (c) 2017, the Perspective Authors.                              ┃
// ┃ ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ ┃
// ┃ This file is part of the Perspective library, distributed under the terms ┃
// ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
// ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛

import { style_cell_flash } from "./cell_flash.js";
import {
    rgbaToRgb,
    infer_foreground_from_background,
} from "../../color_utils.js";
import type { DatagridModel, ColumnConfig, ColorRecord } from "../../types.js";

interface CellMetaWithExtras {
    _is_hidden_by_aggregate_depth?: boolean;
    user?: number;
    dy: number;
    column_header?: string[];
}

interface PluginWithColors
    extends Omit<
        ColumnConfig,
        "pos_fg_color" | "neg_fg_color" | "pos_bg_color" | "neg_bg_color"
    > {
    pos_bg_color?: ColorRecord;
    neg_bg_color?: ColorRecord;
    pos_fg_color?: ColorRecord;
    neg_fg_color?: ColorRecord;
}

export function cell_style_numeric(
    model: DatagridModel,
    plugin: PluginWithColors | undefined,
    td: HTMLElement,
    metadata: CellMetaWithExtras,
    is_settings_open: boolean,
): void {
    const is_positive = (metadata.user ?? 0) > 0;
    const is_negative = (metadata.user ?? 0) < 0;

    let pos_bg_color: ColorRecord;
    if (plugin?.pos_bg_color !== undefined) {
        pos_bg_color = plugin.pos_bg_color;
    } else {
        pos_bg_color = model._pos_bg_color;
    }

    let neg_bg_color: ColorRecord;
    if (plugin?.neg_bg_color !== undefined) {
        neg_bg_color = plugin.neg_bg_color;
    } else {
        neg_bg_color = model._neg_bg_color;
    }

    const bg_tuple: ColorRecord = is_positive
        ? pos_bg_color
        : is_negative
          ? neg_bg_color
          : [
                "",
                model._plugin_background[0],
                model._plugin_background[1],
                model._plugin_background[2],
                "",
                "",
                "",
            ];

    {
        const [hex, r, g, b] = bg_tuple;

        td.style.position = "";
        if (metadata._is_hidden_by_aggregate_depth) {
            td.style.animation = "";
            td.style.backgroundColor = "";
        } else if (plugin?.number_bg_mode === "color") {
            td.style.animation = "";
            td.style.backgroundColor = hex;
        } else if (plugin?.number_bg_mode === "gradient") {
            const a = Math.max(
                0,
                Math.min(
                    1,
                    Math.abs((metadata.user ?? 0) / (plugin.bg_gradient ?? 1)),
                ),
            );
            const source = model._plugin_background as [number, number, number];
            const foreground = infer_foreground_from_background(
                rgbaToRgb([r, g, b, a], source),
            );

            td.style.animation = "";
            td.style.color = foreground;
            td.style.backgroundColor = `rgba(${r},${g},${b},${a})`;
        } else if (plugin?.number_bg_mode === "pulse") {
            style_cell_flash(
                model,
                metadata as any,
                td,
                pos_bg_color,
                neg_bg_color,
                is_settings_open,
            );
            td.style.backgroundColor = "";
        } else if (
            plugin?.number_bg_mode === "disabled" ||
            !plugin?.number_bg_mode
        ) {
            td.style.animation = "";
            td.style.backgroundColor = "";
        } else {
            td.style.animation = "";
            td.style.backgroundColor = "";
        }
    }

    const fg_tuple: ColorRecord = (() => {
        if (plugin?.pos_fg_color !== undefined) {
            return is_positive
                ? plugin.pos_fg_color
                : is_negative
                  ? plugin.neg_fg_color!
                  : [
                        "",
                        model._plugin_background[0],
                        model._plugin_background[1],
                        model._plugin_background[2],
                        "",
                        "",
                        "",
                    ];
        } else {
            return is_positive
                ? model._pos_fg_color
                : is_negative
                  ? model._neg_fg_color
                  : [
                        "",
                        model._plugin_background[0],
                        model._plugin_background[1],
                        model._plugin_background[2],
                        "",
                        "",
                        "",
                    ];
        }
    })();

    const [hex, , , , gradhex] = fg_tuple;

    if (metadata._is_hidden_by_aggregate_depth) {
        td.style.backgroundColor = "";
        td.style.color = "";
    } else if (plugin?.number_fg_mode === "disabled") {
        if (plugin?.number_bg_mode === "color") {
            const source = model._plugin_background as [number, number, number];
            const foreground = infer_foreground_from_background(
                rgbaToRgb([bg_tuple[1], bg_tuple[2], bg_tuple[3], 1], source),
            );
            td.style.color = foreground;
        } else if (plugin?.number_bg_mode === "gradient") {
            // Color already set above
        } else {
            td.style.color = "";
        }
    } else if (plugin?.number_fg_mode === "bar") {
        td.style.color = "";
        td.style.position = "relative";
        td.style.setProperty("--psp-label-bar-color", gradhex);
        td.style.setProperty("--psp-label-bar-bg", hex);
    } else if (plugin?.number_fg_mode === "label-bar") {
        td.style.color = "";
        td.style.setProperty("--psp-label-bar-color", gradhex);
        td.style.setProperty("--psp-label-bar-bg", hex);
    } else if (plugin?.number_fg_mode === "color" || !plugin?.number_fg_mode) {
        td.style.color = hex;
    }
}
