import json
import logging

from flask import Blueprint, request
from flask_jwt_extended import jwt_required
from median.models import Service, Config, Historique

from common.status import (
    HTTP_200_OK, HTTP_204_NO_CONTENT, HTTP_500_INTERNAL_SERVER_ERROR, HTTP_400_BAD_REQUEST, HTTP_404_NOT_FOUND)

wards_blueprint = Blueprint('services', __name__)

logger = logging.getLogger('median')


@wards_blueprint.route('all', methods=['POST'])
@jwt_required()
def get_all():
    logger.info("Récupérer les services")

    try:
        args = json.loads(request.data)
        v_limit = args.get('length', 10)
        v_offset = args.get('start', 0)

        if v_limit != -1:
            paged_services = (Service.select(Service).where(
                Service.type_dest == 'SERVICE')).limit(v_limit).offset(v_offset).order_by(
                Service.code)
        else:
            paged_services = (Service.select(Service).where(
                Service.type_dest == 'SERVICE'))

        param_tri = Config.select(Config.value).where(Config.propriete == 'k_eco_tri_pil')

        k_tri = param_tri[0].value

        return {'data': [{
            'pk': i.pk,
            'dest': i.code,
            'libelle': i.libelle,
            'type_peigne_carnet': i.type_carnet,
            'type_peigne': i.type_peigne,
            'moment_deb': i.moment_deb,
            'deb_matin': i.deb_matin,
            'deb_midi': i.deb_midi,
            'deb_soir': i.deb_soir,
            'deb_coucher': i.deb_coucher,
            'mode': i.riedl_tk_mode,
            'optim_peigne': i.optim_peigne,
            'rield_auto_print': i.riedl_unload_auto_print,
            'aideplus_completion': i.aideplus_completion,
            'tri': (i.tri if (i.tri != '') else k_tri)
        } for i in paged_services]}, HTTP_200_OK

    except Exception as error:
        logger.error(('Get services Datatables raised an exception: ', error.args))
        return {'message': error.args}, HTTP_500_INTERNAL_SERVER_ERROR


@wards_blueprint.route('', methods=['GET'])
@jwt_required()
def get_ward():
    try:
        args = request.args
        v_fonction = args.get('fonction', '0')

        if v_fonction == '1':  # We are in ward address mode for Astus
            services = (Service.select(
                Service.code, Service.libelle).distinct()
                        .join(Historique, on=(Service.code == Historique.service)).where(
                Service.type_dest == 'SERVICE').order_by(Service.code))
        else:
            services = (Service.select(Service.code, Service.libelle, Service.adr1).where(
                Service.type_dest == 'SERVICE').order_by(Service.code))

    except Exception as error:
        return {'message': error.args}, HTTP_400_BAD_REQUEST

    logger.info('Number of ward : %s.' % len(services))
    # logger.info(v_fonction)

    return ([{
        'cle': s.adr1,
        'id': s.code,
        'name': s.libelle,
        'code_et_name': f"{s.code} - {s.libelle}"
    } for s in services])


@wards_blueprint.route('', methods=['PUT'])
@jwt_required()
def update_ward():
    args = json.loads(request.data)
    try:
        v_code = args['code']
        v_libelle = args.get('libelle', 'To be defined')
        v_type_peigne = args.get('type_peigne', 0)
        v_type_peigne_carnet = args.get('type_peigne_carnet', 404)
        v_moment_deb = args.get('moment_deb', 'matin')
        v_deb_matin = args.get('deb_matin', 7)
        v_deb_midi = args.get('deb_midi', 12)
        v_deb_soir = args.get('deb_soir', 18)
        v_deb_coucher = args.get('deb_coucher', 22)
        v_tri = args.get('tri', '')
        v_pk = args['pk']
        v_mode = args.get('mode', 'NO')
        v_optim_peigne = args.get('optim_peigne', False)
        v_print_auto = args.get('rield_auto_print', 0)
        v_plus_completion = args.get('aideplus_completion', 0)
    except Exception:
        return {'message': 'ward is mandatory'}, HTTP_500_INTERNAL_SERVER_ERROR

    Service.update(
        type_carnet=v_type_peigne_carnet, optim_peigne=v_optim_peigne,
        code=v_code, libelle=v_libelle, type_peigne=v_type_peigne, moment_deb=v_moment_deb,
        deb_matin=v_deb_matin, deb_midi=v_deb_midi, deb_soir=v_deb_soir, deb_coucher=v_deb_coucher,
        tri=v_tri, riedl_tk_mode=v_mode, riedl_unload_auto_print=v_print_auto, aideplus_completion=v_plus_completion
    ).where(Service.pk == v_pk).execute()

    return {}, HTTP_204_NO_CONTENT


@wards_blueprint.route('', methods=['POST'])
@jwt_required()
def create_ward():
    args = json.loads(request.data)
    v_code = args['code']
    v_libelle = args.get('libelle', 'TO BE DEFINED!')
    v_type_peigne = args.get('type_peigne', 0)
    v_type_peigne_carnet = args.get('type_peigne_carnet', 404)
    v_moment_deb = args.get('moment_deb', 'matin')
    v_deb_matin = args.get('deb_matin', 7)
    v_deb_midi = args.get('deb_midi', 12)
    v_deb_soir = args.get('deb_soir', 18)
    v_deb_coucher = args.get('deb_coucher', 22)
    v_tri = args.get('tri', '')
    v_mode = args.get('mode', 'NO')
    v_optim_peigne = args.get('optim_peigne', False)
    v_print_auto = args.get('rield_auto_print', 0)

    nb_service = Service.select().where(Service.code == v_code).count()

    if nb_service > 0:
        return {'message': "Ward already exists, we don't create it"}, HTTP_404_NOT_FOUND

    Service.create(
        type_carnet=v_type_peigne_carnet, optim_peigne=v_optim_peigne,
        code=v_code, libelle=v_libelle, type_peigne=v_type_peigne, moment_deb=v_moment_deb,
        deb_matin=v_deb_matin, deb_midi=v_deb_midi, deb_soir=v_deb_soir, deb_coucher=v_deb_coucher,
        tri=v_tri, type_dest='SERVICE', riedl_tk_mode=v_mode, riedl_unload_auto_print=v_print_auto
    )
    return {}, HTTP_204_NO_CONTENT


@wards_blueprint.route('', methods=['DELETE'])
@jwt_required()
def delete_ward():

    try:
        args = json.loads(request.data)
        logger.info(type(args))
        v_code = args['code']
    except Exception as ex:
        logger.info(ex)
        return {'message': "Ward don't exists anymore, we cannot delete it"}, HTTP_500_INTERNAL_SERVER_ERROR
    try:
        Service.delete().where(Service.code == v_code, Service.type_dest == 'SERVICE').execute()
    except Exception:
        return {'message': "Ward don't exists anymore, we cannot delete it"}, HTTP_500_INTERNAL_SERVER_ERROR
    return {}, HTTP_204_NO_CONTENT
