import React, {MutableRefObject, useEffect} from 'react'
import {
    Center,
    Divider,
    Drawer,
    DrawerBody,
    DrawerCloseButton,
    DrawerContent,
    DrawerFooter,
    DrawerHeader,
    DrawerOverlay, Flex,
    Heading, Spacer,
    Text,
} from '@chakra-ui/react'
import AdminMode from './authComponents/AdminMode'
import {StateMethods, useHookstate} from '@hookstate/core'
import {tagState} from '../stateManagement/tagState'
import {
    controllerValues,
    osValues,
    playStatusValues, ratingStateValues,
    ratingValues,
    wineIntelValues,
    yesNo
} from '../componentUtils/SelectValues'
import {retrieveTags} from '../componentUtils/retrieveTags'
import {gameDashboardState} from '../stateManagement/gameState'
import {Select} from 'chakra-react-select'
import getWithFilters from '../componentUtils/getWithFilters'
import {loadingState, showFiltersModuleState} from '../stateManagement/loadingState'
import {adminMode} from '../stateManagement/userState'
import ResetFilterButton from "./helperComponents/ResetFilterButton";
import {ChangeActiveFilterHeader} from "../componentUtils/changeActiveFilterHeader";
import {ratingState, steamRatingState} from "../stateManagement/ratingState";

interface Props {
    filterIsOpen: boolean
    filterOnClose: () => void
    btnRef: MutableRefObject<null>
    filterLoadingState: StateMethods<boolean, any>
}

