# -*- coding: utf8 -*-
from pyramid.httpexceptions import HTTPNotFound, HTTPForbidden
from pyramid.response import Response

try:
    from StringIO import StringIO
except ImportError:
    from io import StringIO
import io
from pyramid.view import view_config
from .models import DBSession, User
from reportlab.pdfgen import canvas
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
from reportlab.lib.units import mm
import qrcode
import subprocess
from .upload import MediaPath
from jm2l.const import CurrentYear

# Create PDF container
EXPIRATION_TIME = 300  # seconds
WIDTH = 85 * mm
HEIGHT = 60 * mm
ICONSIZE = 10 * mm


def JM2L_Logo(canvas, Offset=(0, 0)):
    off_x, off_y = Offset
    logo_object = canvas.beginText()
    logo_object.setFont('Logo', 32)
    logo_object.setFillColorRGB(.83, 0, .33)
    logo_object.setTextOrigin(off_x + 5, off_y + 17)
    logo_object.textLines("JM2L")
    canvas.drawText(logo_object)

    year_object = canvas.beginText()
    year_object.setFont("Helvetica-Bold", 10)
    year_object.setFillColorRGB(1, 1, 1)
    year_object.setTextRenderMode(0)
    year_object.setTextOrigin(off_x + 12, off_y + 35)
    year_object.setWordSpace(13)
    year_object.textLines(" ".join(str(CurrentYear)))
    canvas.drawText(year_object)


def Tiers_Logo(canvas, DispUser, start_pos=None, Offset=(0, 0)):
    border = 0
    off_x, off_y = Offset
    if start_pos is None:
        start_pos = (30 * mm, 2)
    start_x, start_y = start_pos
    max_x, max_y = 34 * mm, 18 * mm
    num = 0
    canvas.setStrokeColorRGB(0.5, 0.5, 0.5)
    list_logos = list()
    for thumb in DispUser.tiers:
        if thumb.ThumbLinks:
            list_logos.append(thumb.ThumbLinks[:3])
    # list_logos = list(filter(lambda x: x.ThumbLinks, DispUser.tiers)[:3])
    # Should We compute a better positionning for logos ?
    DicPos = {}
    DicPos[1] = {0: (1. / 2, 1. / 2)}
    DicPos[2] = {0: (1. / 3, 1. / 2), 1: (2. / 3, 1. / 2)}
    DicPos[3] = {0: (1. / 2, 1. / 4), 1: (1. / 3, 3. / 4), 2: (2. / 3, 3. / 4)}
    DicPos[4] = {0: (1. / 3, 1. / 4), 1: (2. / 3, 1. / 4), 2: (1. / 3, 3. / 4),
                 3: (2. / 3, 3. / 4)}
    DicPos[5] = {0: (1. / 3, 1. / 4), 1: (2. / 3, 1. / 4), 2: (1. / 6, 3. / 4),
                 3: (3. / 6, 3. / 4), 4: (5. / 6, 3. / 4)}
    DicPos[6] = {0: (1. / 6, 1. / 4), 1: (3. / 6, 1. / 4), 2: (5. / 6, 1. / 4),
                 3: (1. / 6, 3. / 4), 4: (3. / 6, 3. / 4), 5: (5. / 6, 3. / 4)}
    DicPos[7] = {0: (1. / 6, 1. / 4), 1: (3. / 6, 1. / 4), 2: (5. / 6, 1. / 4),
                 3: (1. / 8, 3. / 4), 4: (3. / 8, 3. / 4), 5: (5. / 8, 3. / 4),
                 6: (7. / 8, 3. / 4)}
    DicPos[8] = {0: (1. / 8, 1. / 4), 1: (3. / 8, 1. / 4), 2: (5. / 8, 1. / 4),
                 3: (7. / 8, 1. / 4), 4: (1. / 8, 3. / 4), 5: (3. / 8, 3. / 4),
                 6: (5. / 8, 3. / 4), 7: (7. / 8, 3. / 4)}
    # draw overall border
    # canvas.roundRect(start_x, start_y, max_x, max_y, radius=2, stroke=True)
    for tiers in list_logos:
        file_name = tiers.ThumbLinks.pop().split("/")[-1]
        image_path = "jm2l/upload/images/tiers/%s/%s" % (tiers.slug, file_name)
        pos_x = off_x + start_x + DicPos[len(list_logos)][num][0] * max_x - (ICONSIZE + border) / 2
        pos_y = off_y + start_y + DicPos[len(list_logos)][num][1] * max_y - (ICONSIZE + border) / 2
        canvas.setLineWidth(.1)
        if len(list_logos) > 1:
            size = ICONSIZE
        else:
            size = ICONSIZE * 1.5
        canvas.drawImage(image_path,
                         pos_x, pos_y, size, size,
                         preserveAspectRatio=True,
                         anchor='c',
                         mask='auto'
                         )
        # draw icon border
        # canvas.roundRect(pos_x, pos_y, ICONSIZE, ICONSIZE, radius=2, stroke=True)
        num += 1


