from itertools import cycle
from time import get_clock_info
from tracemalloc import start
from flask import (
    Blueprint, flash, g, redirect, render_template, request, url_for
)
from werkzeug.exceptions import abort
import pendulum

# from flaskr.auth import login_required
from period.db import get_db

bp = Blueprint('cycles', __name__)

@bp.route('/')
def index():
    db = get_db()
    current_cycle = db.execute('SELECT * from cycle ORDER BY id DESC LIMIT 1').fetchone()
    start_time = pendulum.parse(current_cycle['start_time'])
    cycle_length = ((pendulum.now() - start_time ).days)+1

    db.execute(
        'UPDATE cycle SET cycle_length = ?'
        ' WHERE id = ?',
        (cycle_length, current_cycle['id'])
    )

    cycles = db.execute(
        'SELECT id, start_time, end_time, cycle_length'
        ' FROM cycle ORDER BY start_time DESC'
    ).fetchall()
    return render_template('cycle/index.html', cycles=cycles)

@bp.route('/create', methods=('GET', 'POST'))
def create():
    if request.method == 'POST':
        start_time_stamp = request.form['start_time']
        start_time = pendulum.from_format(start_time_stamp, 'YYYY-MM-DD')
        try:
            end_time_stamp = request.form['end_time']
            end_time = pendulum.from_format(request.form['end_time'], 'YYYY-MM-DD')
        except ValueError:
            end_time_stamp = "1900-01-01"
            end_time = pendulum.datetime(1900,1,1)
        error = None
        # print(request.form['end_time'])

        if not start_time:
            error = "You must provide a start date"
        
        if end_time > start_time:
            cycle_length = (end_time - start_time).days
        else:
            cycle_length = (pendulum.now() - start_time).days

        if error is not None:
            flash(error)
        else:
            db = get_db()
            if end_time > start_time:
                db.execute(
                    'INSERT INTO cycle (start_time, end_time, cycle_length) VALUES (?, ?, ?)',
                    (start_time_stamp, end_time_stamp, cycle_length)
                )
            else:
                db.execute(
                    'INSERT INTO cycle (start_time)'
                    ' VALUES (?)',
                    (start_time.to_datetime_string(),)
                )
            db.commit()
            # return redirect(url_for('index'))
            return redirect(url_for('cycles.cycle_math'))
    return render_template('cycle/create.html')

def get_cycle(id):
    cycle = get_db().execute(
        'SELECT * from cycle WHERE id = ?',
        (id,)
    ).fetchone()

    if cycle is None:
        abort(404, f"Cycle id {id} doesn't exist.")

    return cycle

@bp.route('/<int:id>/update', methods=('GET', 'POST'))
def update(id):
    cycle = get_cycle(id)

    if request.method == 'POST':
        start_time_stamp = request.form['start_time']
        start_time = pendulum.from_format(start_time_stamp, 'YYYY-MM-DD')
        try:
            end_time_stamp = request.form['end_time']
            end_time = pendulum.from_format(end_time_stamp, 'YYYY-MM-DD')
        except ValueError:
            end_time_stamp = "1900-01-01"
            end_time = pendulum.datetime(1900,1,1)
        error = None
        if end_time is None:
            end_time = "2999-01-01"

        if not start_time:
                error = "You must provide a start date"

        if end_time > start_time:
                cycle_length = (end_time - start_time).days
        else:
            cycle_length = (pendulum.now() - start_time).days

        if error is not None:
            flash(error)
        else:
            db = get_db()
            if end_time > start_time:
                db.execute(
                    'UPDATE cycle SET start_time = ?, end_time = ?, cycle_length = ?'
                    ' WHERE id = ?',
                    (start_time.to_datetime_string(), end_time.to_datetime_string(), cycle_length, id)
                )
            else:
                db.execute(
                    'UPDATE cycle SET start_time = ?, cycle_length = ?'
                    ' WHERE id = ?',
                    (start_time.to_datetime_string(), cycle_length, id)
                )
            db.commit()
            return redirect(url_for('cycles.cycle_math'))
    return render_template('cycle/update.html', cycle=cycle)

@bp.route('/<int:id>/delete', methods=('POST',))
def delete(id):
    get_cycle(id)
    db = get_db()
    db.execute('DELETE FROM cycle WHERE id = ?', (id,))
    db.commit()
    # return redirect(url_for('index'))
    return redirect(url_for('cycles.cycle_math'))

@bp.route('/cycle_math')
def cycle_math():
    db = get_db()

    all_cycles = db.execute(
        'SELECT id, start_time, end_time, cycle_length'
        ' FROM cycle ORDER BY start_time DESC'
    ).fetchall()


    for num, cycle in enumerate(all_cycles):
        # http://127.0.0.1:5000/cycle_math
        # cycle length = next start -  this start
        if num > 0:
            this_start = pendulum.parse(cycle['start_time'])
            next_start = pendulum.parse(all_cycles[num-1]['start_time'])
            cycle_length = (next_start - this_start).days
            db.execute(
                'UPDATE cycle SET cycle_length = ?'
                ' WHERE id = ?',
                (cycle_length, cycle['id'])
            )
            db.commit()


    return redirect(url_for('cycles.index'))