from config import CONFIG
from flask import (
    Blueprint, flash, g, redirect, render_template, request, url_for, session
)
from auth import login_required
from create_db import Card, User

from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker

from numpy.random import choice

bp = Blueprint('deck', __name__)

engine = create_engine(CONFIG['DB_CONNECTION'])
dbsessionmaker = sessionmaker(bind=engine)
dbsession = dbsessionmaker()

@bp.route('/deck', methods=['GET'])
def get_collection(user_id):
    c = dbsession.query(Card).filter(Card.owner_id == user_id).all()
    return c


#2 Probabilistic
## problem je, da pri probabilističnem težko nardiš, da pač en dan ni nič v decku, ker pač vedno izbere glede določeno število pač glede na uteži
# 
# to bi bilo dobro narediti direkt iz baze, ne pa da cel collection spremenimo v ta list ob card.objects TODO
def generate_weights(user_clltn):
    """generiramo uteži za due in new cards posebej; vrne tuple dveh listov za weightse..."""

    weights_due = []
    weights_new = []
    for card in user_clltn:        
        due = card.interest_rate

        if due > 0:
            weights_due.append(due)
            weights_new.append(0)
        else:
            weights_due.append(0)
            weights_new.append(1)
        #če se odločimo, da izločimo iteme jih bo tu ignoriralo, če bo ir 0.

    return weights_new, weights_due


def probabilistic_deck_generator(user_id, max_new, max_due):
        c = get_collection(user_id)
        deck, dck_due, dck_new, due_cards = [], [], [], 0
        w_new, w_due = generate_weights(c)

        #treba je sestet non zero weights 
        new_cards = sum(w_new)
        for w in w_due:
            if w > 0:
                due_cards += 1 

        #preverimo, če imamo dovolj kartic
        if new_cards<max_new:
            max_new = new_cards
        if due_cards<max_due:
            max_due = due_cards

        sum_w_new = sum(w_new)
        sum_w_due = sum(w_due)

        if due_cards:
            dck_due = list(choice(c, size=max_due, replace=False, p=list(map(lambda x: x/sum_w_due, w_due)))) #garancija, da ni ponovitev
        if new_cards:
            dck_new = list(choice(c, size=max_new, replace=False, p=list(map(lambda x: x/sum_w_new, w_new))))

        deck = dck_due + dck_new

        return deck

def get_deck(deck):
    """naredimo string iz cardov"""
    cards_by_id = ""
    for card in deck:
        cards_by_id += str(card.id) + ","
    
    cards_by_id = cards_by_id[:-1]

    return cards_by_id


#################################################
##TODO
# config za max_new in max_due
#################################################
