import json

from flask import request
from median.models import HistoriqueBlocage, Product, CodeBlocage, Adresse, Magasin
from peewee import fn, JOIN


def get_where_expression():
    data = json.loads(request.data)

    start = data['start']
    end = data['end']
    type_mag = data['typeMag']

    return (HistoriqueBlocage.chrono >= start) & (HistoriqueBlocage.chrono <= end) & (Magasin.type_mag == type_mag)


def get_ref_by_lock_adresse_request(adr_pk):

    data = json.loads(request.data)
    start = data['start']
    end = data['end']

    mode = data.get('mode', 0)
    typeMag = data.get('typeMag', None)

    andexpr = (
        (HistoriqueBlocage.chrono >= start) &
        (HistoriqueBlocage.chrono <= end) &
        (Magasin.type_mag == typeMag if typeMag is not None else True)
    )

    if mode == 0:
        return (HistoriqueBlocage
                .select(fn.COUNT(HistoriqueBlocage.pk).alias('count'),
                        HistoriqueBlocage.reference.alias('reference'),
                        Product.designation.alias('designation'),
                        HistoriqueBlocage.bloque.alias('cause_code'),
                        CodeBlocage.libelle.alias('cause_designation'))
                .join(CodeBlocage, JOIN.LEFT_OUTER, on=HistoriqueBlocage.bloque == CodeBlocage.valeur)
                .join(Adresse, on=Adresse.adresse == HistoriqueBlocage.adresse)
                .join(Product, on=Product.reference == HistoriqueBlocage.reference)
                .join(Magasin, on=Magasin.mag == Adresse.magasin)
                .where(andexpr & (HistoriqueBlocage.bloque != 0) & (Adresse.pk == adr_pk))
                .group_by(HistoriqueBlocage.reference, HistoriqueBlocage.bloque)
                .order_by(fn.COUNT(HistoriqueBlocage.pk).desc()))
    else:
        return (HistoriqueBlocage
                .select(fn.COUNT(HistoriqueBlocage.pk).alias('count'),
                        HistoriqueBlocage.adresse.alias('reference'),
                        HistoriqueBlocage.bloque.alias('cause_code'),
                        CodeBlocage.libelle.alias('cause_designation'))
                .join(CodeBlocage, JOIN.LEFT_OUTER, on=HistoriqueBlocage.bloque == CodeBlocage.valeur)
                .join(Adresse, on=Adresse.adresse == HistoriqueBlocage.adresse)
                .join(Product, on=Product.reference == HistoriqueBlocage.reference)
                .join(Magasin, on=Magasin.mag == Adresse.magasin)
                .where(andexpr & (HistoriqueBlocage.bloque != 0) & (Product.pk == adr_pk))
                .group_by(HistoriqueBlocage.adresse, HistoriqueBlocage.bloque)
                .order_by(fn.COUNT(HistoriqueBlocage.pk).desc()))


def get_causes_request():
    andexpr = get_where_expression()

    data = json.loads(request.data)
    mode = data.get('mode', 0)

    if mode == 0:
        req = (HistoriqueBlocage
               .select(fn.YEAR(HistoriqueBlocage.chrono).alias('year'),
                       fn.WEEKOFYEAR(HistoriqueBlocage.chrono).alias('week'),
                       fn.COUNT(HistoriqueBlocage.pk).alias('nb'),
                       HistoriqueBlocage.adresse.alias('title'),
                       HistoriqueBlocage.bloque.alias('cause'),
                       Adresse.pk.alias('address_pk'),
                       CodeBlocage.libelle.alias('designation'))
               .join(Adresse, on=Adresse.adresse == HistoriqueBlocage.adresse)
               .join(Magasin, on=Adresse.magasin == Magasin.mag)
               .join(CodeBlocage, JOIN.LEFT_OUTER, on=HistoriqueBlocage.bloque == CodeBlocage.valeur)
               .where(andexpr & (HistoriqueBlocage.bloque != 0))
               .group_by(HistoriqueBlocage.adresse, HistoriqueBlocage.bloque, fn.YEAR(HistoriqueBlocage.chrono),
                         fn.WEEKOFYEAR(HistoriqueBlocage.chrono)))
    else:
        req = (HistoriqueBlocage
               .select(fn.YEAR(HistoriqueBlocage.chrono).alias('year'),
                       fn.WEEKOFYEAR(HistoriqueBlocage.chrono).alias('week'),
                       fn.COUNT(HistoriqueBlocage.pk).alias('nb'),
                       HistoriqueBlocage.reference.alias('title'),
                       Product.designation.alias('subtitle'),
                       HistoriqueBlocage.bloque.alias('cause'),
                       Product.pk.alias('address_pk'),
                       CodeBlocage.libelle.alias('designation'))
               .join(Adresse, on=Adresse.adresse == HistoriqueBlocage.adresse)
               .join(Product, on=Product.reference == HistoriqueBlocage.reference)
               .join(Magasin, on=Adresse.magasin == Magasin.mag)
               .join(CodeBlocage, JOIN.LEFT_OUTER, on=HistoriqueBlocage.bloque == CodeBlocage.valeur)
               .where(andexpr & (HistoriqueBlocage.bloque != 0) & (HistoriqueBlocage.reference != ''))
               .group_by(HistoriqueBlocage.reference, HistoriqueBlocage.bloque, fn.YEAR(HistoriqueBlocage.chrono),
                         fn.WEEKOFYEAR(HistoriqueBlocage.chrono)))

    return req.order_by(HistoriqueBlocage.chrono.desc())
