"""
Replacement for RUSA ACP brevet time calculationstor
(see https://rusa.org/octime_acp.html)
"""

# **** This is flask_brevets for Project 5 ****

import flask
import os
from flask import Flask, request, url_for, redirect, render_template
from pymongo import MongoClient 

import arrow  
import config
import logging
import json

import acp_times  # Brevet time calculations
import brevets_db # MongoDB operations in Python

###
# Globals
###
app = flask.Flask(__name__)
CONFIG = config.configuration()

client = MongoClient('mongodb://' + os.environ['MONGODB_HOSTNAME'], 27017)
db = client.timesdb     # database object for pymongo

FORMAT = "YYYY-MM-DDTHH:mm"

###
# Pages
###

@app.route("/")
@app.route("/index")
def index():
    app.logger.debug("Main page entry")
    return render_template("calc.html")      

@app.errorhandler(404)
def page_not_found(error):
    app.logger.debug("Page not found")
    return render_template("404.html"), 404

@app.route("/error")
def form_error():
    app.logger.debug("Form Error page entry")
    return render_template("form_error.html")

###############
# AJAX request handlers
#   These return JSON, rather than rendering pages.
###############
@app.route("/_calc_times")
def _calc_times():
    """
    Calculates open/close times from miles, using rules
    described at https://rusa.org/octime_alg.html.
    """
    app.logger.debug("Got a JSON request")

    # Retrieve the values passed in the JSON request from the client
    km = request.args.get('km', 999, type=float)
    brev_dist = request.args.get('brev_dist', type=int)
    date_time = request.args.get('date_time',type=str)
    control_arrow = arrow.get(date_time, FORMAT)

    app.logger.debug("km={}".format(km))
    app.logger.debug("request.args: {}".format(request.args))
    app.logger.debug("control_time=" + control_arrow.format(FORMAT))

    # Pass in brevet distance and date/time the "race" started
    # Find opening and closing times for the control, then send those to client
    open_time = acp_times.open_time(km, brev_dist, control_arrow)
    close_time = acp_times.close_time(km, brev_dist, control_arrow)
    
    open_time = open_time.format(FORMAT)
    close_time = close_time.format(FORMAT)
    app.logger.debug("open_time= " + open_time)
    app.logger.debug("close_time= " + close_time)

    # Server sends JSON response -> processed by JQuery in calc.html that will parse info
    result = {"open": open_time, "close": close_time}
    return flask.jsonify(result=result)


# Flask route used for inserting the open/close times into our MongoDB database
@app.route('/submit', methods=['POST'])
def submit():
    app.logger.debug("Recieved a POST request to insert control times into DB")

    # Issue: Using the standard requests.get_json() method doesn't produce a Python dict like we want
    request_str = request.form.get("controlTimes",type=str)

    # Have to use built-in json library, json.loads() basically does the same thing
    control_times = json.loads(request_str)
    app.logger.debug(f"control_times = {control_times} \n type of control_times={type(control_times)}")

    # Using brevets_db.insert_times() to insert the times into the database
    brevets_db.insert_times(control_times)
   
    # Redirect to the main page after inserting items into the database
    return redirect(url_for('index'))


# Flask route used for retrieving the control times from MongoDB
@app.route('/display')
def display():
    app.logger.debug("Recieved a HTTP GET request to retrieve control times from MongoDB")

    # Using brevets_db.retrieve_times() to retrieve what was most recently stored in the db
    control_times = brevets_db.retrieve_times()
    if len(control_times) == 0:
        return redirect(url_for("form_error"))

    # First element in list of "docs", get brevDist and beginDate "columns"
    brevet = control_times[0]["brevDist"]
    startDate = control_times[0]["beginDate"]
    # How do we format the opening / closing times from python?
    # Iterate over the opening/closing times in control_times[] -> make arrow objects? -> format into readable

    # Passing info from MongoDB into the display_times HTML page
    # Example:  return render_template('index.html', items=list(db.tododb.find()) )
    return render_template('display_times.html', brevDist=brevet, beginDate=startDate, times=control_times)


#############
app.debug = CONFIG.DEBUG
if app.debug:
    app.logger.setLevel(logging.DEBUG)

app.logger.setLevel(logging.DEBUG)

if __name__ == "__main__":
    print("Opening for global access on port {}".format(CONFIG.PORT)) 
    app.run(port=CONFIG.PORT, host="0.0.0.0", debug=True)
