import {AbstractModal} from "tc-shared/ui/react-elements/modal/Definitions";
import React from "react";
import {joinClassList} from "tc-shared/ui/react-elements/Helper";
import TeaCupImage from "./TeaCup.png";
import {ErrorBoundary} from "tc-shared/ui/react-elements/ErrorBoundary";
import {ClientIcon} from "svg-sprites/client-icons";
import {ClientIconRenderer} from "tc-shared/ui/react-elements/Icons";

const cssStyle = require("./Renderer.scss");

export class ModalFrameTopRenderer extends React.PureComponent<{
    modalInstance: AbstractModal,

    className?: string,

    onClose?: () => void,
    onPopout?: () => void,
    onMinimize?: () => void,

    replacePageTitle: boolean,
}> {
    private readonly refTitle = React.createRef<HTMLDivElement>();
    private titleElement: HTMLTitleElement;
    private observer: MutationObserver;

    componentDidMount() {
        if(this.props.replacePageTitle) {
            const titleElements = document.getElementsByTagName("title");
            if(titleElements.length === 0) {
                this.titleElement = document.createElement("title");
                document.head.appendChild(this.titleElement);
            } else {
                this.titleElement = titleElements[0];
            }

            this.observer = new MutationObserver(() => this.updatePageTitle());
            this.observer.observe(this.refTitle.current, {
                attributes: true,
                subtree: true,
                childList: true,
                characterData: true
            });
            this.updatePageTitle();
        }
    }

    componentWillUnmount() {
        this.observer?.disconnect();
        this.observer = undefined;
        this.titleElement = undefined;
    }

    render() {
        const buttons = [];
        if(this.props.onMinimize) {
            buttons.push(
                <div className={cssStyle.button} onClick={this.props.onMinimize} key={"button-minimize"}>
                    <ClientIconRenderer icon={ClientIcon.MinimizeButton} />
                </div>
            );
        }

        if(this.props.onPopout) {
            buttons.push(
                <div className={cssStyle.button} onClick={this.props.onPopout} key={"button-popout"}>
                    <ClientIconRenderer icon={ClientIcon.ChannelPopout} />
                </div>
            );
        }

        if(this.props.onClose) {
            buttons.push(
                <div className={cssStyle.button} onClick={this.props.onClose} key={"button-close"}>
                    <ClientIconRenderer icon={ClientIcon.CloseButton} />
                </div>
            );
        }

        return (
            <div className={joinClassList(cssStyle.modalTitle, this.props.className)}>
                <div className={cssStyle.icon}>
                    <img src={TeaCupImage} alt={""} draggable={false} />
                </div>
                <div className={cssStyle.title} ref={this.refTitle}>
                    <ErrorBoundary>
                        {this.props.modalInstance.renderTitle()}
                    </ErrorBoundary>
                </div>
                {buttons}
            </div>
        );
    }

    private updatePageTitle() {
        if(!this.refTitle.current) {
            return;
        }

        this.titleElement.innerText = this.refTitle.current.textContent;
    }
}


export class ModalBodyRenderer extends React.PureComponent<{
    modalInstance: AbstractModal,
    className?: string
}> {
    constructor(props) {
        super(props);
    }

    render() {
        return (
            <div className={joinClassList(
                cssStyle.modalBody,
                this.props.className,
                cssStyle["color-" + this.props.modalInstance.color()]
            )}>
                <ErrorBoundary>
                    {this.props.modalInstance.renderBody()}
                </ErrorBoundary>
            </div>
        )
    }
}

export class ModalFrameRenderer extends React.PureComponent<{
    windowed: boolean,
    children: [React.ReactElement<ModalFrameTopRenderer>, React.ReactElement<ModalBodyRenderer>]
}> {
    render() {
        return (
            <div className={cssStyle.modalFrame + " " + (this.props.windowed ? cssStyle.windowed : "")}>
                {this.props.children[0]}
                {this.props.children[1]}
            </div>
        );
    }
}

export class PageModalRenderer extends React.PureComponent<{
    modalInstance: AbstractModal,
    onBackdropClicked: () => void,
    children: React.ReactElement<ModalFrameRenderer>,

    shown: boolean
}> {
    constructor(props) {
        super(props);

        this.state = {
            shown: false
        };
    }

    render() {
        return (
            <div
                className={joinClassList(
                    cssStyle.modalPageContainer,
                    cssStyle["align-" + this.props.modalInstance.verticalAlignment()],
                    this.props.shown ? cssStyle.shown : undefined
                )}
                tabIndex={-1}
                role={"dialog"}
                aria-hidden={true}
                onClick={event => {
                    if(event.target !== event.currentTarget) {
                        return;
                    }

                    this.props.onBackdropClicked();
                }}
            >
                <div className={cssStyle.dialog}>
                    {this.props.children}
                </div>
            </div>
        );
    }
}

export const WindowModalRenderer = (props: {
    children: [React.ReactElement<ModalFrameTopRenderer>, React.ReactElement<ModalBodyRenderer>]
}) => {
    return (
        <div className={cssStyle.modalWindowContainer}>
            {props.children[0]}
            {props.children[1]}
        </div>
    );
}