// /*Copyright (C) 2019 Centro de Computacao Cientifica e Software Livre
// Departamento de Informatica - Universidade Federal do Parana

// This file is part of Plataforma Integrada MEC.

// Plataforma Integrada MEC is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// Plataforma Integrada MEC is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.

// You should have received a copy of the GNU Affero General Public License
// along with Plataforma Integrada MEC.  If not, see <http://www.gnu.org/licenses/>.*/ 


import React, { useEffect, useState, Fragment, useContext } from 'react';
import styled from 'styled-components';
import { Link } from 'react-router-dom';
import Breadcrumbs from '@material-ui/core/Breadcrumbs';
import HeaderFilters from '../Components/SearchPageComponents/HeaderFilters';
import ResourceTemplate from '../Components/SearchPageComponents/ResourceTemplate';
import CollectionTemplate from '../Components/SearchPageComponents/CollectionTemplate';
import UserTemplate from '../Components/SearchPageComponents/UserTemplate';
import Error from '../Components/SearchPageComponents/Error';
import { getRequest } from '../Components/HelperFunctions/getAxiosConfig';
import { useHistory } from 'react-router-dom';
import SearchExpansionPanel from '../Components/SearchExpansionPanel/SearchExpansionPanel';
import FilterSummary from '../Components/SearchPageComponents/FilterSummary';
import {
    filtersCurriculum,
    filtersTypes,
    filtersStages,
    filtersLanguages,
} from '../Components/SearchPageComponents/filters';
import { Store } from '../Store'

import SnackBar from '../Components/SnackbarComponent';

