/* global chrome */
// BOOKMARK import here
import {Menu, MenuItem, Sidebar, SubMenu, useProSidebar} from "react-pro-sidebar";
import Island from "@jetbrains/ring-ui/dist/island/island";
import {H3, H4} from "@jetbrains/ring-ui/dist/heading/heading";
import {useEffect, useState} from "react";
import Img from 'react-image';
import Loader from '@jetbrains/ring-ui/dist/loader/loader';
import Text from '@jetbrains/ring-ui/dist/text/text';
import '@jetbrains/icons/file-js'
import Panel from "@jetbrains/ring-ui/dist/panel/panel";
import ImageActions from "./ImageActions";
import DraggableButton from "./KnowledgeDashBoard/DraggableButton";
import 'rc-dropdown/assets/index.css';
import Link from "@jetbrains/ring-ui/dist/link/link";
import {Col, Grid, Row} from '@jetbrains/ring-ui/dist/grid/grid';
import * as PropTypes from "prop-types";
import {SettingsView} from "./SettingsView";
import {WolframAlphaSearchArea} from "./WolframAlphaSearchArea";
import {filter, uniq} from "lodash";
import Badge from "@jetbrains/ring-ui/dist/badge/badge";
import {KnowledgeDashBoardHeader} from "./KnowledgeDashBoardHeader";

SettingsView.propTypes = {
    onKeyDown: PropTypes.func,
    onClick: PropTypes.func
};


KnowledgeDashBoardHeader.propTypes = {
    onClick: PropTypes.func,
    state: PropTypes.shape({
        loadingDraggableButton: PropTypes.bool,
        currentAssumption: PropTypes.string,
        dashBoardHidden: PropTypes.bool,
        loadingResult: PropTypes.bool,
        currentQuery: PropTypes.string,
        currentView: PropTypes.string,
        queryResult: PropTypes.arrayOf(PropTypes.any),
        buttonPosition: PropTypes.shape({x: PropTypes.number, y: PropTypes.number})
    }),
    onClick1: PropTypes.func,
    onClick2: PropTypes.func
};
/**
 * @desc This is Knowledge Dashboard
 * @class KnowledgeDashBoard
 * @returns {JSX.Element}
 * @todo How to design a program
 */
