from server import *
import json

@app.route("/api/user/add", methods=['POST'])
@csrf_protect
def api_user_add():
    ref = request.values.get('ref', None)
    name = request.values.get('name', '')
    if name == '':
        if ref:
            return redirect(ref)
        else:
            return 'name is empty', 422
    mail = request.values.get('mail', '')
    args = []
    args.append(request.values.get('name', ''))
    args.append(mail)
    if request.values.get('transaction_mail', False):
        args.append(True)
    else:
        args.append(False)
    if request.values.get('allow_logging', False):
        args.append(True)
    else:
        args.append(False)
    if request.values.get('sort_by_buycount', False):
        args.append(True)
    else:
        args.append(False)
    try:
        query("INSERT INTO user (name, mail, transaction_mail, allow_logging, sort_by_buycount) VALUES (?, ?, ?, ?, ?)", *args)
    except sqlite3.IntegrityError:
        flash('Username already taken.')
        return redirect(ref)

    if mail != '':
        img_data = load_gravatar(mail)
        if img_data:
            fp = io.BytesIO()
            fp.write(img_data)
            picture_id = import_image(fp)
            if picture_id:
                query('UPDATE user SET picture_id = ? WHERE name = ?', picture_id, name)

    if ref:
        return redirect(ref)
    else:
        return 'OK'

def load_gravatar(mail):
    import hashlib
    import requests

    if not mail or mail == '':
        return None

    mailhash = hashlib.md5(mail.encode()).hexdigest()
    url = 'https://www.gravatar.com/avatar/{}?s=200&d=404'.format(mailhash)
    res = requests.get(url)
    if res.status_code == 404:
        return None
    bytes_ = next(res.iter_content(chunk_size=config['MAX_CONTENT_LENGTH']))
    return bytes_

@app.route("/api/user/<name>/edit", methods=['POST'])
@csrf_protect
def api_user_edit(name):
    ref = request.values.get('ref', None)
    user = query('SELECT * FROM user WHERE name = ?', name)
    if len(user) != 1:
        return "User not found", 404

    args = []
    args.append(request.values.get('name', ''))
    args.append(request.values.get('mail', ''))
    if request.values.get('transaction_mail', False):
        args.append(True)
    else:
        args.append(False)
    if request.values.get('allow_logging', False):
        args.append(True)
    else:
        args.append(False)
    args.append(request.values.get('picture_id', -1, type=int))
    if request.values.get('sort_by_buycount', False):
        args.append(True)
    else:
        args.append(False)
    args.append(name)

    query("UPDATE user SET name = ?, mail = ?, transaction_mail = ?, allow_logging = ?, picture_id = ?, sort_by_buycount = ? WHERE name = ?", *args)

    if ref:
        return redirect(ref)
    else:
        return 'OK'

@app.route("/api/user/<sender>/transfer", methods=['GET', 'POST'])
@csrf_protect
def api_user_transfer(sender):
    ref = request.values.get('ref', None)
    sender = query('SELECT * FROM user WHERE name = ?', sender)
    if not len(sender) == 1:
        if ref:
            flash('Sender not found')
            return redirect(ref)
        else:
            return 'Sender not found', 422
    sender = sender[0]

    recipient = request.values.get('recipient', None)
    recipient = query('SELECT * FROM user WHERE name = ?', recipient)
    if not len(recipient) == 1:
        if ref:
            flash('Recipient not found')
            return redirect(ref)
        else:
            return 'Recipient not found', 422
    recipient = recipient[0]


    amount = int(float(request.values.get('amount', 0))*100)
    reason = request.values.get('reason')

    query('UPDATE user SET balance = balance - ? WHERE id = ?', amount, sender['id'])
    log_action(sender['id'], sender['balance'], sender['balance'] - amount, 'transferTo', recipient['id'], reason)

    query('UPDATE user SET balance = balance + ? WHERE id = ?', amount, recipient['id'])
    log_action(recipient['id'], recipient['balance'], recipient['balance'] + amount, 'transferFrom', sender['id'], reason)

    if ref:
        return redirect(ref)
    else:
        return 'OK'


