import React, { ChangeEvent, useContext, useEffect, useState } from 'react'
import { useHistory } from 'react-router-dom'
import DatePicker from 'react-datepicker'
import { PageMarginLeftRight } from '../../style/PageMarginLeftRight'
import styled, { ThemeContext } from 'styled-components'
import { distance } from '../../style/sizes'
import { Bar, BarChart, CartesianGrid, Label, Legend, ResponsiveContainer, Tooltip, XAxis, YAxis } from 'recharts'
import { chartColors } from '../../style/chartColors'
import 'react-datepicker/dist/react-datepicker.css'
import Input from '../../components/input/Input'
import { InputWithLabel } from '../../components/inputWithLabel/InputWithLabel'
import { ChartInfoBox } from '../../components/chartInfoBox/ChartInfoBox'
import Button from '../../components/button/Button'
import Select from 'components/select/Select'
import { ClipLoader } from 'react-spinners'
import logo from './../../pictures/SantanderCyclesLogo.png';

interface IBikeTripDurationCount {
    classLabel: string,
    count: number
}

/**
 * Landing page of our dashboard.
 * Contains non-map visualizations.
 * Also contains link to access bike sharing map of London.
 */
export const Home = () => {
    const history = useHistory()

    const [startTimeStamp, setStartTimestamp] = useState(Date.UTC(2015, 0, 4, 0, 5))
    const [endTimeStamp, setEndTimeStamp] = useState(Date.UTC(2015, 0, 19, 0, 10))
    const [classSize, setClassSize] = useState(300)

    const [tripDurationData, setTripDurationData] = useState<IBikeTripDurationCount[] | undefined>(undefined)

    const [loadingState, setLoadingState] = useState(false)

    // fetch data from our server once at beginning, later only on button click
    useEffect(() => {fetchData()}, [])

    const fetchData = async () => {
        setLoadingState(true)
        const response = await fetch(`http://localhost:8081/api/bike-trip-durations?classSize=${classSize}&from=${startTimeStamp / 1000}&to=${endTimeStamp / 1000}`)
        const jsonResponse = await response.json()
        setTripDurationData(jsonResponse.bikeTripDurationCounts)
        setLoadingState(false)
    }

    return (
        <PageMarginLeftRight>
            <StyledTopRow>
            <div><Button onClick={() => history.push('/map')}>To map</Button></div>
            <img src={logo} alt='Logo' height='75' />
            </StyledTopRow>
            <StyledRow>
            <h2>Bike-sharing in London</h2>
            </StyledRow>
            <StyledRow>
                <div>
                <ChartInfoBox bold={true} description={'This bar chart shows the count of trips with similar durations within the selected timerange. The bars represent the number of trips.'}>
                    <StyledRow>
                        <InputWithLabel label={'Class Size'}> 
                            <Select defaultValue='300' onChange={(event: ChangeEvent<HTMLSelectElement>) => setClassSize(Number(event.target.value))}>
                                <option value='60'>1 minute</option>
                                <option value='300'>5 minutes</option>
                                <option value='600'>10 minutes</option>
                                <option value='1200'>20 minutes</option>
                                <option value='1800'>30 minutes</option>
                            </Select>
                        </InputWithLabel>
                    </StyledRow>
                    <StyledRow>
                        <InputWithLabel label={'From'}>
                            <DatePicker
                                selected={new Date(startTimeStamp)}
                                onChange={(date: Date) => setStartTimestamp(date.getTime())}
                                dateFormat='yyyy/MM/dd, HH:mm'
                                showTimeSelect
                                timeFormat='HH:mm'
                                timeIntervals={5}
                                customInput={<Input />}
                            />
                        </InputWithLabel>
                        <InputWithLabel label={'To'}>
                            <DatePicker
                                selected={new Date(endTimeStamp)}
                                onChange={(date: Date) => setEndTimeStamp(date.getTime())}
                                dateFormat='yyyy/MM/dd, HH:mm'
                                showTimeSelect
                                timeFormat='HH:mm'
                                timeIntervals={5}
                                customInput={<Input />}
                            />
                        </InputWithLabel>
                    </StyledRow>
                    <StyledRow>
                        <Button onClick={fetchData}>Apply Options</Button>&nbsp;&nbsp;&nbsp;{loadingState && <ClipLoader color={'white'} loading={loadingState}/>}
                    </StyledRow>
                </ChartInfoBox>
                </div>
                <ResponsiveContainer width='100%' height={600}>
                    <BarChart
                        data={tripDurationData}
                        margin={{top: 5, right: 0, left: 30, bottom: 50,}}
                        barCategoryGap={15}
                    >
                        <CartesianGrid strokeDasharray='3 3'/>
                        <XAxis dataKey='classLabel' angle={45} textAnchor='start' height={50}>
                            <Label value='duration of trip in minutes' offset={10} position='bottom' style={{fill: 'rgba(255, 255, 255, 1)'}} />
                        </XAxis>
                        <YAxis allowDecimals={false} />
                        <Tooltip contentStyle={{ backgroundColor: useContext(ThemeContext).colors.backgroundPrimary }}/>
                        <Legend layout='vertical' verticalAlign='top' align='center'/>
                        <Bar dataKey='count' fill={chartColors.cyan['50']} legendType='rect' name='count of trips' />
                    </BarChart>
                </ResponsiveContainer>
            </StyledRow>

        </PageMarginLeftRight>
    )
}

const StyledRow = styled.div`
    padding: ${distance.large};
    display: flex;
    flex-direction: row;
`
const StyledTopRow = styled.div`
    display: flex;
    flex-direction: row;
    justify-content: space-between;
    padding: ${distance.large};
`