function FilterBar({filterIsOpen, filterOnClose, btnRef}: Props) {
    const gameState = useHookstate(gameDashboardState)
    const games = gameState.get()
    const {filters, searchParams} = games
    const setShowFiltersModuleState = useHookstate(showFiltersModuleState)
    const loadedState = useHookstate(loadingState)
    const admin = useHookstate(adminMode).get()
    const tagsState = useHookstate(tagState)
    const tags = tagsState.get()
    const setRatingState = useHookstate(ratingState)
    const useRatingState = setRatingState.get()
    const setSteamRatingState = useHookstate(steamRatingState)
    const useSteamRatingState = setSteamRatingState.get()

    const getTags = () => {
        if (tags.developer.length < 2) return retrieveTags()
        else return
    }

    useEffect(() => {
        return () => {
            getTags()
        }
    }, [tags.developer])

    const filterToSelectDefaultValue = (filterName: string) => {
        if (filters[filterName as keyof typeof filters] === "") return
        return filters[filterName as keyof typeof filters].split(',').map(value => {
            return {label: value, value: value}
        })
    }

    const ratingToSelectDefaultValue = (value: string) => {
        let label: string = '='
        if (value === "") return
        if (value === "[lte]") label = '<='
        if (value === "[gte]") label = '>='
        return { label, value }
    }

    const changeFilters = async (filterName: string, value: string) => {
        const finalFilter = {...filters, [filterName]: value}

        await ChangeActiveFilterHeader(finalFilter, searchParams, setShowFiltersModuleState)

        return await getWithFilters(
            gameState,
            loadedState,
            admin,
            games.count.currentPage,
            games.count.limit,
            games.searchParams,
            finalFilter,
            useRatingState,
            useSteamRatingState
        )
    }

    return (
        <Drawer
            isOpen={filterIsOpen}
            placement="right"
            onClose={filterOnClose}
            finalFocusRef={btnRef}
        >
            <DrawerOverlay/>
            <DrawerContent>
                <DrawerCloseButton/>
                <DrawerHeader>
                    <Heading as={'h3'}>Filters</Heading>
                </DrawerHeader>

                <DrawerBody>
                    <AdminMode/>
                    <Divider my={'3'}/>
                    <Center>
                        <ResetFilterButton/>
                    </Center>
                    <Divider my={'3'}/>
                    <Text mb={'1'} fontSize={'xl'}>Series</Text>
                    <Select
                        size={'sm'}
                        defaultValue={filterToSelectDefaultValue("series")}
                        isClearable
                        isMulti
                        name="series"
                        onChange={(event) => {
                            const value = event.map(a => a.value).join(',')
                            changeFilters("series", value)
                        }}
                        options={tags.series}
                    />
                    <Divider my={'3'}/>
                    <Flex mb={'1'}>
                        <Text mb={'1'} fontSize={'xl'}>Rating</Text>
                        <Spacer />
                        <Select
                            size={'sm'}
                            defaultValue={ratingToSelectDefaultValue(useRatingState)}
                            name="rating"
                            onChange={(event) => {
                                if (event === null) return
                                setRatingState.set(event.value)
                            }}
                            options={ratingStateValues}
                            chakraStyles={{
                                container: (provided) => ({
                                    ...provided,
                                    width: "75px"
                                })
                            }}
                        />
                    </Flex>
                    <Select
                        size={'sm'}
                        defaultValue={filterToSelectDefaultValue("rating")}
                        isClearable
                        name="rating"
                        onChange={(event) => {
                            if(event === null) return changeFilters("rating", "")
                            changeFilters("rating", event.value)
                        }}
                        options={ratingValues}
                    />
                    <Divider my={'1'}/>
                    <Flex mb={'1'}>
                        <Text mb={'1'} fontSize={'xl'}>Steam Rating</Text>
                        <Spacer />
                        <Select
                            size={'sm'}
                            defaultValue={ratingToSelectDefaultValue(useSteamRatingState)}
                            name="steamRating"
                            onChange={(event) => {
                                if (event === null) return
                                setSteamRatingState.set(event.value)
                            }}
                            options={ratingStateValues}
                            chakraStyles={{
                                container: (provided) => ({
                                    ...provided,
                                    width: "75px"
                                })
                            }}
                        />
                    </Flex>
                    <Select
                        size={'sm'}
                        defaultValue={filterToSelectDefaultValue("steamRating")}
                        isClearable
                        name="steamRating"
                        onChange={(event) => {
                            if(event === null) return changeFilters("steamRating", "")
                            changeFilters("steamRating", event.value)
                        }}
                        options={ratingValues}
                    />
                    <Divider my={'1'}/>
                    <Text mb={'1'} fontSize={'xl'}>Play Status</Text>
                    <Select
                        size={'sm'}
                        defaultValue={filterToSelectDefaultValue("playStatus")}
                        isClearable
                        isMulti
                        name="playStatus"
                        onChange={(event) => {
                            const value = event.map(a => a.value).join(',')
                            changeFilters("playStatus", value)
                        }}
                        options={playStatusValues}
                    />
                    <Divider my={'1'}/>
                    <Text mb={'1'} fontSize={'xl'}>Genres</Text>
                    <Select
                        size={'sm'}
                        defaultValue={filterToSelectDefaultValue("genre")}
                        isClearable
                        isMulti
                        name="genre"
                        onChange={(event) => {
                            const value = event.map(a => a.value).join(',')
                            changeFilters("genre", value)
                        }}
                        options={tags.genres}
                    />
                    <Divider my={'1'}/>
                    <Text mb={'1'} fontSize={'xl'}>Operating System</Text>
                    <Select
                        size={'sm'}
                        defaultValue={filterToSelectDefaultValue("os")}
                        isClearable
                        isMulti
                        name="os"
                        onChange={(event) => {
                            const value = event.map(a => a.value).join(',')
                            changeFilters("os", value)
                        }}
                        options={osValues}
                    />
                    <Divider my={'1'}/>
                    <Text mb={'1'} fontSize={'xl'}>Store</Text>
                    <Select
                        size={'sm'}
                        defaultValue={filterToSelectDefaultValue("store")}
                        isClearable
                        isMulti
                        name="store"
                        onChange={(event) => {
                            const value = event.map(a => a.value).join(',')
                            changeFilters("store", value)
                        }}
                        options={tags.store}
                    />
                    <Divider my={'1'}/>
                    <Text mb={'1'} fontSize={'xl'}>Controller Support</Text>
                    <Select
                        size={'sm'}
                        defaultValue={filterToSelectDefaultValue("controller")}
                        isClearable
                        isMulti
                        name="controller"
                        onChange={(event) => {
                            const value = event.map(a => a.value).join(',')
                            changeFilters("controller", value)
                        }}
                        options={controllerValues}
                    />
                    <Divider my={'1'}/>
                    <Text mb={'1'} fontSize={'xl'}>Developer</Text>
                    <Select
                        size={'sm'}
                        defaultValue={filterToSelectDefaultValue("developer")}
                        isClearable
                        isMulti
                        name="developer"
                        onChange={(event) => {
                            const value = event.map(a => a.value).join(',')
                            changeFilters("developer", value)
                        }}
                        options={tags.developer}
                    />
                    <Divider my={'1'}/>
                    <Text mb={'1'} fontSize={'xl'}>Publisher</Text>
                    <Select
                        size={'sm'}
                        defaultValue={filterToSelectDefaultValue("publisher")}
                        isClearable
                        isMulti
                        name="publisher"
                        onChange={(event) => {
                            const value = event.map(a => a.value).join(',')
                            changeFilters("publisher", value)
                        }}
                        options={tags.publisher}
                    />
                    <Divider my={'1'}/>
                    <Text mb={'1'} fontSize={'xl'}>Do you own the Soundtrack?</Text>
                    <Select
                        size={'sm'}
                        defaultValue={filterToSelectDefaultValue("soundtrack")}
                        isClearable
                        isMulti
                        name="soundtrack"
                        onChange={(event) => {
                            const value = event.map(a => a.value).join(',')
                            changeFilters("soundtrack", value)
                        }}
                        options={yesNo}
                    />
                    <Divider my={'1'}/>
                    <Text mb={'1'} fontSize={'xl'}>Does in work on Intel?</Text>
                    <Select
                        size={'sm'}
                        defaultValue={filterToSelectDefaultValue("intel")}
                        isClearable
                        isMulti
                        name="intel"
                        onChange={(event) => {
                            const value = event.map(a => a.value).join(',')
                            changeFilters("intel", value)
                        }}
                        options={wineIntelValues}
                    />
                    <Divider my={'1'}/>
                    <Text mb={'1'} fontSize={'xl'}>Does is work with Wine?</Text>
                    <Select
                        size={'sm'}
                        defaultValue={filterToSelectDefaultValue("wine")}
                        isClearable
                        isMulti
                        name="wine"
                        onChange={(event) => {
                            const value = event.map(a => a.value).join(',')
                            changeFilters("wine", value)
                        }}
                        options={wineIntelValues}
                    />
                    <Divider my={'1'}/>
                </DrawerBody>

                <DrawerFooter>

                </DrawerFooter>
            </DrawerContent>
        </Drawer>
    )
}

export default FilterBar