import React, {FC, Dispatch, SetStateAction, useEffect, useState} from "react"
import PageLayout from "../components/PageLayout"
import useAxiosTools from "../hooks/AxiosTools"
import {WeatherValue} from "../types"
import Card from "../components/Card"
import Img from "../components/Img"

const Weather = () => {

    const [currentWeather, setCurrentWeather] = useState<WeatherValue | null>(null)
    const [fetchTime, setFetchTime] = useState(0)
    const [weatherDays, setWeatherDays] = useState<[string, WeatherValue[]][] | null>(null)
    const {loading, setLoading, errorLabel, errorCatch, cleanErrors, axiosGet} = useAxiosTools()

    useEffect(() => {
        const timer = setInterval(() => {
            if (!loading && (fetchTime + 5 * 60) < getCurrentTime()) {
                fetchWeather()
            }
        }, 1000)
        return () => clearInterval(timer)
    }, [fetchTime])

    const getCurrentTime = () => Number(((new Date).getTime() / 1000).toFixed())

    const fetchWeather = async () => {
        try {
            setLoading(true)
            cleanErrors()
            const res = await axiosGet(`/api/weather`)
            const currentWeather = res.data.list[0]

            const weatherDays: [string, WeatherValue[]][] = []
            let objectEntries = {index: -1, date: ''}
            res.data.list.forEach((item: WeatherValue) => {
                const date = item.dt_txt.split(' ')[0]

                if (date === (new Date).toSQLDate()) {
                    if (currentWeather.main.temp_min > item.main.temp_min) {
                        currentWeather.main.temp_min = item.main.temp_min
                    }
                    if (currentWeather.main.temp_max < item.main.temp_max) {
                        currentWeather.main.temp_max = item.main.temp_max
                    }
                }

                if (date !== objectEntries.date) {
                    objectEntries = {index: objectEntries.index + 1, date}
                }

                if (!weatherDays[objectEntries.index]) {
                    weatherDays[objectEntries.index] = [date, []]
                }

                weatherDays[objectEntries.index][1] = [...weatherDays[objectEntries.index][1], item]
            })
            setWeatherDays(weatherDays)
            setCurrentWeather(currentWeather)
            setFetchTime(getCurrentTime())
        } catch (e) {
            errorCatch(e)
        } finally {
            setLoading(false)
        }
    }

    return <PageLayout>

        {errorLabel()}

        <Card className={`flex justify-between ${loading ? 'animate-pulse' : ''}`}>
            <div className="m-2 flex flex-col justify-between">
                <span className="text-6xl">{currentWeather?.main.temp.toFixed() ?? '--'} °C</span>
                <span
                    className="text-secondary dark:text-secondary-ligth">{currentWeather?.weather[0].description}</span>
            </div>
            <div className="flex items-stretch">
                <div>
                    {/*{currentWeather && <img src={`http://openweathermap.org/img/wn/${currentWeather?.weather[0].icon}@2x.png`}*/}
                    {/*     alt={currentWeather?.weather[0].main} width="120px" />}*/}
                    {currentWeather && <Img src={`images/icons/${currentWeather?.weather[0].icon}.svg`}
                                            alt={currentWeather?.weather[0].main} width="120px"/>}
                </div>
                <div className="flex flex-col gap-1">
                    <span className="pt-5 text-4xl">{currentWeather?.main.temp_max.toFixed() ?? '--'} <span
                        className="text-2xl">°C</span></span>
                    <span
                        className="mt-2 text-2xl text-secondary dark:text-secondary-ligth">{currentWeather?.main.temp_min.toFixed() ?? '--'} °C</span>
                </div>
            </div>
        </Card>
        <div className="m-3">
            {weatherDays?.filter(([date]) => date !== (new Date).toSQLDate())
                .map(([date, values]) => <WeatherCard key={date} date={date} values={values}/>)}
        </div>
    </PageLayout>
}

export default Weather

const WeatherCard: FC<{ date: string, values: WeatherValue[] }> = ({date, values = []}) => {

    const [weatherState, setWeatherState] = useState<{
        main: string,
        description: string,
        icon: string,
        min: number,
        max: number
    } | null>(null)
    const [showDetails, setShowDetails] = useState(false)

    useEffect(() => {
        console.log(values)
        const weatherState = {
            min: 100,
            max: -100,
            main: '',
            icon: '',
            description: '',
        }
        const result: Record<string, number> = {}
        values.forEach(value => {
            if (value.main.temp_min < weatherState.min) {
                weatherState.min = value.main.temp_min
            }
            if (value.main.temp_max > weatherState.max) {
                weatherState.max = value.main.temp_max
            }

            const tag = value.weather[0].main
            if (!result[tag]) {
                result[tag] = 0
            }
            result[tag]++
        })

        let itemToReturn: { name: string, value: number } | null = null
        for (const item in result) {
            if (!itemToReturn || itemToReturn.value < result[item]) {
                itemToReturn = {name: item, value: result[item]}
            }
        }

        if (itemToReturn && itemToReturn.name) {
            const nameToSearch = itemToReturn.name
            const value = values.find(item => item.weather[0].main === nameToSearch)
            if (value) {
                weatherState.main = itemToReturn.name
                weatherState.description = value.weather[0].description
                weatherState.icon = value.weather[0].icon.replace('n', 'd')
                setWeatherState(weatherState)
            }
        }
    }, [])

    return <>
        <div className="flex gap-5" onClick={(() => setShowDetails(!showDetails))}>
            <div className="flex h-full flex-1 flex-col gap-2">
                <span className="text-lg font-bold"
                      title={(new Date(date)).toLocaleDateString()}>{(new Date(date)).getWeekDay()}</span>
                <span className="text-secondary dark:text-secondary-ligth">{weatherState?.description}</span>
            </div>
            <div className="-mt-1.5 flex items-center">
                <Img src={`images/icons/${weatherState?.icon}.svg`}
                     alt={weatherState?.main + ' ' + weatherState?.icon}
                     width="80px"/>

            </div>
            <div className="flex flex-col gap-1">
                <span className="text-lg">{weatherState?.max.toFixed()} °C</span>
                <span className="text-secondary dark:text-secondary-ligth">{weatherState?.min.toFixed()} °C</span>
            </div>
        </div>
        <WeatherDetails showDetails={showDetails} closeDetails={() => showDetails(false)} values={values}/>
    </>
}

const WeatherDetails: FC<WeatherDetailsProps> = ({showDetails, closeDetails, values}) => {

    return <ul onClick={closeDetails}
               className={`${showDetails ? 'h-44 opacity-100' : 'h-0 opacity-0'} flex gap-2 overflow-hidden overflow-x-auto transition-all`}>
        {values.map(value => <li key={value.dt} className="w-40">
            <div className="text-center">{Number(value.dt_txt.split(' ')[1].split(':')[0])} h</div>
            <div>
                <Img src={`images/icons/${value.weather[0].icon.replace('n', 'd')}.svg`}
                     alt={value.weather[0].description}
                     width="80px"/>
            </div>
            <div className="text-center">
                <span className="font-bold">
                    {value.main.temp}
                </span> °C
            </div>
            {value.weather[0].description}
        </li>)}
    </ul>
}

interface WeatherDetailsProps {
    showDetails: boolean,
    closeDetails: Dispatch<SetStateAction<boolean>>,
    values: WeatherValue[],
}
