import { applySwitcheroo } from '../designApplication';
import { ColorSet, ComponentId } from '../dataModels';
import { ComponentBase, ComponentState } from './componentBase';
import { getPositionerByName, PopupManager } from '../popupManager';

export type PopupState = ComponentState & {
    _type_: 'Popup-builtin';
    anchor?: ComponentId;
    content?: ComponentId;
    color?: ColorSet | 'none';
    corner_radius?: number | [number, number, number, number];
    position?:
        | 'auto'
        | 'left'
        | 'top'
        | 'right'
        | 'bottom'
        | 'center'
        | 'fullscreen';
    alignment?: number;
    gap?: number;
    is_open?: boolean;
};

export class PopupComponent extends ComponentBase {
    state: Required<PopupState>;

    private anchorContainer: HTMLElement;
    private contentContainer: HTMLElement;

    private popupManager: PopupManager;

    createElement(): HTMLElement {
        let element = document.createElement('div');
        element.classList.add('rio-popup');

        this.anchorContainer = document.createElement('div');
        this.anchorContainer.classList.add('rio-popup-anchor');
        element.appendChild(this.anchorContainer);

        this.contentContainer = document.createElement('div');
        this.contentContainer.classList.add(
            'rio-popup-animation-scale',
            'rio-popup-content'
        );
        element.appendChild(this.contentContainer);

        // Initialize the popup manager. Many of these values will be
        // overwritten by the updateElement method.
        this.popupManager = new PopupManager(
            this.anchorContainer,
            this.contentContainer,
            getPositionerByName('center', 0, 0.5)
        );

        return element;
    }

    updateElement(
        deltaState: PopupState,
        latentComponents: Set<ComponentBase>
    ): void {
        super.updateElement(deltaState, latentComponents);

        // Update the children
        this.replaceOnlyChild(
            latentComponents,
            deltaState.anchor,
            this.anchorContainer
        );

        this.replaceOnlyChild(
            latentComponents,
            deltaState.content,
            this.contentContainer
        );

        // Update the popup manager
        if (
            deltaState.position !== undefined ||
            deltaState.alignment !== undefined ||
            deltaState.gap !== undefined
        ) {
            this.popupManager.positioner = getPositionerByName(
                deltaState.position ?? this.state.position,
                deltaState.gap ?? this.state.gap,
                deltaState.alignment ?? this.state.alignment
            );
        }

        // Open / Close
        if (deltaState.is_open !== undefined) {
            this.popupManager.isOpen = deltaState.is_open;
        }

        // Colorize
        if (deltaState.color === 'none') {
            applySwitcheroo(this.contentContainer, 'keep');
            this.contentContainer.style.removeProperty('background-color');
            this.contentContainer.style.removeProperty('box-shadow');
        } else if (deltaState.color !== undefined) {
            applySwitcheroo(this.contentContainer, deltaState.color);
            this.contentContainer.style.backgroundColor = `var(--rio-local-bg)`;
            this.contentContainer.style.boxShadow = `0 0 1rem var(--rio-global-shadow-color)`;
        }

        // Update the corner radius
        if (deltaState.corner_radius !== undefined) {
            if (typeof deltaState.corner_radius === 'number') {
                this.contentContainer.style.borderRadius = `${deltaState.corner_radius}rem`;
            } else {
                this.contentContainer.style.borderRadius = `${deltaState.corner_radius[0]}rem ${deltaState.corner_radius[1]}rem ${deltaState.corner_radius[2]}rem ${deltaState.corner_radius[3]}rem`;
            }
        }
    }

    onDestruction(): void {
        super.onDestruction();
        this.popupManager.destroy();
    }
}
