import json
import logging
from datetime import datetime

from common.status import HTTP_200_OK, HTTP_500_INTERNAL_SERVER_ERROR
from flask import Blueprint, request
from flask_jwt_extended import jwt_required, get_jwt_identity
from median.constant import EtatListe
from median.models import FListe, FItem, WorkItemModel, User, Magasin
from peewee import DoesNotExist

from ressources.blueprint.external.replenishService import get_replenish_list
from ressources.blueprint.external.external_blueprint import test_med, supply


external_replenish_blueprint = Blueprint('external_replenish', __name__)

logger = logging.getLogger('median')


@external_replenish_blueprint.route('count', methods=['POST'])
@jwt_required()
def count():
    c = get_replenish_list().count()

    return {"data": c}, HTTP_200_OK


@external_replenish_blueprint.route('all', methods=['POST'])
@jwt_required()
def get_all():
    data = json.loads(request.data)

    page = data['pageNumber']
    page_size = data['rowsPerPage']

    lis = (get_replenish_list()
           .limit(page_size).offset(page * page_size)
           .order_by(FListe.date_creation.desc(), FListe.zone_fin))

    logger.info('Récupérer les listes de réappro ACCED... %s' % lis.count())
    return {"list": [{'pk': li.pk,
                      'label': li.liste,
                      'equipment': {
                          'pk': li.equipment_pk,
                          'mag': li.equipment_mag,
                          'label': li.equipment_label,
                          'avatar': li.equipment_avatar
                      },
                      'date_creation': str(li.date_creation)} for li in lis.objects()]}, HTTP_200_OK


@external_replenish_blueprint.route('/testmed/<string:liste_pk>', methods=['GET'])
@jwt_required()
def verif_med(liste_pk):
    item = test_med()

    if item[1] == HTTP_200_OK:
        try:
            replenish_item = (
                FItem.select()
                     .join(FListe, on=FListe.liste == FItem.liste)
                     .where(
                            (FListe.pk == liste_pk) &
                            (FItem.reference == item[0]['reference']) &
                            (FItem.fraction == item[0]['fraction'])
                     )).get()
            remaind = replenish_item.qte_dem - replenish_item.qte_serv
            item[0]['remaind'] = remaind if remaind > 0 else 0

        except DoesNotExist:
            item = {'alertMessage': 'external.scanmed.error.list.notexist'}, HTTP_500_INTERNAL_SERVER_ERROR

    return item


@external_replenish_blueprint.route('<string:liste_pk>', methods=['POST'])
@jwt_required()
def replenish(liste_pk):

    data = json.loads(request.data)
    reference = data['reference']
    fraction = data.get('fraction', 100)
    quantity = int(data['quantity'])
    expiration = datetime.strptime(data['selectedExpirationDate'], '%Y-%m-%d').date()
    batch = data['selectedBatch']
    cip = data['selectedCIP']
    location = data['location']
    serial = data['selectedSerial']

    identity = get_jwt_identity()

    usr = User.get(User.pk == identity)

    equipment = (
        Magasin.select(Magasin.pk)
        .join(FListe, on=FListe.zone_fin == Magasin.type_mag)
        .where(FListe.pk == liste_pk).get())

    try:
        item_list = (
            FItem.select()
            .join(FListe, on=FListe.liste == FItem.liste)
            .where((FListe.pk == liste_pk) &
                   (FItem.reference == reference) &
                   (FItem.fraction == fraction))).get()
    except DoesNotExist:
        return {'alertMessage': 'external.scanmed.error.list.notexist'}, HTTP_500_INTERNAL_SERVER_ERROR

    item_list.qte_serv = item_list.qte_serv + quantity
    item_list.etat = EtatListe.EnCours.value if item_list.qte_serv + quantity < item_list.qte_dem \
        else EtatListe.Solde.value
    item_list.save()

    work_item = WorkItemModel()
    work_item.fraction = fraction
    work_item.reference = reference
    work_item.adresse = location
    work_item.quantite_dem = quantity
    work_item.quantite_serv = quantity
    work_item.liste = item_list.liste
    work_item.item = item_list.item
    work_item.mode = item_list.mode
    work_item.date_peremption = expiration
    work_item.lot = batch
    work_item.cip = cip
    work_item.utilisateur = usr.username
    # work_item.contenant = item_list.contenant
    work_item.info = serial
    work_item.save()

    supply(equipment_pk=equipment.pk)

    return {}, HTTP_200_OK


@external_replenish_blueprint.route('detail/<string:item_pk>', methods=['GET'])
@jwt_required()
def get_detail_line(item_pk):
    items = (WorkItemModel
             .select(WorkItemModel.cip,
                     WorkItemModel.date_peremption,
                     WorkItemModel.lot,
                     WorkItemModel.info.alias('serial'),
                     WorkItemModel.adresse,
                     WorkItemModel.quantite_serv,
                     WorkItemModel.pk)
             .join(FItem, on=(FItem.item == WorkItemModel.item) &
                             (FItem.liste == WorkItemModel.liste))
             .where(FItem.pk == item_pk))

    return {
        "list": [{
            "cip": item.cip,
            "expiration": item.date_peremption,
            "batch": item.lot,
            "address": item.adresse,
            "serial": item.serial,
            "quantity": item.quantite_serv,
            "pk": item.pk
        }
         for item in items]
    }, HTTP_200_OK
