import os
import logging
import requests
import cups
from weasyprint import HTML
from requests.adapters import Retry
import uuid
import subprocess
import datetime
import time

retries = Retry(total=5,
                backoff_factor=0.1,
                status_forcelist=[ 500, 502, 503, 504 ])

def webhook(parsed_body: dict):
    try:
        webhooks = os.environ.get('webhooks').split(";") if os.environ.get('webhooks') else []
        for webhook in webhooks:
            logging.info("POST zu {}".format(webhook))
            s = requests.Session()
            s.mount('https://', requests.adapters.HTTPAdapter(max_retries=retries))
            s.post(webhook,json=parsed_body)
    except Exception as e:
        logging.error("alarminator_api", e)

def alarminator_api(parsed_body: dict):
    try:
        alarminator_api = os.environ.get('alarminator_api') if os.environ.get('alarminator_api') else ""
        alarminator_token = os.environ.get('alarminator_token') if os.environ.get('alarminator_token') else ""
        alarminator_zvies_use_PEALGRP = True if os.environ.get('alarminator_zvies_use_PEALGRP') == 'True' else False
        maps_api_key = os.environ.get('MAPS_API_KEY',"")
        if alarminator_api != "" and alarminator_token != "":
            if 'ALARMDEPESCHE' in parsed_body: # sendAlarm triggern
                logging.info("GET zu {}/operations/sendAlarm".format(alarminator_api))
                s = requests.Session()
                s.mount('https://', requests.adapters.HTTPAdapter(max_retries=retries))
                req_string = ""
                req_string +="?token={}".format(alarminator_token)
                if 'Einsatzbeginn(Soll)' in parsed_body:
                    req_string +="&alarmdate={}".format(parsed_body['Einsatzbeginn(Soll)'].split(" ")[0]) 
                    req_string +="&alarmtime={}".format(parsed_body['Einsatzbeginn(Soll)'].split(" ")[1])
                if 'Auftragsnummer' in parsed_body and not (os.environ.get('IS_DEV') and os.environ.get('IS_DEV') == "True"):
                    req_string +="&operationnumber={}".format(parsed_body['Auftragsnummer']) 
                if 'Sachverhalt' in parsed_body:
                    req_string +="&message={}".format(parsed_body['Sachverhalt']) 
                if 'Einsatzziel' in parsed_body:
                    if 'Stadt' in parsed_body['Einsatzziel']:
                        req_string +="&community={}".format(parsed_body['Einsatzziel']['Stadt'])
                    if 'PLZ / Ort' in parsed_body['Einsatzziel']:
                        req_string +="&location={}".format(parsed_body['Einsatzziel']['PLZ / Ort'])
                    if 'Objekt' in parsed_body['Einsatzziel']:
                        req_string +="&object={}".format(parsed_body['Einsatzziel']['Objekt'])
                    street = []
                    if 'Strasse' in parsed_body['Einsatzziel']:
                        street.append(parsed_body['Einsatzziel']['Strasse']) 
                    if 'Zusatz Strasse' in parsed_body['Einsatzziel']:
                        street.append(parsed_body['Einsatzziel']['Zusatz Strasse']) 
                    if 'Strasse / Hs.-Nr.' in parsed_body['Einsatzziel']:
                        street.append(parsed_body['Einsatzziel']['Strasse / Hs.-Nr.'])
                    if 'Info' in parsed_body['Einsatzziel']:
                        street.append(parsed_body['Einsatzziel']['Info'])
                    if street.__len__() > 0:
                        req_string +="&street={}".format("\n".join(street))
                
                if 'Einsatzmittelliste' in parsed_body:
                    gear = []
                    for r in parsed_body['Einsatzmittelliste']:
                        #if r['Typ'] != 'PEALGRP':
                        if r['Ressourcen'] not in gear:
                            gear.append(r['Ressourcen'])
                    req_string +="&gear={}".format(';'.join(gear))

                req_string +="&district={}".format('district')
                req_string +="&floor={}".format('floor')
                req_string +="&section={}".format('section')
                req_string +="&keywordRaw={}".format(parsed_body['Einsatzstichwort'])
                #req_string +="&keywordId={}".format('keywordId')
                req_string +="&keywordCategory={}".format(parsed_body['Einsatzstichwort'].split("(")[0])
                req_string +="&keywordName={}".format(parsed_body['Einsatzstichwort'].split("(")[1].split(")")[0])
                if alarminator_zvies_use_PEALGRP:
                    if 'Einsatzmittelliste' in parsed_body:
                        zveis = []
                        for r in parsed_body['Einsatzmittelliste']:
                            if r['Typ'] == 'PEALGRP':
                                zveis.append(r['Ressourcen'])
                        req_string +="&zveis={}".format(';'.join(zveis))
                else:
                    req_string +="&zveis={}".format(parsed_body['ALARMDEPESCHE'])
                
                if maps_api_key != "":
                    try:
                        maps_address_param = []
                        if 'Objekt' in parsed_body['Einsatzziel']:
                            maps_address_param.append("{}".format(parsed_body['Einsatzziel']['Objekt']))
                        
                        if street.__len__() > 0:
                            maps_address_param.append('{}'.format(",".join(street)))
                        if 'Stadt' in parsed_body['Einsatzziel']:
                            maps_address_param.append("{}".format(parsed_body['Einsatzziel']['Stadt']))
                        if 'PLZ / Ort' in parsed_body['Einsatzziel']:
                            maps_address_param.append("{}".format(parsed_body['Einsatzziel']['PLZ / Ort']))
                        
                        maps_request = requests.get('https://maps.google.com/maps/api/geocode/json?address={}&key={}'.format(','.join(maps_address_param),maps_api_key))
                        if maps_request.json()['results'].__len__() == 1:
                            req_string +="&lat={}".format(maps_request.json()['results'][0]['geometry']['location']['lat'])
                            req_string +="&lon={}".format(maps_request.json()['results'][0]['geometry']['location']['lng'])
                    except Exception as maps_e:
                        logging.error('error getting maps',maps_e)
                    
                # req_string +="&gkx={}".format() if False
                # req_string +="&gky={}".format() if False
                #  if False
                # req_string +="&lon={}".format() if False
                subject = ""
                if 'Notfallgeschehen' in parsed_body:
                    subject = parsed_body['Notfallgeschehen'] + "\n"
                if 'Notfallgeschehen' in parsed_body:
                    subject = parsed_body['Notfallgeschehen'] + "\n"
                req_string +="&subject={}".format(subject)
                req_string +="&ils={}".format("ILS Saar")
                req_string +="&connector={}".format("MailParser")
                if os.environ.get('IS_DEV') and os.environ.get('IS_DEV') == "True":
                    req_string +="&isTest=1"
                s.get(alarminator_api+"/operations/sendAlarm/"+req_string)
    except Exception as e:
        logging.error("alarminator_api", e)