export default function KnowledgeDashBoard() {


// BOOKMARK state of this file
    /**
     * @desc state of this file
     */
    const [state, setState] = useState({
        currentQuery: "",
        currentAssumption: "",
        queryResult: [],
        dashBoardHidden: true,
        buttonPosition: {x: 0, y: 0},
        currentView: 'WolframAlpha',
        loadingDraggableButton: false,
        loadingResult: false,
    });
    const [isUsingDemoApi, setIsUsingDemoApi] = useState(undefined);
    chrome.storage.sync.get("wolframApi", (result) => {
        if (result.wolframApi === 'DEMO') {
            setIsUsingDemoApi(true);
        } else {
            setIsUsingDemoApi(false);
        }
    })
    const [currentPageReadability, setCurrentPageReadability] = useState(undefined);
    const [extensionEntities, setExtensionEntities] = useState(undefined);
    window.onload = () => {
        /*console.log("page is fully loaded")
        const clonedDocument = document.cloneNode(true)
        const pageReadability = new Readability(clonedDocument).parse()
        console.log("pageReadability", pageReadability.textContent)
        if (currentPageReadability !== pageReadability) {
            setCurrentPageReadability(pageReadability)
        }*/
    }

    useEffect(() => {
        chrome.runtime.sendMessage({textRazorEntitiesQuery: currentPageReadability?.textContent}, (result) => {
            const entities = result.response.entities
            const highConfidenceAndRelevanceEntities = filter(entities, (entity) => entity.confidenceScore > 5.0 && entity.relevanceScore > 0.9)
            const uniqueEntitiesId = uniq(highConfidenceAndRelevanceEntities.map((entity) => entity.entityId))
            setExtensionEntities(uniqueEntitiesId)
        })
    }, [currentPageReadability])

    const renderEntities = () => {
        if (extensionEntities) {
            return extensionEntities.map(entity => {
                return (<Badge valid
                               style={{cursor: 'pointer'}}
                               onClick={() => {
                                   sendQueryToBackGround(entity, undefined, undefined, undefined)
                               }}
                >{entity}</Badge>)
            })
        }
    }
    /**
     * @desc state of React-Pro-Sidebar
     */
    const {collapseSidebar, toggleSidebar, collapsed} = useProSidebar();
    // Fetch wolfram api in background and set to this component stage
    // Set wolfram api in background when this component state change


    /**
     * @function
     * @desc Toggle sidebar
     */
    function toggleSideBar() {
        if (collapsed) {
            toggleSidebar(true);
            collapseSidebar(false);
            setState({...state, dashBoardHidden: false});
        } else {
            collapseSidebar(true);
            toggleSidebar(false);
            setState({...state, dashBoardHidden: true});
        }
    }


    /**
     * @function
     * @param query
     * @param assumption
     * @param reinterpret
     * @param podstate
     */
    function sendQueryToBackGround(query,
                                   assumption,
                                   reinterpret,
                                   podstate = ""
    ) {
        // console.log("currentAssumption is",state.currentAssumption)
        setState(prevState => ({...prevState, currentQuery: query}));
        setState(prevState => ({...prevState, loadingResult: true}));
        if (assumption !== undefined) {
            setState(prevState => ({...prevState, currentAssumption: assumption}));
        }
        // If query is change, assumption simply get reset, at least in our case
        chrome.runtime.sendMessage({
            freeStyleQuery: query,
            assumption: assumption,
            reinterpret: reinterpret,
            podstate: podstate
        }, (response) => {
            setState(prevState => ({...prevState, queryResult: response.queryresult}));
            setState(prevState => ({...prevState, loadingResult: false}));
        });
    }

    /**
     * @function
     * @param e
     */
    function onDragStart(e) {
        setState({...state, buttonPosition: {x: e.screenX, y: e.screenY}});
    }

    /**
     * @function
     * @param e
     */
    function onDragStop(e) {
        const dragX = Math.abs(e.screenX - state.buttonPosition.x);
        const dragY = Math.abs(e.screenY - state.buttonPosition.y);
        // console.log(dragX,dragY)
        if (dragX > 5 || dragY > 5) {
            e.stopPropagation();
        } else {
            toggleSideBar();
        }

    }

    /**
     * Set wolfram key
     * @function
     * @param key
     */


    // DONE render podstate
    /**
     * @function
     * @returns {*}
     */
    function renderPods() {
        const queryResult = state.queryResult;
        if (queryResult.success === false) return;
        const query = queryResult.inputstring;
        const pods = queryResult.pods;
        let renderPods = null;
        if (queryResult.pods === undefined) return;
        renderPods = pods.map((pod, index) => {
            let renderStates;
            // DONE render states
            if (pod.states) {
                const statesArray = [];
                for (let i = 0; i < pod.states.length; i++) {
                    if (pod.states[i].states) {
                        for (let j = 0; j < pod.states[i].states.length; j++) {
                            statesArray.push(pod.states[i].states[j]);
                        }
                    } else {
                        statesArray.push(pod.states[i]);
                    }
                }
                renderStates = statesArray.map((state_, index) => {
                    const podStateInput = state_.input;
                    const podStateName = state_.name;
                    return (
                        <span>
                            {index > 0 && ", "}
                            <Link
                                onClick={() => {
                                    sendQueryToBackGround(query,
                                        state.currentAssumption,
                                        true, podStateInput)
                                }
                                }
                            >{podStateName}</Link></span>
                    )
                })
            }
            /**
             * @function
             */
            const subpodRender = pod.subpods.map((subpod, index) => {
                const subpodTitle = subpod.title;
                const subpodImage = subpod.img.src;
                const height = subpod.img.height;
                const width = subpod.img.width;
                let renderSubpodStates;

                if (subpod.states) {
                    const subpodStatesArray = [];
                    for (let i = 0; i < subpod.states.length; i++) {
                        if (subpod.states[i].states) {
                            for (let j = 0; j < subpod.states[i].states.length; j++) {
                                subpodStatesArray.push(subpod.states[i].states[j]);
                            }
                        } else {
                            subpodStatesArray.push(subpod.states[i]);
                        }
                    }

                    renderSubpodStates = subpodStatesArray.map((state_, index) => {
                        const subpodStateInput = state_.input;
                        const subpodStateName = state_.name;
                        return (
                            <span>
                                {index > 0 && ", "}
                                <Link
                                    onClick={() => {
                                        sendQueryToBackGround(query,
                                            state.currentAssumption,
                                            true, subpodStateInput)
                                    }
                                    }
                                >{subpodStateName}</Link></span>
                        )
                    })
                }
                return (

                    <Grid>

                        <Row>
                            <Col>
                                <Row><H4 key={index}>
                                    {subpodTitle}
                                </H4></Row>
                                {subpod.states && <Text>Other states: {renderSubpodStates}</Text>}
                                {/*TODO make those image ease in out*/}
                                <Row><Img src={subpodImage}
                                          height={height}
                                          width={width}
                                          key={subpodImage}
                                          loader={<Loader/>}
                                          unloader={<Text>Image not found</Text>}
                                          style={{animation: "slideIn 1s forwards"}}
                                /></Row>
                            </Col>
                            <Col xs={12}>
                                <Row end={"xs"}>
                                    <Col xs={6}><ImageActions subpod={subpod}/></Col>
                                </Row>
                            </Col>
                        </Row></Grid>
                )
            })
            return (
                <Panel
                    key={index}>
                    <H3>
                        <Text>{pod.title}</Text>
                    </H3>
                    {pod.states && <Text>Other states: {renderStates}</Text>}
                    {subpodRender}
                </Panel>
            )
        })
        return renderPods;


    }

    /*

     */
    /**
     * @function
     */
    function renderAssumptions() {
        const queryResult = state.queryResult;
        // console.log("query result", queryResult)
        const query = queryResult.inputstring;
        if (queryResult.success === false) return
        let assumptionRender = null;


        const simpleTypes = ["Clash", "MultiClash", "SubCategory", "SubCategory", "Attribute"
            , "Unit", "AngleUnit", "Function", "TimeAMOrPM", "DateOrder",
            "MortalityYearDOB", "ListOrTimes", "ListOrNumber", "CoordinateSystem",
            "I", "NumberBase", "MixedFraction", "TideStation"]
        if (queryResult.assumptions) {
            if (Array.isArray(queryResult.assumptions)) {
                const assumptionArray = queryResult.assumptions;
                assumptionRender = assumptionArray.map((assumptions, index) => {
                    const type = assumptions.type;
                    // console.log(assumptions)
                    if (simpleTypes.includes(type)) {
                        const descriptions = assumptions.values.map((assumption) => assumption.desc);
                        const inputs = assumptions.values.map((assumption) => assumption.input);
                        const selectedData = descriptions.map((description, index) => ({
                                label: description,
                                input: inputs[index],
                                key: index,
                            })
                        )
                        const menuItemRender = selectedData.splice(1).map((data) => {
                            return (
                                <MenuItem key={data.key}
                                          onClick={() => {
                                              sendQueryToBackGround(query, data.input)
                                          }}>
                                    {data.label}
                                </MenuItem>
                            )
                        })
                        return (
                            <p>
                                Assuming <Link>{selectedData[0].label}</Link>, other assumptions
                                <Menu
                                    closeOnClick={true}
                                >
                                    <SubMenu label={type}>
                                        {menuItemRender}
                                    </SubMenu>

                                </Menu>
                            </p>
                        )


                    }
                })
            } else if (queryResult.assumptions.values !== undefined) {
                const assumptions = queryResult.assumptions.values;
                const assumptionsType = queryResult.assumptions.type;
                const descriptions = assumptions.map((assumption) => assumption.desc);
                const inputs = assumptions.map((assumption) => assumption.input);
                const selectedData = descriptions.map((description, index) => ({
                    label: description,
                    input: inputs[index],
                    key: index,
                }))
                const menuItemRender = selectedData.splice(1).map((data) => {
                    return (
                        <MenuItem

                            key={data.key}
                            onClick={() => {
                                sendQueryToBackGround(query, data.input)
                            }}>
                            {data.label}
                        </MenuItem>
                    )
                })
                assumptionRender = (
                    <p>
                        Assuming <Link>{selectedData[0].label}</Link>, other assumptions
                        <Menu
                            closeOnClick={true}
                        >

                            {menuItemRender}

                        </Menu></p>)


            }
        }
        return (
            <Panel>
                {assumptionRender}
            </Panel>
        )


    }


    /**
     *
     * @type {number}
     */
    const windowHeight = window.innerHeight;
    /**
     *
     * @type {number}
     */
    const sidebarHeightWithoutHeader = windowHeight - 64;

    return (
        <div>
            <DraggableButton
                title={"Wisdoom!!!!!"}
                onStart={onDragStart} onStop={onDragStop} state={state}/>
            {/*TODO make the header in sidebar sticky*/}
            <Sidebar
                defaultCollapsed={true}
                collapsedWidth={0}
                width={"50%"}
                // white
                backgroundColor={"#ffffff"}
                style={{
                    position: "fixed",
                    bottom: 0,
                    right: 0,
                    height: sidebarHeightWithoutHeader,
                    // set right border visible
                    border: "1px solid #e0e0e0",
                }}>
                <Island
                    style={{
                        position: "sticky",
                        border: "none", boxShadow: "none",
                    }}
                >
                    {/*How to make this header sticky*/}
                    <KnowledgeDashBoardHeader onClick={() => {
                        toggleSideBar()
                    }} state={state} onClick1={() => {
                        setState({...state, currentView: "WolframAlpha"})
                    }} onClick2={(e) => {
                        setState({...state, currentView: "Settings"});
                    }}/>

                    {isUsingDemoApi && <Panel><Text>
                        Using demo api. Only some queries like "Weather" work!. Go to <Link
                        onClick={() => {
                            setState({...state, currentView: "Settings"})
                        }
                        }
                        active={false}>settings</Link> to add your own api key. Get your api key
                        from <Link
                        href={"https://developer.wolframalpha.com/portal/myapps/"}>here</Link>
                    </Text></Panel>
                    }
                    {/*Setting view*/}
                    {state.currentView === "Settings" &&
                        <SettingsView
                        />
                    }

                    {state.currentView === "WolframAlpha" &&
                        <div
                            style={{
                                marginLeft: "5%",
                                marginRight: "5%",
                                marginBottom: "5%",
                                backgroundColor: "rgb(0,0,0,0)", border: "none", boxShadow: "none"

                            }}
                        >
                            <WolframAlphaSearchArea onKeyDown={(e) => {
                                if (e.key === 'Enter') {
                                    sendQueryToBackGround(e.target.value, "", true, "")
                                }
                            }} onClick={() => {
                                sendQueryToBackGround(document.getElementById("wolframQueryInput").value,
                                    "", true, "")

                            }}


                            />
                            {/*{state.loadingResult === false ?
                                renderAssumptions() : <LoaderScreen
                                    message={"Inject Wis-doom everywhere"}/>}*/}
                            {currentPageReadability &&
                                <Panel>
                                    {renderEntities()}

                                </Panel>
                            }
                            {renderAssumptions()}
                            {renderPods()}

                        </div>
                    }
                </Island>
            </Sidebar>


        </div>
    )
}