from io import BytesIO, StringIO

import matplotlib
import matplotlib.pyplot as plt
import matplotlib.dates as mdates

import pandas as pd

from numpy import nan_to_num
from base64 import b64encode
from subprocess import Popen, PIPE

def svg_histogram(r, title="", label="", bins = 10):
    """
    Création d'un histogramme au format SVG
    
    @param r une série de données entières
    @param title le titre de la figure
    @param label précision du type de données que l'on compte
    @parameter bins est directement passé à pyplot.hist (10 par défaut)
    @return une chaîne de caractères
    """
    if not r:
        return None
    matplotlib.use('agg')
    plt.rcParams['svg.fonttype'] = 'none'
    plt.hist(r, label=label, bins=bins)
    plt.legend(frameon=False)
    plt.title(title)
    f = BytesIO()
    plt.savefig(f, format="svg")
    return f.getvalue().decode("utf-8")

def demo_svg_histogram():
    import numpy as np
    np.random.seed(19680801)
    r = np.random.randn(1000)
    with open ("svg_histogram.svg", "w") as outfile:
        outfile.write(svg_histogram(
            r, "Voici un histogramme.", 'Nombre de livres prêtés'
        ))
    return

def svg_actions_datees(dates, name="date de ..."):
    """
    Création d'un graphique au format SVG, qui présente une frise
    chronologique des nombres d'actions, regroupées par dates

    @param dates une série de dates (une par action, la répétition de dates
                 est possible)
    @param name un label expliquant le nature des dates
    @return une chaîne de caractères
    """
    # gettext_lazy peut être cause de difficultés, on force une évaluation
    name = str(name)
    matplotlib.use('agg')
    plt.rcParams['svg.fonttype'] = 'none'
    f = StringIO()
    f.write(name + "\n")
    for d in dates:
        f.write(str(d)+"\n")
    f.seek(0)
    les_dates = pd.read_csv(f, parse_dates=[name])
    s = les_dates.groupby(les_dates[name])[name].count()
    s = s.resample("1d").apply({"compte": lambda x: sum(nan_to_num(x))})
    fig,ax1 = plt.subplots()

    plt.plot(s.index, s.values)
    plt.title("nombre d'opérations, selon la " + name)

    ax1.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m'))
    plt.xticks(rotation=30)

    f = BytesIO()
    plt.savefig(f, format="svg")
    return f.getvalue().decode("utf-8")

def demo_svg_actions_datees():
    from .models import Prets
    with open ("svg_dates_prets.svg", "w") as outfile:
        outfile.write(svg_actions_datees(
            (p.date_pret for p in Prets.objects.all()),
            "date de prêt"
        ))
    return

def urlToQrcode(url):
    """
    Transforme une URL en un QR-Code
    @param url l'URL à encoder
    @return le code source d'un élément <img>
    """
    command = [
        'qrencode',
        '-o', '-',   # to stdout
        '-s', '6',   # pixel size
        '-l', 'H',   # highest correction level
        '-m', '8',   # margin size
        '-t', 'PNG', # type PNG
        '--background=FFFFFF',
        url          # url to encode
    ]
    p = Popen(command, stdout=PIPE, stderr=PIPE)
    outs, errs = p.communicate()
    qrcode = f"<img src='data:image/png;base64, {b64encode(outs).decode()}' "+ \
        "alt='Qr-code'/>"
    return qrcode

if __name__ == "__main__":
    # demo_svg_histogram()
    demo_svg_actions_datees()
