import React from 'react';
import { Heading, Box, Flex, Icon, Link as CLink, Button } from '@chakra-ui/core';
import { Link, Redirect } from "react-router-dom";
import DayPicker from "react-day-picker";
import "react-day-picker/lib/style.css";
import { sources } from '../sources.json';
function addDays(date, days) {
    var result = new Date(date);
    result.setDate(result.getDate() + days);
    return result;
}
export default class Location extends React.Component {
    constructor(props) {
        super(props);
        this.state = { tides: [{ date: '', time: '', distance: 0 }],
                       waves: false,
                       weather: false,
                       locationIndex: 0,
                       loaded: false,
                       date: new Date(new Date().toLocaleDateString()),
                       id: '',
                       name: '',
                       nextTideable: '',
                       urls: { marine: '', weather: '' },
                       redirectToDay: false,
                       showDayPicker: false,
                       goodTides: [],
                       okTides: [],
                       tidesDate: new Date(2000, 1, 1)
                     };
    }
    update = () => {
        fetch(`/api/location/${this.state.id}/date/` + this.state.date.toISOString())
            .then(res => res.json())
            .then(obj => {
                const waves = obj.waves.length > 0 ? obj.waves
                      .sort((a, b) => new Date(a.date) - new Date(b.date))[0] : false;
                const highestSwell = waves ? waves.swellDetails
                      .reduce((r, x) => x.height > r.height ? x : r, { height: -1 }) :
                      false;
                const windHigher = waves ? waves.windHeight > highestSwell.height : false;
                const w = obj.weather;
                const nextTideable = new Date(obj.nextTideable.date);
                this.setState({ tides: obj.tides,
                                waves: waves ?
                                { height: windHigher ? waves.windHeight : highestSwell.height,
                                  direction: windHigher ? '' : highestSwell.direction,
                                  swell: obj.waves.map(w => w.swellText),
                                  wind: obj.waves.map(w => w.windText)
                                } : false,
                                weather: w ?
                                { wind: { speed: w.windSpeed,
                                          direction: w.windDirection },
                                  conditions: w.shortForecast,
                                  high: w.temperature
                                } : false,
                                name: obj.name,
                                loaded: true,
                                nextTideable: nextTideable.getFullYear() + '/' +
                                (nextTideable.getMonth() + 1) + '/' +
                                nextTideable.getDate(),
                                urls: obj.urls,
                                redirectToDay: false
                              });
            });
    }
    fetchTideability = () => {
        fetch(`/api/location/${this.state.id}/tide/` + this.state.date.toISOString())
            .then(res => res.json())
            .then(obj => this.setState({
                goodTides: obj.goodTides.map(x => new Date(x))
                    .filter(x => x.getHours() < 22 && x.getHours() > 5),
                okTides: obj.okTides.map(x => new Date(x))
                    .concat(obj.goodTides.map(x => new Date(x))
                            .filter(x => x.getHours() >= 22 && x.getHours() <= 5)),
                tidesDate: this.state.date
            }));
    }
    componentDidMount() {
        const { match: { params } } = this.props;
        this.setState({ id: params.id,
                        date: params.y ? new Date(parseInt(params.y), parseInt(params.m) - 1, parseInt(params.d)) :
                        this.state.date },
                      () => {
                          this.update();
                          this.fetchTideability();
                      });
    }
    componentDidUpdate(oldProps) {
        const { match: { params } } = this.props;
        const oldParams = oldProps.match.params;
        const date = '' + params.y + params.m + params.d;
        const oldDate = '' + oldParams.y + oldParams.m + oldParams.d;
        if (params.id !== oldProps.match.params.id ||
            date !== oldDate) {
            this.setState({ id: params.id, loaded: false,
                            date: params.y ? new Date(parseInt(params.y), parseInt(params.m) - 1, parseInt(params.d)) : this.state.date
                          },
                          () => {
                              this.update();
                              // if its been a month since we fetched good/okTides
                              if (params.id !== oldProps.match.params.id ||
                                  Math.abs(this.state.date - this.state.tidesDate) >= 2588400000) {
                                  this.fetchTideability();
                              }
                          });
        }
    }
    dayClick = day => {
        this.setState({ redirectToDay: day });
    }
    toggleDayPicker = () => {
        this.setState({ showDayPicker: !this.state.showDayPicker });
    }
    render() {
        if (this.state.loaded && this.state.redirectToDay) {
            return ();
        } else if (this.state.loaded) {
            const sourceIndex = sources.map(source => source.id).indexOf(this.state.id);
            const prevLocationObj = sources[sourceIndex === 0 ?
                                            sources.length - 1 : sourceIndex - 1];
            const nextLocationObj = sources[sourceIndex === sources.length - 1 ?
                                            0 : sourceIndex + 1];
            const prevLocation =
                  (
                      
                        
                      
                  );
            const nextLocation =
                  (
                      
                        
                      
                  );
            const nextDayDate = addDays(this.state.date, 1);
            const nextDay = '/location/' + this.state.id + '/' +
                  nextDayDate.getFullYear() + '/' +
                  (nextDayDate.getMonth() + 1) + '/' +
                  nextDayDate.getDate();
            const prevDayDate = addDays(this.state.date, -1);
            // const today = new Date(new Date().toLocaleDateString());
            const prevDay =
                  '/location/' + this.state.id + '/' +
                  prevDayDate.getFullYear() + '/' +
                  (prevDayDate.getMonth() + 1) + '/' +
                  prevDayDate.getDate();
            const { weather } = this.state;
            const tideMin = Math.min.apply(Math, this.state.tides.map(x => x.distance)),
                  tideColor = tideMin < -0.3 ? 'green' : tideMin < 0 ? 'orange' : 'black';
            const waveColor = this.state.waves.height < 5 ? 'green' :
                  this.state.waves.height < 10 ? 'orange' : 'red';
            const conditionsScore = RegExp('rain', 'g').test(weather.conditions) ? 5 : 0;
            const tempScore = weather.high >= 60 ? 0 : weather.high >= 50 ? 5 : 10;
            const windSpeed = weather.wind ? weather.wind.speed : "0";
            const maxWind = Math.max.apply(Math, windSpeed.match(/[0-9]+/g).map(x => parseInt(x)));
            const windScore = maxWind <= 10 ? 0 : maxWind <= 20 ? 5 : 10;
            const weatherScore = Math.max(conditionsScore, tempScore, windScore);
            const weatherColor = weatherScore < 5 ? 'green' : weatherScore === 5 ? 'orange' : 'red';
            return (
                
                  
                    
                      {prevLocation}
                      {this.state.name}
                      {nextLocation}
                    
                  
                  
                    
                      
                        
                      
                      
                      
                        
                      
                    
                    {this.state.showDayPicker ? (
                        
                          
                        
                    ) : (<>>)}
                    
                      
                    
                  
                  
                    
                      
                        Tide 
                      
                    
                    {this.state.tides.map((tide, i) => (
                        
                          Level: {tide.distance} ft
                          Time: {new Date(tide.date).toLocaleTimeString()}
                        
                    ))}
                
                    {this.state.waves ? (
                        
                          
                            
                              Waves 
                            
                          
                          
                            
                              Max waves: {this.state.waves.height}ft {this.state.waves.direction}
                            
                          
                        
                    ) : (<>>)}
                {this.state.weather ? (
                    
                      
                      
                        Weather 
                      
                    
                    
                      Conditions: {weather.conditions}
                      High: {weather.high}
                      Wind: {weather.wind.speed} {weather.wind.direction}
                    
                  
                ) : (<>>)}
                
            );
        } else {
            return ('Loading...');
        }
    }
}