from flask import Blueprint, request
from flask_jwt_extended import jwt_required
from median.models import Magasin, Historique, Product, Stock, Adresse

from peewee import JOIN

astus_drawer_blueprint = Blueprint('astus_drawer', __name__)


def get_obj_locations(i):
    return {
        'store': i.magasin,
        'pk': i.pk,
        'adress': i.adresse,
        'format': i.format,
        'lock': i.bloque,
        'replenish_lock': i.bloque_reappro,
        'container': i.contenant
    }


def getObjStock(stk):
    obj = {
        'pk': stk.pk,
        'magasin': stk.magasin.libelle,
        'code': stk.magasin.mag,
        'zone_admin': stk.zone_admin,
        'adress': stk.adresse,
        'reference': stk.reference,
        'batch_number': stk.lot,
        'quantity': stk.quantite,
        'container': stk.contenant,
        'expiration_date': stk.date_peremption.strftime('%Y-%m-%d'),
        'entry_date': stk.date_entree.strftime('%Y-%m-%dT%H:%M:%S'),
    }

    return obj


@astus_drawer_blueprint.route('', methods=['GET'])
@jwt_required()
def get_drawer():
    data = request.args
    drawer_code = data['code']
    magasin_alias = Magasin.alias('magasin_stock')
    magasin_adressAlias = Magasin.alias('magasin_adress')
    product_alias = Product.alias('product_stock')
    product_adressAlias = Product.alias('product_adress')

    req = Historique.select(Historique.contenant, Historique.adresse.alias('histo_adr'), Historique.reference,
                            Historique.fraction, Historique.type_mouvement, Historique.adresse_from,
                            Historique.quantite_totale, Historique.quantite_demande,
                            Historique.quantite_mouvement, Historique.quantite_prescrite,
                            Historique.quantite_totale_lot, Historique.info,
                            Historique.liste, Historique.service, Historique.id_pilulier,
                            Historique.ucd, Historique.lot, Historique.utilisateur, Historique.poste,
                            Historique.date_peremption, Historique.serial, Historique.chrono,
                            Magasin.mag, Magasin.libelle, Product.designation,
                            Stock, magasin_alias.mag, magasin_alias.libelle, Adresse,
                            magasin_adressAlias.mag, magasin_adressAlias.libelle,
                            product_alias.designation.alias('stock_designation'),
                            Adresse.emplacement,
                            product_adressAlias.designation.alias('adress_designation')) \
        .join(Magasin, JOIN.LEFT_OUTER, on=Historique.adresse.startswith(Magasin.mag)) \
        .switch(Historique) \
        .join(Product, JOIN.LEFT_OUTER, on=Historique.reference == Product.reference) \
        .switch(Historique) \
        .join(Adresse, JOIN.LEFT_OUTER, on=Historique.contenant == Adresse.contenant) \
        .join(magasin_adressAlias, JOIN.LEFT_OUTER, on=(Adresse.magasin == magasin_adressAlias.mag)) \
        .join(product_adressAlias, JOIN.LEFT_OUTER, on=(Adresse.emplacement == product_adressAlias.reference)) \
        .switch(Historique) \
        .join(Stock, JOIN.LEFT_OUTER, on=Historique.contenant == Stock.contenant) \
        .join(magasin_alias, JOIN.LEFT_OUTER, on=(Stock.magasin == magasin_alias.mag)) \
        .join(product_alias, JOIN.LEFT_OUTER, on=(Stock.reference == product_alias.reference)) \
        .where((Historique.contenant == drawer_code)) \
        .order_by(Historique.chrono.desc())

    drawer = {'historic': [], 'stock': {}, 'adress': {}}

    if req.exists():
        stock = None
        for i in req:
            drawer['container'] = i.contenant

            if stock is None:
                stock = {}
                stk = i.stock if hasattr(i, 'stock') else None
                adr = i.adresse if hasattr(i, 'adresse') else None

                if adr is not None:
                    stock['magasin'] = adr.magasin.libelle
                    stock['code'] = adr.magasin.mag
                    stock['adress'] = adr.adresse
                    stock['format'] = adr.format
                    stock['lock'] = adr.bloque
                    stock['replenish_lock'] = adr.bloque_reappro
                    stock['container'] = adr.contenant
                    if hasattr(adr.magasin, 'product'):
                        stock['designation'] = adr.magasin.product.adress_designation,
                        stock['designation'] = stock['designation'][
                            0]  # <= Un tuple est généré pour une raison inconnue

                if stk is not None:
                    stock['magasin'] = stk.magasin.libelle
                    stock['code'] = stk.magasin.mag
                    stock['adress'] = stk.adresse
                    stock['reference'] = stk.reference
                    if hasattr(stk.magasin, 'product'):
                        stock['designation'] = stk.magasin.product.stock_designation,
                        stock['designation'] = stock['designation'][
                            0]  # <= Un tuple est généré pour une raison inconnue
                    stock['zone_admin'] = stk.zone_admin
                    stock['batch_number'] = stk.lot
                    stock['quantity'] = stk.quantite
                    stock['container'] = stk.contenant
                    stock['expiration_date'] = stk.date_peremption.strftime('%Y-%m-%d')
                    stock['entry_date'] = stk.date_entree.strftime('%Y-%m-%dT%H:%M:%S')

                drawer['stock'] = stock

            histo = {
                'pk': i.pk,
                'magasin': i.magasin.libelle if hasattr(i, 'magasin') else '',
                'code': i.magasin.mag if hasattr(i, 'magasin') else '',
                'chrono': str(i.chrono),
                'reference': i.reference,
                'designation': (i.product.designation if hasattr(i, 'product') else ''),
                'fraction': i.fraction,
                'type_mouvement': i.type_mouvement,
                'adresse': i.histo_adr,
                'adresse_from': i.adresse_from,
                'quantite_mouvement': i.quantite_mouvement,
                'quantite_prescrite': (i.quantite_demande if (i.type_mouvement == 'CPE') or (i.type_mouvement == 'ENT')
                                       else i.quantite_prescrite),
                'quantite_totale': i.quantite_totale,
                'info': i.info,
                'liste': i.liste,
                'service': i.service,
                'patient': (i.patient.nom + " " + i.patient.prenom if hasattr(i, 'patient') else ''),
                'pilulier': i.id_pilulier,
                'lot': i.lot,
                'ucd': i.ucd,
                'utilisateur': i.utilisateur,
                'poste': i.poste,
                'date_peremption': str(i.date_peremption or ''),
                'serial': i.serial,
                'contenant': i.contenant
            }

            drawer['historic'].append(histo)

        return {
            'data': drawer
        }, 200
    else:
        return {'alertMessage': 'astus.drawer_search.empty',
                'param': [drawer_code]
                }, 200