def QRCode(DispUser):
    qr = qrcode.QRCode(
        version=1,
        error_correction=qrcode.constants.ERROR_CORRECT_L,
        box_size=10,
        border=2,
    )
    # Data of QR code
    qr.add_data('http://jm2l.linux-azur.org/user/%s' % DispUser.slug)
    qr.make(fit=True)

    return qr.make_image()


def one_badge(c, DispUser, Offset=(0, 0)):
    # Logo on Top
    JM2L_Logo(c, Offset)
    off_x, off_y = Offset

    c.rect(off_x - 3, off_y - 3, WIDTH + 6, HEIGHT + 6, fill=0, stroke=1)
    if DispUser.Staff:
        # Staff
        c.setFillColorRGB(.83, 0, .33)
        c.rect(off_x - 3, off_y + HEIGHT - 30, WIDTH + 6, 33, fill=1, stroke=0)
        c.setFillColorRGB(1, 1, 1)
        c.setFont('Liberation', 30)
        c.drawCentredString(off_x + WIDTH / 2, off_y + HEIGHT - 24, "STAFF")
    elif DispUser.is_Intervenant:
        # Intervenant
        c.setFillColorRGB(.21, .67, .78)
        c.rect(off_x - 3, off_y + HEIGHT - 30, WIDTH + 6, 33, fill=1, stroke=0)
        c.setFillColorRGB(1, 1, 1)
        c.setFont('Liberation', 30)
        c.drawCentredString(off_x + WIDTH / 2, off_y + HEIGHT - 24, "Intervenant")
    elif DispUser.is_crew:
        # Benevole
        c.setFillColorRGB(.18, .76, .23)
        c.rect(off_x - 3, off_y + HEIGHT - 30, WIDTH + 6, 33, fill=1, stroke=0)
        c.setFillColorRGB(1, 1, 1)
        c.setFont('Liberation', 30)
        c.drawCentredString(off_x + WIDTH / 2, off_y + HEIGHT - 24, "Bénévole")
    else:
        # Visiteur
        c.setFillColorRGB(.8, .8, .8)
        c.rect(off_x - 3, off_y + HEIGHT - 30, WIDTH + 6, 33, fill=1, stroke=0)
        c.setFillColorRGB(1, 1, 1)
        c.setFont('Liberation', 30)
        c.drawCentredString(off_x + WIDTH / 2, off_y + HEIGHT - 24, "Visiteur")

    c.restoreState()

    c.setFont('Liberation', 18)
    c.setStrokeColorRGB(0, 0, 0)
    c.setFillColorRGB(0, 0, 0)
    # Feed Name and SurName
    if DispUser.prenom and DispUser.nom and len(DispUser.prenom) + len(DispUser.nom) > 18:
        if DispUser.pseudo:
            c.drawCentredString(off_x + WIDTH / 2, off_y + HEIGHT / 2 + 0 * mm, "%s" % DispUser.prenom)
            # c.setFont('Courier', 17)
            c.drawCentredString(off_x + WIDTH / 2, off_y + HEIGHT / 2 - 8 * mm, "%s" % DispUser.nom)
        else:
            c.drawCentredString(off_x + WIDTH / 2, off_y + HEIGHT / 2 + 4 * mm, "%s" % DispUser.prenom)
            # c.setFont('Courier', 17)
            c.drawCentredString(off_x + WIDTH / 2, off_y + HEIGHT / 2 - 8 * mm, "%s" % DispUser.nom)
    else:
        c.drawCentredString(off_x + WIDTH / 2, off_y + HEIGHT / 2 + 0 * mm, "%s %s" % (DispUser.prenom, DispUser.nom))

    if DispUser.pseudo:
        c.setFont("Helvetica-Oblique", 18)
        c.drawCentredString(off_x + WIDTH / 2, off_y + HEIGHT / 2 + 10 * mm, "%s" % DispUser.pseudo)

    #  Put QR code to user profile
    c.drawInlineImage(QRCode(DispUser),
                      off_x + WIDTH - 20 * mm - 5, off_y + 5,
                      20 * mm, 20 * mm,
                      preserveAspectRatio=True,
                      anchor='s')

    Tiers_Logo(c, DispUser, None, Offset)


