#!/usr/bin/env python3
from bottle import jinja2_view, static_file, Jinja2Template, Bottle, request, url
from datetime import datetime
from cheroot import wsgi
import os
import bottle
import psycopg2
import json
import commonmark
import traceback
import random
import functools
from math import ceil
import locale

from .database import Database
from collections import OrderedDict

def countView(fn):
    def newFn(*args, **kwargs):
        data = fn(*args, **kwargs)
        database.execute("INSERT INTO viewers (ip, user_agent, request_url) VALUES (%s, %s, %s);",
        (request.remote_addr, request.environ.get('HTTP_USER_AGENT'), request.path))
        return data
    return newFn

# locale.setlocale(locale.LC_ALL, "nl_NL.UTF-8")

menu = OrderedDict(
        [("Startpagina", "/"),
         ("Uitgaven", "/uitgaven"),
         ("Artikelen", "/artikelen"),
         ("<span id='colorshift'>Solliciteren</span>", "/doemee"),
         ("Over de Harry", "/over")])

Jinja2Template.defaults = {"url": url, "site_name": "Harry", "navigation": menu}
try:
    Jinja2Template.defaults.update(__builtins__.__dict__)
except:
    Jinja2Template.defaults.update(__builtins__)
Jinja2Template.settings = {"autoescape": True}

view = functools.partial(jinja2_view, template_lookup=["templates"])

database = Database(user="harry", password="ySStB5hFaaNmLhKwXH", database="harry", host="localhost")

def reformat_date(date):
    # 1 januari 1970, 00:00
    fmt_date = date.strftime("%d %B %Y, %H:%M")
    if (fmt_date.endswith('00:00')):
        fmt_date = date.strftime("%d %B %Y")
    return fmt_date

app = Bottle()

@app.route('/')
@view('index.html')
@countView
def index():
    results = database.execute("""
        SELECT * FROM select_articles() ORDER BY date DESC, page_number DESC;
    """).fetchall()
    
    for result in results:
        result["date"] = reformat_date(result["date"])
    
    featured_results = [result for result in results if result["featured"]]
    normal_results = [result for result in results if not result["featured"]] \
        + featured_results[2:]
        
    
    nPages = ceil(len(normal_results) / 9)
    
    return {"title": "Harry", "results": normal_results,
            "fresult1": featured_results[0], "fresult2": featured_results[1],
            "enumerate": enumerate, "range": range, "npages": nPages,
            "page": 1
    }

@app.route('/artikel/<id:int>')
@view('artikel.html')
@countView
def artikel(id):
    result = database.execute("""
        SELECT * FROM select_articles() WHERE id = %s ORDER BY date, page_number;
    """, id).fetchone()
    
    title = result["title"]
    date = reformat_date(result["date"])
    body = commonmark.commonmark(result["body"])
    authors = ", ".join(result["authors"])
    categories = ", ".join(result["categories"])
    banner_image = result["image_url"] or "https://www.w3.org/Icons/w3cmem4.gif"
    
    categories_as_pgarray = '{' + ','.join(result["categories"]) + '}'
    print(categories_as_pgarray)
    result = database.execute("""SELECT * FROM articles_per_cat() WHERE name =any(%s);""",
        (categories_as_pgarray,)).fetchall()
    
    suggestions = []
    for row in result:
        for item in row["articles_json"]:
            if (item["title"] != title and item not in suggestions):
                suggestions.append(item)
    
    random.shuffle(suggestions)
    
    return {"title": "Harry - %s" % (title), "article_title": title, "date": date,
            "body": body, "authors": authors, "categories": categories, "banner_image": banner_image,
            "suggestions": suggestions[:20]
    }
    

@app.route('/uitgaven')
@view('uitgaven.html')
@countView
def uitgaven():
    return {"title": "Harry - Uitgaven"}
    
@app.route('/artikelen')
@view('artikelen.html')
@countView
def artikelen():
    return artikelen_page(1)

@app.route('/artikelen/<page:int>')
@view('artikelen.html')
@countView
def artikelen_page(page):
    results = database.execute("""
        SELECT * FROM select_articles() ORDER BY date DESC, page_number DESC;
    """).fetchall()
    
    for result in results:
        result["date"] = reformat_date(result["date"])
        
    begin = (page - 1) * 9
    end = page * 9
    
    nPages = ceil(len(results) / 9)
    
    categories = [i for i in database.execute("""SELECT * FROM articles_per_cat()""").fetchall()
                    if i["articles_json"] is not None]
    
    return {"title": "Harry - Artikelen", "results": results[begin:end], "enumerate": enumerate,
        "categories": categories, "npages": nPages, "page": page
    } 

@app.route('/doemee')
@view('solliciteren.html')
@countView
def solliciteren():
    return {"title": "Harry - Solliciteren"}

@app.route('/over')
@view('over.html')
@countView
def over():
    return {"title": "Harry - Over de Harry"}
    
@app.route('/uitgaven/<id:int>')
@view('viewer.html')
@countView
def view_edition(id):
    if (not os.path.exists('static/harry-druk-%d.pdf' % id)):
        # het bestand bestaat niet
        return redirect("/uitgaven", code=307)
    return {"title": "Harry - Jaargang 2015-2016", "id": id}

@app.route('/categorie/<id:int>')
@view('categorie.html')
@countView
def view_category(id):
    category = database.execute("""SELECT * FROM articles_per_cat() WHERE id = %s""",
        id).fetchone();
    categories = [i for i in database.execute("""SELECT * FROM articles_per_cat()""").fetchall()
                    if i["articles_json"] is not None]
    return {"title": "Harry - Categorie", "repr": repr,
            "category": category, "enumerate": enumerate,
            "categories": categories}


@app.route('/static/:path#.+#', name='static')
def static(path):
    return static_file(path, root='static')

app.catchall = False
