import { LitElement } from 'lit';
import { TemplateResult } from 'lit-html';

declare class FloatingService extends FloatingUI {
    protected options: FloatingUIOptions;
    protected trigger: string;
    private hoverTimeout;
    constructor();
    private setTarget;
    private getTarget;
    private setContent;
    handleSlotChange({ target }: {
        target: any;
    }): void;
    private hasTrigger;
    private listener;
    private handleBlur;
    private handleFocus;
    private handleClick;
    private handleMouseOver;
    private handleMouseOut;
    private handleClickOutside;
}

declare class FloatingUI extends PlusBase {
    protected options: FloatingUIOptions;

    constructor(
    options: FloatingUIOptions = {
        position: "bottom",
        showArrow: false,
        offset: 6,
        showDelay: 200,
        hideDelay: 200,
        zIndex: 50,
        autoHide: true,
    },
    ) {
        super();
        this.options = options;
    }

    updatePosition() {
        // const { target, content, offset: _offset, autoHide, position, showArrow } = this.options;
        if (!this.options.target || !this.options.content) return;
        const _middleware = [offset(this.options.offset), flip(), shift({ padding: 8 })];
        if (this.options.autoHide) {
            _middleware.push(hide({ padding: 10 }));
        }
        const arrowElement = this.options.content.querySelector(".arrow") as HTMLElement;
        if (this.options.showArrow) {
            if (arrowElement) {
                _middleware.push(arrow({ element: arrowElement }));
            }
        }

        computePosition(this.options.target, this.options.content, {
            placement: this.options.position,
            middleware: _middleware,
        }).then(({ x, y, placement, middlewareData }) => {
            Object.assign(this.options.content.style, {
                left: `${x}px`,
                top: `${y}px`,
            });
            if (this.options.showArrow && arrowElement) {
                // const { x: arrowX, y: arrowY } = middlewareData.arrow;

                const staticSide = {
                    top: "bottom",
                    right: "left",
                    bottom: "top",
                    left: "right",
                }[placement.split("-")[0]];

                Object.assign(arrowElement.style, {
                    left: middlewareData.arrow.x != null ? `${middlewareData.arrow.x}px` : "",
                    top: middlewareData.arrow.y != null ? `${middlewareData.arrow.y}px` : "",
                    right: "",
                    bottom: "",
                    [staticSide]: "-6px",
                });
            }
        });
    }

    show() {
        this.options.content.style.display = "block";
        this.updatePosition();
        this.options.isOpened?.(true);
    }

    hide() {
        this.options.content.style.display = "none";
        this.options.isOpened?.(false);
    }

    isOpen() {
        return this.options.content.style.display === "block";
    }

    destroy() {}
}

declare type FloatingUIOptions = {
    target?: HTMLElement;
    content?: HTMLElement;
    position?: PlacementType;
    showArrow?: boolean;
    offset?: number;
    showDelay?: number;
    hideDelay?: number;
    zIndex?: number;
    autoHide?: boolean;
    onShow?: () => void;
    onHide?: () => void;
    isOpened?: (open: boolean) => void;
    onVisibleChange?: (visible: boolean) => void;
    onPositionChange?: (position: PlacementType) => void;
};

declare type PlacementType = "top" | "top-start" | "top-end" | "bottom" | "bottom-start" | "bottom-end" | "left" | "left-start" | "left-end" | "right" | "right-start" | "right-end";

declare abstract class PlusBase extends LitElement {
    static styles = [unsafeCSS(tailwind), unsafeCSS(theme), unsafeCSS(fa)];

    // ID property with default value
    @property({ type: String, reflect: true })
    id: string = `plusui-${Math.random().toString(36).slice(2, 12)}`;

    // Name property with default value
    @property()
    name: string = "";

    // Value property with default value
    @property({ type: String, reflect: true })
    value: string | number = "";

    // Disabled property with default value
    @property({ type: Boolean, reflect: true })
    disabled: boolean = false;

    // Readonly property with default value
    @property({ type: Boolean, reflect: true })
    readonly: boolean = false;

    // Required property with default value
    @property({ type: Boolean, reflect: true })
    required: boolean = false;

    // Loading property with default value
    @property({ type: Boolean })
    loading = false;

    // Title property with default value
    @property()
    title = "";

    // emit function to dispatch events
    emit(name: string, options?: CustomEventInit) {
        // Create a new CustomEvent object
        const event = new CustomEvent(name, {
            bubbles: true,
            cancelable: false,
            composed: true,
            detail: {},
            ...options,
        });

        // Dispatch the event
        this.dispatchEvent(event);

        // Return the event
        return event;
    }
}

export declare class PopoverComponent extends FloatingService {
    size: SizeType;
    placement: PlacementType;
    showArrow: boolean;
    title: string;
    status: "success" | "warning" | "error" | "info" | "default" | "primary" | "attention";
    okText: string;
    cancelText: string;
    trigger: string;
    _prefixIcon: string;
    set prefixIcon(value: any);
    get prefixIcon(): any;
    private onConfirm;
    private onCancel;
    constructor();
    protected firstUpdated(): void;
    render(): TemplateResult<1>;
}

declare type SizeType = "sm" | "md" | "lg";

export { }