@view_config(route_name='badge_user')  # , http_cache=(EXPIRATION_TIME, {'public': True}))
def badge_user(request):
    isoutpng = request.params.get('png')
    user_slug = request.matchdict.get('user_slug', None)
    if user_slug is None or len(user_slug) == 0:
        raise HTTPNotFound(u"Cet utilisateur n'a pas été reconnu")
    # Query database
    DispUser = User.by_slug(user_slug)
    if DispUser is None:
        raise HTTPNotFound()

    # Ok let's generate a PDF Badge

    # Register LiberationMono font
    ttf_file = "jm2l/static/fonts/LiberationMono-Regular.ttf"
    pdfmetrics.registerFont(TTFont("Liberation", ttf_file))
    #  Import font
    ttf_file_logo = "jm2l/static/fonts/PWTinselLetters.ttf"
    pdfmetrics.registerFont(TTFont("Logo", ttf_file_logo))

    pdf = io.BytesIO()
    out_img = io.BytesIO()

    c = canvas.Canvas(pdf, pagesize=(WIDTH, HEIGHT))
    c.translate(mm, mm)

    # Feed some metadata
    c.setCreator("linux-azur.org")
    c.setTitle("Badge")

    c.saveState()

    one_badge(c, DispUser)
    out_pdf = MediaPath().get_mediapath("badge", DispUser.uid, 'badge.pdf')
    c.showPage()
    c.save()
    pdf.seek(0)
    if isoutpng:
        out_png = MediaPath().get_mediapath("badge", DispUser.uid, 'badge.png')
        #  Let's generate a png file for website
        with open("./%s" % out_pdf, 'wb') as pdff:
            pdff.write(pdf.read())

        Command = ["convert", "-density", "150x150", out_pdf, out_png]
        subprocess.call(Command)

        with open("./%s" % out_png, 'rb') as pngfile:
            out_img.write(pngfile.read())  # pngfile.read(), "utf8"))

        out_img.seek(0)
        return Response(app_iter=out_img, content_type='image/png')
    else:
        return Response(app_iter=pdf, content_type='application/pdf')


@view_config(route_name='all_badges')
def planche_badge(request):
    if request.user is None:
        # Don't answer to users that aren't logged
        raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.')
    # Query database about selected Year.
    Users = DBSession.query(User)
    #            .join(User_Event)\
    #            .filter(User_Event.year_uid == year)

    # Register LiberationMono font
    ttf_file = "jm2l/static/fonts/LiberationMono-Regular.ttf"
    pdfmetrics.registerFont(TTFont("Liberation", ttf_file))
    #  Import font
    ttf_file_logo = "jm2l/static/fonts/PWTinselLetters.ttf"
    pdfmetrics.registerFont(TTFont("Logo", ttf_file_logo))

    pdf = io.BytesIO()

    FULLWIDTH = 210 * mm
    FULLHEIGHT = 297 * mm

    c = canvas.Canvas(pdf, pagesize=(FULLWIDTH, FULLHEIGHT))
    c.translate(mm, mm)

    # Feed some metadata
    c.setCreator("linux-azur.org")
    c.setTitle("Badge")
    t = 0
    list_user = filter(lambda x: x.is_Intervenant or x.Staff or x.is_crew, Users)
    for num, disp_user in enumerate(list_user):
        c.saveState()
        offsets = (((num - t) % 2) * (WIDTH + 40) + 40, int(((num - t) / 2)) * (HEIGHT + 25) + 40)
        one_badge(c, disp_user, offsets)
        if num % 8 == 7:
            t = num + 1
            c.showPage()

    c.showPage()
    c.save()
    pdf.seek(0)
    return Response(app_iter=pdf, content_type='application/pdf')
