
import { isDevEnvironment, showBalloonMessage } from "../../engine/debug/index.js";
import { serializable } from "../../engine/engine_serialization.js";
import { DeviceUtilities } from "../../engine/engine_utils.js";
import { Behaviour } from "../Component.js";
import { type IPointerClickHandler, PointerEventData } from "../ui/index.js";
import { ObjectRaycaster } from "../ui/Raycaster.js";

/**
 * [OpenURL](https://engine.needle.tools/docs/api/OpenURL) OpenURLMode defines how a URL should be opened.
 */
export enum OpenURLMode {
    NewTab = 0,
    SameTab = 1,
    NewWindow = 2
}

/** 
 * OpenURL behaviour opens a URL in a new tab or window when the object (or any if it's children) is clicked.
 * 
 * @category Interactivity
 * @category Web
 * @group Components
 */
export class OpenURL extends Behaviour implements IPointerClickHandler {

    /**
     * The URL to open.
     */
    @serializable()
    url?: string;

    /**
     * The mode in which the URL should be opened: NewTab, SameTab, NewWindow.
     */
    @serializable()
    mode: OpenURLMode = OpenURLMode.NewTab;

    /**
     * If true, the URL will be opened when the object with this component is clicked.
     */
    @serializable()
    clickable: boolean = true;

    /**
     * Opens the URL in a new tab or window.
     */
    async open() {
        if (!this.url) {
            console.warn("OpenURL: URL is not set, can't open.", this);
            return;
        }

        this._validateUrl();

        let url = this.url;
        if (!url.startsWith("mailto:") && url.includes("@")) {
            url = "mailto:" + url;
        }

        switch (this.mode) {
            case OpenURLMode.NewTab:
                if (DeviceUtilities.isSafari()) {
                    globalThis.open(url, "_blank");
                }
                else
                    globalThis.open(url, "_blank");
                break;
            case OpenURLMode.SameTab:
                // TODO: test if "same tab" now also works on iOS
                if (DeviceUtilities.isSafari() && DeviceUtilities.isiOS()) {
                    globalThis.open(url, "_top");
                }
                else
                    globalThis.open(url, "_self");
                break;
            case OpenURLMode.NewWindow:
                if (DeviceUtilities.isSafari()) {
                    globalThis.open(url, "_top");
                }
                else globalThis.open(url, "_new");
                break;

        }
    }
    /** @internal */
    start(): void {
        const raycaster = this.gameObject.getComponentInParent(ObjectRaycaster);
        if (!raycaster) this.gameObject.addComponent(ObjectRaycaster);
    }
    /** @internal */
    onPointerEnter(args) {
        if (!args.used && this.clickable)
            this.context.input.setCursor("pointer");
    }
    /** @internal */
    onPointerExit() {
        if (this.clickable)
            this.context.input.unsetCursor("pointer");
    }
    /** @internal */
    onPointerClick(args: PointerEventData) {
        if (this.clickable && !args.used && this.url?.length)
            this.open();
    }
    private _validateUrl() {
        if (!this.url) return;
        if (this.url.startsWith("www.")) {
            if (isDevEnvironment()) {
                console.warn("URL is not valid, adding https:// to the start of the URL", this.url);
            }
            this.url = "https://" + this.url;
        }
    }
}