export default function Search() {
    const history = useHistory();
    const { state } = useContext(Store)

    const [currOption, setCurrOption] = useState('');
    const [currOrder, serCurrOrder] = useState('review_average');
    const [currQuery, setCurrQuery] = useState('');
    const [currPage, setCurrPage] = useState(0);
    const [currCurriculumValues, setCurrCurriculumValues] = useState('');
    const [currTypeOfResValues, setCurrTypeOfResValues] = useState('');
    const [currTeachingStageValues, setCurrTeachingStageValues] = useState('');
    const [currLanguagesValues, setCurrLanguagesValues] = useState('');
    const [currTag, setCurrTag] = useState('');
    const [isLoading, setIsLoading] = useState(false);
    const [error, setError] = useState(false);
    const [snackInfo, setSnackInfo] = useState({
        open: false,
        text: "",
        severity: "",
    });

    const [curriculumComponents, setCurriculumComponents] = useState([]);
    const [typeOfResources, setTypeOfResources] = useState([]);
    const [teachingStage, setTeachingStage] = useState([]);
    const [languages, setLanguages] = useState([]);
    const [tag, setTag] = useState('');

    const [resourcesArray, setResourcesArray] = useState([]);
    const [totalResources, setTotalResources] = useState(0);

    const [collectionsArray, setCollectionsArray] = useState([])
    const [totalCollections, setTotalCollections] = useState(0);

    const [usersArray, setUsersArray] = useState([])
    const [totalUsers, setTotalUsers] = useState(0);

    const options = [
        { value: 'Recursos', name: 'LearningObject', color: state.contrast === "" ? '#ff7f00' : "yellow" },
        { value: 'Coleções', name: 'Collection', color: state.contrast === "" ? '#673ab7' : "yellow" },
        { value: 'Usuários', name: 'User', color: state.contrast === "" ? '#00bcd4' : "yellow" },
    ];

    const orders = [
        { value: 'Mais Estrelas', name: 'review_average', color: state.contrast === "" ? '#ff7f00' : "yellow" },
        { value: 'Mais Relevante', name: 'score', color: state.contrast === "" ? '#ff7f00' : "yellow" },
        { value: 'Mais Baixados', name: 'downloads', color: state.contrast === "" ? '#ff7f00' : "yellow" },
        { value: 'Mais Favoritados', name: 'likes', color: state.contrast === "" ? '#ff7f00' : "yellow" },
        { value: 'Mais Recentes', name: 'publicationdesc', color: state.contrast === "" ? '#ff7f00' : "yellow" },
        { value: 'Ordem Alfabética', name: 'title', color: state.contrast === "" ? '#ff7f00' : "yellow" },
    ];

    function handleSnackInfo(info) {
        setSnackInfo({ ...info })
    }

    function handleCloseSnack() {
        const snackInfo = {
            open: false,
            text: "",
            severity: "",
        }
        handleSnackInfo(snackInfo)
    }

    function onButtonClicked() {
        const curriculumValues = [];
        const typeOfResourcesValues = [];
        const teachingStageValues = [];
        const languagesValues = [];

        for (let index = 0; index < curriculumComponents.length; index++) {
            const element = curriculumComponents[index];
            if (element.isChecked)
                curriculumValues.push(element.value);
        }

        for (let index = 0; index < typeOfResources.length; index++) {
            const element = typeOfResources[index];
            if (element.isChecked)
                typeOfResourcesValues.push(element.value);
        }

        for (let index = 0; index < teachingStage.length; index++) {
            const element = teachingStage[index];
            if (element.isChecked)
                teachingStageValues.push(element.value);
        }

        for (let index = 0; index < languages.length; index++) {
            const element = languages[index];
            if (element.isChecked)
                languagesValues.push(element.value);
        }

        let url = `/busca?page=0&results_per_page=12&query=${currQuery}&search_class=${currOption}`

        if (currOption !== 'User') {
            url = url + `&order=${currOrder}`
            if (currOption === 'LearningObject') {
                if (curriculumValues.length >= 1) {
                    url = url + `&subjects=${curriculumValues}`
                }
                if (typeOfResourcesValues.length >= 1) {
                    url = url + `&object_types=${typeOfResourcesValues}`
                }
                if (teachingStageValues.length >= 1) {
                    url = url + `&educational_stages=${teachingStageValues}`
                }
                if (languagesValues.length >= 1) {
                    url = url + `&languages=${languagesValues}`
                }
                if (tag && tag.length >= 1)
                    url = url + `&tags=${tag}`
            }
        }

        history.push(url);
    }

    function resetFilters() {
        for (let index = 0; index < filtersCurriculum.length; index++) {
            if (filtersCurriculum[index].isChecked)
                filtersCurriculum[index].isChecked = false;
        }
        for (let index = 0; index < filtersLanguages.length; index++) {
            if (filtersLanguages[index].isChecked)
                filtersLanguages[index].isChecked = false;
        }
        for (let index = 0; index < filtersStages.length; index++) {
            if (filtersStages[index].isChecked)
                filtersStages[index].isChecked = false;
        }
        for (let index = 0; index < filtersTypes.length; index++) {
            if (filtersTypes[index].isChecked)
                filtersTypes[index].isChecked = false;
        }
        setTag('')
    }

    function handleChangeOption(e) {
        const value = e.target.value;
        let url;

        if (value !== 'User')
            url = `/busca?page=0&results_per_page=12&order=review_average&query=${currQuery}&search_class=${value}`
        else
            url = `/busca?page=0&results_per_page=12&query=${currQuery}&search_class=${value}`

        resetFilters()
        history.push(url);
    }

    function handleChangeOrder(e) {
        const value = e.target.value;
        let url = `/busca?page=0&results_per_page=12&query=${currQuery}&search_class=${currOption}`

        if (currOption !== 'User') {
            url = url + `&order=${value}`
            if (currOption === 'LearningObject') {
                if (currCurriculumValues) {
                    url = url + `&subjects=${currCurriculumValues}`
                }
                if (currTypeOfResValues) {
                    url = url + `&object_types=${currTypeOfResValues}`
                }
                if (currTeachingStageValues) {
                    url = url + `&educational_stages=${currTeachingStageValues}`
                }
                if (currLanguagesValues) {
                    url = url + `&languages=${currLanguagesValues}`
                }
                if (currTag)
                    url = url + `&tags=${currTag}`
            }
        }

        history.push(url);
    }

    function handleNextPage() {
        const nextPage = currPage + 1;
        let url = `/busca?page=${nextPage}&results_per_page=12&query=${currQuery}&search_class=${currOption}`

        if (currOption !== 'User') {
            url = url + `&order=${currOrder}`
            if (currOption === 'LearningObject') {
                if (currCurriculumValues) {
                    url = url + `&subjects=${currCurriculumValues}`
                }
                if (currTypeOfResValues) {
                    url = url + `&object_types=${currTypeOfResValues}`
                }
                if (currTeachingStageValues) {
                    url = url + `&educational_stages=${currTeachingStageValues}`
                }
                if (currLanguagesValues) {
                    url = url + `&languages=${currLanguagesValues}`
                }
                if (currTag)
                    url = url + `&tags=${currTag}`
            }
        }
        history.push(url);
    }

    function handlePreviousPage() {
        const previousPage = currPage - 1;
        let url = `/busca?page=${previousPage}&results_per_page=12&query=${currQuery}&search_class=${currOption}`

        if (currOption !== 'User') {
            url = url + `&order=${currOrder}`
            if (currOption === 'LearningObject') {
                if (currCurriculumValues) {
                    url = url + `&subjects=${currCurriculumValues}`
                }
                if (currTypeOfResValues) {
                    url = url + `&object_types=${currTypeOfResValues}`
                }
                if (currTeachingStageValues) {
                    url = url + `&educational_stages=${currTeachingStageValues}`
                }
                if (currLanguagesValues) {
                    url = url + `&languages=${currLanguagesValues}`
                }
                if (currTag)
                    url = url + `&tags=${currTag}`
            }
        }
        history.push(url);
    }

    function handleSuccess(data, headers, option) {
        if (option === 'LearningObject') {
            setResourcesArray(data)
            if (headers.has('X-Total-Count')) {
                setTotalResources(headers.get('X-Total-Count'));
            }
        }
        else if (option === 'Collection') {
            setCollectionsArray(data)
            if (headers.has('X-Total-Count')) {
                setTotalCollections(headers.get('X-Total-Count'));
            }
        }
        else {
            setUsersArray(data);
            if (headers.has('X-Total-Count')) {
                setTotalUsers(headers.get('X-Total-Count'));
            }
        }
        setIsLoading(false);
    }

    function handleFail() {
        const snackInfo = {
            open: true,
            text: "Houve um erro ao carregar os dados!",
            severity: "warning",
        }
        handleSnackInfo(snackInfo)
        setError(true);
        setIsLoading(false);
    }

    function handleSubjects(subjectsString) {
        if (subjectsString) {
            const selectedSubjects = subjectsString.split(',');
            for (let i = 0; i < selectedSubjects.length; i++) {
                const elementOfSelectedSubs = selectedSubjects[i];
                for (let j = 0; j < filtersCurriculum.length; j++) {
                    if (elementOfSelectedSubs === filtersCurriculum[j].value)
                        filtersCurriculum[j].isChecked = true;
                }
            }
        }
        setCurriculumComponents(filtersCurriculum);
    }

    function handleObjectTypes(objectTypesString) {
        if (objectTypesString) {
            const selectedObjectTypes = objectTypesString.split(',');
            for (let i = 0; i < selectedObjectTypes.length; i++) {
                const elementOfSelectedObjectTypes = selectedObjectTypes[i];
                for (let j = 0; j < filtersTypes.length; j++) {
                    if (elementOfSelectedObjectTypes === filtersTypes[j].value)
                        filtersTypes[j].isChecked = true;
                }
            }
        }
        setTypeOfResources(filtersTypes);
    }

    function handleLanguages(languagesString) {
        if (languagesString) {
            const selectedLanguages = languagesString.split(',');

            for (let i = 0; i < selectedLanguages.length; i++) {
                const elementOfSelectedLanguages = selectedLanguages[i];
                for (let j = 0; j < filtersLanguages.length; j++) {
                    if (elementOfSelectedLanguages === filtersLanguages[j].value)
                        filtersLanguages[j].isChecked = true;
                }
            }
        }
        setLanguages(filtersLanguages);
    }

    function handleStages(stagesString) {
        if (stagesString) {
            const selectedStages = stagesString.split(',');

            for (let i = 0; i < selectedStages.length; i++) {
                const elementOfSelectedStages = selectedStages[i];
                for (let j = 0; j < filtersStages.length; j++) {
                    if (elementOfSelectedStages === filtersStages[j].value)
                        filtersStages[j].isChecked = true;
                }
            }
        }
        setTeachingStage(filtersStages);
    }

    useEffect(() => {
        setIsLoading(true)

        var hashtagProblem=window.location.href.replace('#','/'); /*If there is a '#' on the search,replaces it with a '/' to avoid problems*/
        const urlParams = new URLSearchParams(hashtagProblem);
        const query = urlParams.get("query");
        const searchClass = urlParams.get("search_class");
        const page = parseInt(urlParams.get("page"));
        const order = urlParams.get("order");
        const subjects = urlParams.get("subjects");
        const objectTypes = urlParams.get("object_types");
        const educationalStages = urlParams.get("educational_stages");
        const languages = urlParams.get("languages");
        const tags = urlParams.get("tags");

        setCurrOption(searchClass);
        setCurrQuery(query);
        setCurrPage(page);
        serCurrOrder(order);
        setCurrCurriculumValues(subjects);
        setCurrLanguagesValues(languages);
        setCurrTeachingStageValues(educationalStages);
        setCurrTypeOfResValues(objectTypes);
        setCurrTag(tags);
        setTag(tags);

        handleSubjects(subjects);
        handleObjectTypes(objectTypes);
        handleStages(educationalStages);
        handleLanguages(languages);

        let url = `/search?page=${page}&results_per_page=12&query=${query}&search_class=${searchClass}`

        if (searchClass !== 'User') {
            url = url + `&order=${order}`
            if (searchClass === 'LearningObject') {
                if (subjects) {
                    url = url + `&subjects[]=${subjects}`
                }
                if (objectTypes) {
                    url = url + `&object_types[]=${objectTypes}`
                }
                if (educationalStages) {
                    url = url + `&educational_stages[]=${educationalStages}`
                }
                if (languages) {
                    url = url + `&languages[]=${languages}`
                }
                if (tags)
                    url = url + `&tags[]=${tags}`
            }
        }

        getRequest(
            url,
            (data, headers) => { handleSuccess(data, headers, searchClass) },
            handleFail,
        );

    }, [window.history.state === null ? true : window.history.state.key, state.currentUser.id])

    if (error)
        return (
            <div style={state.contrast === "" ? {} : { backgroundColor: "black" }}>
                <MainPageError>
                    <SnackBar
                        snackbarOpen={snackInfo.open}
                        handleClose={handleCloseSnack}
                        severity={snackInfo.severity}
                        text={snackInfo.text}
                    />
                    <Error contrast={state.contrast} />
                </MainPageError>
            </div>
        )
    else
        return (
            <div style={state.contrast === "" ? {} : { backgroundColor: "black" }}>
                <MainPage>
                    <SnackBar
                        snackbarOpen={snackInfo.open}
                        handleClose={handleCloseSnack}
                        severity={snackInfo.severity}
                        text={snackInfo.text}
                    />
                    <StyledBreadCrumbs contrast={state.contrast}>
                        <Link to='/'>Página Inicial</Link>
                        <span>Busca</span>
                    </StyledBreadCrumbs>
                    <HeaderFilters
                        contrast={state.contrast}
                        options={options}
                        orders={orders}
                        currOption={currOption}
                        currOrder={currOrder}
                        handleChangeOption={handleChangeOption}
                        handleChangeOrder={handleChangeOrder}
                    />
                    {
                        currOption === 'LearningObject' &&
                        <Fragment>
                            <SearchExpansionPanel
                                contrast={state.contrast}
                                setTag={(tag) => setTag(tag)}
                                curriculumComponents={curriculumComponents}
                                setCurriculum={(array) => { setCurriculumComponents(array) }}
                                typeOfResources={typeOfResources}
                                setTypeRes={(array) => { setTypeOfResources(array) }}
                                teachingStage={teachingStage}
                                setTeachingStage={(array) => { setTeachingStage(array) }}
                                languages={languages}
                                setLanguages={(array) => { setLanguages(array) }}
                            />
                            {
                                <FilterSummary
                                    contrast={state.contrast}
                                    curriculumComponents={curriculumComponents}
                                    typeOfResources={typeOfResources}
                                    languages={languages}
                                    teachingStage={teachingStage}
                                    tag={tag}
                                    onButtonClicked={onButtonClicked}
                                />
                            }
                            <ResourceTemplate
                                contrast={state.contrast}
                                handleNextPage={handleNextPage}
                                handlePreviousPage={handlePreviousPage}
                                isLoading={isLoading}
                                currPage={currPage}
                                resources={resourcesArray}
                                totalResources={totalResources}
                            />
                        </Fragment>
                    }
                    {
                        currOption === 'Collection' &&
                        <CollectionTemplate
                            contrast={state.contrast}
                            handleNextPage={handleNextPage}
                            handlePreviousPage={handlePreviousPage}
                            isLoading={isLoading}
                            currPage={currPage}
                            resources={collectionsArray}
                            totalResources={totalCollections}
                        />
                    }
                    {
                        currOption === 'User' &&
                        <UserTemplate
                            contrast={state.contrast}
                            handleNextPage={handleNextPage}
                            handlePreviousPage={handlePreviousPage}
                            isLoading={isLoading}
                            currPage={currPage}
                            resources={usersArray}
                            totalResources={totalUsers}
                        />
                    }
                </MainPage>
            </div>
        )
}

const MainPage = styled.div`  
    padding: 1em 0;
    width: 90%; 
    margin: 0 auto; 
`
const MainPageError = styled.div` 
    width: 90%;
    margin: 0 auto; 
    display: flex; 
    justify-content: center; 
    align-items: center; 
    padding: 1em; 
`
const StyledBreadCrumbs = styled(Breadcrumbs)`
    display: flex;
    justify-content: flex-start;
    span {
        color: ${props => props.contrast === "" ? "#a5a5a5" : "white"};
    }
    a {
        color: ${props => props.contrast === "" ? "#00bcd4" : "yellow"};
        text-decoration: ${props => props.contrast === "" ? "none" : "underline"};
    }
`;