import React, { useState, useEffect } from 'react';
import { Menu, MenuItem } from '@material-ui/core';
import NestedMenuItem from "material-ui-nested-menu-item";
import { QueryElem, QueryLeafBy, QueryLeafOp, TagQueryInfo } from '../../lib/query/Query';
import QBSelectWithRequest from './QBSelectWithRequest';
import { Requests } from './QueryBuilder';

export interface MenuProps {
    anchorEl: null | HTMLElement,
    onClose: () => void,
    onCreateQuery: (q: QueryElem) => void,
    requestFunctions: Requests,
}

export function createTagInfo(tag: any, allTags: any[]): TagQueryInfo {
    const resolveName: (t: any) => string[] = (t: any) => {
        if (t.parentId) {
            const parent = allTags.filter((o: any) => o.tagId === t.parentId)[0];
            return [resolveName(parent), t.name];
        }
        return [t.name];
    }

    const resolveChildren: (t: any) => Set<number> = (t: any) => {
        if (t.childIds.length > 0) {
            const childSets: Set<number>[] = allTags.filter((o: any) => t.childIds.includes(o.tagId))
                .map((child: any) => resolveChildren(child));

            var r = new Set<number>();
            childSets.forEach((c: any) => {
                r = new Set([...r, ...c]);
            });

            return r;
        }
        return new Set([t.tagId]);
    }

    return {
        matchIds: [...resolveChildren(tag)],
        fullName: resolveName(tag),
    }
}

export function QBAddElemMenu(props: MenuProps) {
    let anchorEl = props.anchorEl;
    let onClose = props.onClose;

    interface TagItemProps {
        tag: any,
        allTags: any[],
    }
    const TagItem = (_props: TagItemProps) => {
        if (_props.tag.childIds.length > 0) {
            const children = _props.allTags.filter(
                (tag: any) => _props.tag.childIds.includes(tag.tagId)
            );

            return <NestedMenuItem
                label={_props.tag.name}
                parentMenuOpen={Boolean(anchorEl)}
                onClick={() => {
                    onClose();
                    props.onCreateQuery({
                        a: QueryLeafBy.TagInfo,
                        leafOp: QueryLeafOp.Equals,
                        b: createTagInfo(_props.tag, _props.allTags),
                    });
                }}
            >
                {children.map((child: any) => <TagItem tag={child} allTags={_props.allTags} />)}
            </NestedMenuItem>
        }

        return <MenuItem
            onClick={() => {
                onClose();
                props.onCreateQuery({
                    a: QueryLeafBy.TagInfo,
                    leafOp: QueryLeafOp.Equals,
                    b: createTagInfo(_props.tag, _props.allTags),
                });
            }}
        >
            {_props.tag.name}
        </MenuItem>
    }

    const BaseTagsItem = (_props: any) => {
        const [tags, setTags] = useState<any[] | null>(null);

        useEffect(() => {
            (async () => {
                setTags(await props.requestFunctions.getTags());
            })()
        }, []);

        return tags ?
            <>
                {tags.filter((tag: any) => !tag.parentId).map((tag: any) => {
                    return <TagItem tag={tag} allTags={tags} />
                })}
            </>
            : <>...</>
    }

    return <Menu
        anchorEl={anchorEl}
        keepMounted
        open={Boolean(anchorEl)}
        onClose={onClose}
    >
        <MenuItem disabled={true}>New query element</MenuItem>
        <NestedMenuItem
            label="Song"
            parentMenuOpen={Boolean(anchorEl)}
        >
            <QBSelectWithRequest
                label="Title"
                getNewOptions={props.requestFunctions.getSongTitles}
                onSubmit={(s: string, exact: boolean) => {
                    onClose();
                    props.onCreateQuery({
                        a: QueryLeafBy.SongTitle,
                        leafOp: exact ? QueryLeafOp.Equals : QueryLeafOp.Like,
                        b: s
                    });
                }}
                style={{ width: 300 }}
            />
        </NestedMenuItem>
        <NestedMenuItem
            label="Artist"
            parentMenuOpen={Boolean(anchorEl)}
        >
            <QBSelectWithRequest
                label="Name"
                getNewOptions={props.requestFunctions.getArtists}
                onSubmit={(s: string, exact: boolean) => {
                    onClose();
                    props.onCreateQuery({
                        a: QueryLeafBy.ArtistName,
                        leafOp: exact ? QueryLeafOp.Equals : QueryLeafOp.Like,
                        b: s
                    });
                }}
                style={{ width: 300 }}
            />
        </NestedMenuItem>
        <NestedMenuItem
            label="Album"
            parentMenuOpen={Boolean(anchorEl)}
        >
            <QBSelectWithRequest
                label="Name"
                getNewOptions={props.requestFunctions.getAlbums}
                onSubmit={(s: string, exact: boolean) => {
                    onClose();
                    props.onCreateQuery({
                        a: QueryLeafBy.AlbumName,
                        leafOp: exact ? QueryLeafOp.Equals : QueryLeafOp.Like,
                        b: s
                    });
                }}
                style={{ width: 300 }}
            />
        </NestedMenuItem>
        <NestedMenuItem
            label="Tag"
            parentMenuOpen={Boolean(anchorEl)}
        >
            <BaseTagsItem />
        </NestedMenuItem>
    </Menu >
}