@app.route("/api/item/<int:itemid>/del")
@csrf_protect
@admin_required
def delitem(itemid):
    query("UPDATE item SET deleted = ? WHERE id = ?", {0:1,1:0}[itemidtoobj(itemid).get('deleted', 0)], itemid)
    return redirect(request.values.get('ref', url_for('itemlist')))

@app.route("/api/img/<imgid>")
@app.route("/api/img/")
def get_img(imgid=None):
    data = query('SELECT data FROM pictures WHERE id = ?', imgid)
    if len(data) == 1:
        r = Response(data[0]['data'], mimetype='image/png')
        r.headers['Cache-Control'] = 'public, max-age=315360000'
        return r
    else:
        return 'Not found', 404

@app.route("/api/img/add", methods=['GET', 'POST'])
@app.route("/api/img/add/<imgid>", methods=['GET', 'POST'])
def api_img_add(imgid=None):
    if (request.method == 'POST') and ('img' in request.files):
        if request.files['img'].filename == '':
            flash('Please select an image')
            return redirect(url_for("api_img_add"))
        newid = import_image(request.files['img'])
        return redirect(url_for("api_img_add",imgid=newid))
    else:
        # TODO why!?!
        if imgid:
            imgid = int(imgid)
        return render_template('imgupload.html', pictures=query("SELECT id from pictures"), selected=imgid)

def import_image(fp):
    img = Image.open(fp)
    tmp = io.BytesIO()
    with img:
        img.load()
        img.thumbnail((200,200) , Image.ANTIALIAS)
        img.save(tmp,format="PNG")
    newid = modify("INSERT INTO pictures (data) values (?)",sqlite3.Binary(tmp.getvalue()))
    return newid

@app.route("/api/user/<name>/buy/<int:itemid>")
@csrf_protect
def api_user_buy(name, itemid):
    user = query('SELECT * FROM user WHERE name = ?', name)[0]
    price = itemprice(itemidtoobj(itemid))
    if user:
        query('UPDATE user SET balance = balance - ? WHERE name = ?', price, name)
        usernew = query('SELECT * FROM user WHERE name = ?', name)[0]
        if price > 0:
            log_action(user['id'], user['balance'], usernew['balance'], 'buy', itemid)
        else:
            log_action(user['id'], user['balance'], usernew['balance'], 'recharge', itemid)
    if request.values.get('noref', False):
        return 'OK'
    else:
        ref = request.values.get('ref', None)
        if ref:
            return redirect(ref)
        else:
            return 'OK'

@app.route("/api/user/<name>/balance", methods=['GET', 'POST'])
@csrf_protect
def api_user_balance(name, newbalance=None):
    user = query('SELECT * FROM user WHERE name = ?', name)[0]
    if not newbalance:
        newbalance = request.values.get('newbalance', None)
    if newbalance:
        newbalance = int(newbalance)
        query('UPDATE user SET balance = ? WHERE name = ?', newbalance, name)
        log_action(user['id'], user['balance'], newbalance, 'set_balance', 0)
    else:
        data = query('SELECT balance FROM user WHERE name = ?', name)[0]['balance']
        if request.values.get('formatted', False):
            return euro(data)
        else:
            return str(data)
    ref = request.values.get('ref', None)
    if ref:
        return redirect(ref)
    else:
        return 'OK'

def date_json_handler(obj):
    return obj.isoformat() if hasattr(obj, 'isoformat') else obj

@app.route("/api/user/<name>/log")
def api_user_log(name):
    resulttype = request.values.get('type', 'html')
    log=query('SELECT log.* FROM log JOIN user ON log.user_id=user.id WHERE (user.name = ?)  ORDER BY log.time DESC LIMIT 50', name)
    user=query('SELECT * from user WHERE name = ?', name)[0]
    if resulttype == 'json':
        return json.dumps(log, default=date_json_handler)
    else:
        return render_template_string("{% from 'macros.html' import loglist %}{{ loglist(log, user) }}", user=user, log=log)

# vim: et ts=4 sw=4