from datetime import datetime, timedelta
from math import ceil
from passlib.apps import custom_app_context as poc_pwd_context
from dateutil import tz
from .pagination import Pagination

from_zone = tz.tzutc()
to_zone = tz.tzlocal()


def get_lastest_tag_values(request):
    latest_tag_values = []
    latesttag_agg = request.db['wellData'].aggregate([
        {
            '$sort': {"tagname": 1, "timestamp": 1}
        },
        {
            '$group': {
                '_id': "$tagname",
                'timestamp': {'$last': "$timestamp"},
                'value': {'$last': "$currentValue"},
                'max': {'$last': "$maxDailyValue"},
                'min': {'$last': "$minDailyValue"},
                'average': {'$last': "$dailyAverage"},
                'total': {'$last': "$dailyTotal"}
            }
        }
    ])
    for t in latesttag_agg:
        latest_tag_values.append(t)
    return latest_tag_values


def get_latest_card(request):
    try:
        latest_card = list(request.db['cards'].find().sort("timestamp", -1).limit(1))[0]
        return latest_card
    except IndexError:
        return []


def card_page(request):
    page_num = 1
    try:
        page_num = int(request.matchdict['page_num'])
    except KeyError:
        pass

    cards_date_start = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
    try:
        cards_date_start = datetime.strptime(request.matchdict['cards_date'], "%Y-%m-%d")
    except KeyError:
        pass

    cards_date_end = cards_date_start + timedelta(days=1)

    num_per_page = 100
    num_cards = request.db['cards'].find({'timestamp': {'$lt': cards_date_end, '$gte': cards_date_start}}).count()
    pages = ceil(num_cards / num_per_page)

    cards = request.db['cards'].find({'timestamp': {'$lt': cards_date_end, '$gte': cards_date_start}}).sort("timestamp", -1).skip(num_per_page * (page_num - 1)).limit(num_per_page)
    return {'cards': list(cards), 'pagination': Pagination(page_num, num_per_page, num_cards), 'cards_date': cards_date_start.strftime("%Y-%m-%d"), 'navgroup': 'cards'}


def get_all_dates_with_cards(request):
    datelist = []
    dateagg = request.db['cards'].aggregate([
        {"$group": {
            "_id": {"$concat": [
                {"$substr": [{"$year": "$timestamp"}, 0, 4]},
                "-",
                {"$substr": [{"$month": "$timestamp"}, 0, 2]},
                "-",
                {"$substr": [{"$dayOfMonth": "$timestamp"}, 0, 2]},
            ]},
            "count": {"$sum": 1}
        }},
        {"$sort": {"_id": -1}}
    ])
    for d in dateagg:
        datelist.append({'count': d['count'], 'date': datetime.strptime(d['_id'], "%Y-%m-%d").date()})
    return list(datelist)


def get_poc_address(request):
    addr_obj = list(request.db['pocConfiguration'].find({"_id": "pocIPAddress"}))
    address = False
    if len(addr_obj) > 0:
        address = addr_obj[0]['pocIPAddress']
    return address


def set_password(request, username, password):
    password_hash = poc_pwd_context.encrypt(password)
    request.db['users'].update_one({'username': username}, {"$set":{"username": username, "password": password_hash}}, upsert=True)


def check_password(request, username, password):
    users = list(request.db['users'].find({'username': username}))
    if len(users) > 0:
        this_user = users[0]

        # is it cleartext?
        if password == this_user['password']:
            set_password(request, username, password)
            return check_password(request, username, password)

        return poc_pwd_context.verify(password, this_user['password'])
