import os
import logging
import datetime
import math
import re
from six.moves.urllib.request import urlopen
from six.moves.urllib.parse import urlencode

import aniso8601
from flask import Flask, json, render_template
from flask_ask import Ask, request, session, question, statement


ENDPOINT = "https://tidesandcurrents.noaa.gov/api/datagetter"
SESSION_CITY = "city"
SESSION_DATE = "date"

# NOAA station codes
STATION_CODE_SEATTLE = "9447130"
STATION_CODE_SAN_FRANCISCO = "9414290"
STATION_CODE_MONTEREY = "9413450"
STATION_CODE_LOS_ANGELES = "9410660"
STATION_CODE_SAN_DIEGO = "9410170"
STATION_CODE_BOSTON = "8443970"
STATION_CODE_NEW_YORK = "8518750"
STATION_CODE_VIRGINIA_BEACH = "8638863"
STATION_CODE_WILMINGTON = "8658163"
STATION_CODE_CHARLESTON = "8665530"
STATION_CODE_BEAUFORT = "8656483"
STATION_CODE_MYRTLE_BEACH = "8661070"
STATION_CODE_MIAMI = "8723214"
STATION_CODE_TAMPA = "8726667"
STATION_CODE_NEW_ORLEANS = "8761927"
STATION_CODE_GALVESTON = "8771341"

STATIONS = {}
STATIONS["seattle"] =  STATION_CODE_SEATTLE
STATIONS["san francisco"] =  STATION_CODE_SAN_FRANCISCO
STATIONS["monterey"] =  STATION_CODE_MONTEREY
STATIONS["los angeles"] =  STATION_CODE_LOS_ANGELES
STATIONS["san diego"] =  STATION_CODE_SAN_DIEGO
STATIONS["boston"] =  STATION_CODE_BOSTON
STATIONS["new york"] =  STATION_CODE_NEW_YORK
STATIONS["virginia beach"] =  STATION_CODE_VIRGINIA_BEACH
STATIONS["wilmington"] =  STATION_CODE_WILMINGTON
STATIONS["charleston"] =  STATION_CODE_CHARLESTON
STATIONS["beaufort"] =  STATION_CODE_BEAUFORT
STATIONS["myrtle beach"] =  STATION_CODE_MYRTLE_BEACH
STATIONS["miami"] =  STATION_CODE_MIAMI
STATIONS["tampa"] =  STATION_CODE_TAMPA
STATIONS["new orleans"] =  STATION_CODE_NEW_ORLEANS
STATIONS["galveston"] =  STATION_CODE_GALVESTON


app = Flask(__name__)
ask = Ask(app, "/")
logging.getLogger('flask_ask').setLevel(logging.DEBUG)


class TideInfo(object):

    def __init__(self):
        self.first_high_tide_time = None
        self.first_high_tide_height = None
        self.low_tide_time = None
        self.low_tide_height = None
        self.second_high_tide_time = None
        self.second_high_tide_height = None


@ask.launch
def launch():
    welcome_text = render_template('welcome')
    help_text = render_template('help')
    return question(welcome_text).reprompt(help_text)


@ask.intent('OneshotTideIntent',
    mapping={'city': 'City', 'date': 'Date'},
    convert={'date': 'date'},
    default={'city': 'seattle', 'date': datetime.date.today })
def one_shot_tide(city, date):
    if city.lower() not in STATIONS:
        return supported_cities()
    return _make_tide_request(city, date)


@ask.intent('DialogTideIntent',
    mapping={'city': 'City', 'date': 'Date'},
    convert={'date': 'date'})
def dialog_tide(city, date):
    if city is not None:
        if city.lower() not in STATIONS:
            return supported_cities()
        if SESSION_DATE not in session.attributes:
            session.attributes[SESSION_CITY] = city
            return _dialog_date(city)
        date = aniso8601.parse_date(session.attributes[SESSION_DATE])
        return _make_tide_request(city, date)
    elif date is not None:
        if SESSION_CITY not in session.attributes:
            session.attributes[SESSION_DATE] = date.isoformat()
            return _dialog_city(date)
        city = session.attributes[SESSION_CITY]
        return _make_tide_request(city, date)
    else:
        return _dialog_no_slot()


@ask.intent('SupportedCitiesIntent')
def supported_cities():