import os
import logging
import requests
import cups
from weasyprint import HTML, CSS
from weasyprint.text.fonts import FontConfiguration
from requests.adapters import Retry
import uuid

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 'Notfallgeschehen' in parsed_body:
                    req_string +="&message={}".format(parsed_body['Notfallgeschehen']) 
                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"
                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 cups_print(parsed_body: dict, body: str):
    html = HTML(string='<html><head></head><body>'+body+"</body></html>", base_url="")
    font_config = FontConfiguration()
    pdf = html.write_pdf(font_config=font_config,stylesheets=[CSS(string='body { font-family: serif !important }')])
    fname = "/tmp/{}.pdf".format(uuid.uuid4())
    
    if os.environ.get('IS_DEV') and os.environ.get('IS_DEV') == "True":
        with open("{}.pdf".format(uuid.uuid4()),"wb") as f:
            f.write(pdf)
    try:
        conn = cups.Connection ()
        printer_arr = os.environ.get('printer',"DEFAULT").split(";")
        print_num = int(os.environ.get('print_num',0))
        for printer in printer_arr:
            if 'ALARMDEPESCHE' in parsed_body:
                with open(fname,"wb") as f:
                    f.write(pdf)
                for i in range(0, print_num):
                    conn.printFile (printer, fname, "Alarmfax", {})
                os.remove(fname)
    except Exception as e:
        if os.path.exists(fname):
            os.remove(fname)
        logging.error("cups_print", e)