def generate_pdf(html_body, filename):
    f = "/tmp/{}.html".format(uuid.uuid4())
    with open(f,"w") as _f:
        _f.write(html_body)
    subprocess.run(["/usr/bin/google-chrome-stable", "--headless", "--no-sandbox", "--disable-gpu", "--print-to-pdf="+filename, "--no-pdf-header-footer", "--print-to-pdf-no-header", "--no-margins", f])
    if os.path.exists(f):
        os.remove(f)

def cups_print(parsed_body: dict, body: str):
    # if os.environ.get('IS_DEV') and os.environ.get('IS_DEV') == "True":
    #     generate_pdf(body, "{}.pdf".format(uuid.uuid4()))
    fname = "{}.pdf".format(uuid.uuid4())
    try:
        conn = cups.Connection ()
        printer_arr = os.environ.get('printer',"DEFAULT").split(";")
        print_num = int(os.environ.get('print_num',0))
        #if printer_arr.__len__() > 0:
        generate_pdf(body, fname)
        for printer in printer_arr:
            print(printer)
            if 'ALARMDEPESCHE' in parsed_body:
                for i in range(0, print_num):
                    conn.printFile (printer, fname, "Alarmfax", {})
    except Exception as e:
        logging.error("cups_print", e)
    finally:
        if os.path.exists(fname):
            os.remove(fname)

            
def divera_messenger(parsed_body: dict):
    # /api/v2/alarms
    # message-channels?accesskey=XXX
    
    try:
        api = "https://app.divera247.com/api/v2/"
        messenger_api_token = os.environ.get('DIVERA_MESSANGER_API_KEY') if os.environ.get('DIVERA_MESSANGER_API_KEY') else ""
        alarmer_api_token = os.environ.get('DIVERA_ALARMER_API_KEY') if os.environ.get('DIVERA_ALARMER_API_KEY') else ""
        if messenger_api_token != "":
            if 'ALARMDEPESCHE' in parsed_body: # sendAlarm triggern
                if 'Einsatzmittelliste' in parsed_body:
                    
                    zveis = []
                    message = "Alarmierte Einsatzmittel:\n"
                    for r in parsed_body['Einsatzmittelliste']:
                        if r['Typ'] == 'PEALGRP':
                            zveis.append(r['Ressourcen'])
                    message +='\n'.join(zveis)
                    if 'Zusatztext zum Ort' in parsed_body:
                        message += "\n\nZusatztext zum Ort:\n"+parsed_body['Zusatztext zum Ort']
                    if 'Zusatztext zum Objekt' in parsed_body:
                        message += "\n\nZusatztext zum Objekt:\n"+parsed_body['Zusatztext zum Objekt']
                        
                    logging.info("GET zu {}alarms?accesskey=XXX".format(api))
                    s = requests.Session()
                    s.mount('https://', requests.adapters.HTTPAdapter(max_retries=retries))
                    start = datetime.datetime.now()
                    message_channel_id = None
                    alarm_id = None
                    alarm_text = None
                    while message_channel_id is None and datetime.datetime.now() < start + datetime.timedelta(minutes=1):
                        r = s.get("{}alarms?accesskey={}".format(api, messenger_api_token))
                        r_json = r.json()
                        if 'items' in r_json.get('data',{}):
                            for item in r_json.get('data',{})['items']:
                                if str(r_json['data']['items'][item]['foreign_id']) == str(parsed_body['Auftragsnummer']):
                                    logging.info("EinsatzNr {} in Divera gefunden, sende Nachricht...".format(r_json['data']['items'][item]['foreign_id']))
                                    message_channel_id = r_json['data']['items'][item]['message_channel_id']
                                    alarm_id = r_json['data']['items'][item]['id']
                                    alarm_text = r_json['data']['items'][item]['text']
                        if message_channel_id is None or alarm_id is None:
                            time.sleep(20)
                    
                    if alarmer_api_token != "":
                        if alarm_text is None:
                            alarm_text = ""
                        r = s.put("{}alarms/{}?accesskey={}".format(api, alarm_id, alarmer_api_token),json={
                            "Alarm": {
                                "text": alarm_text+"\n\n"+message,
                            }
                        })


                    if message_channel_id:
                        r = s.post("{}messages?accesskey={}".format(api, messenger_api_token),json={
                            "Message": {
                                "message_channel_id": str(message_channel_id),
                                # "parent_id": 0,
                                "text": message,
                            }
                        })
                        pass
    except Exception as e:
        logging.error("divera_messenger", e)
