from __future__ import absolute_import
import requests
import xmltodict
import time
import threading
from datetime import datetime, timedelta
from dostadmin import app, db, app_logger
from utils.helpers.helpers import get_current_utc_time
from dostadmin.db_model import Campaign

exotel_sid = app.config["EXOTEL_SID"]
exotel_token = app.config["EXOTEL_TOKEN"]
exotel_call_recording_api_key = app.config["EXOTEL_CALL_RECORDING_API_KEY"]
exotel_call_recording_token = app.config["EXOTEL_CALL_RECORDING_TOKEN"]
admin_server_ip = app.config["ADMIN_SERVER"]
exotel_phone = app.config["EXOTEL_PHONE"]


def make_call(phone, exo_appid, trial=0, ignore_check=False, exo_phone="01140844944"):
    app_logger.info(
        "Exotel Helper: Calling %s with appid %s and trial %d", phone, exo_appid, trial
    )
    # adding time check
    # Calls allowed only between 8.00 AM and 10.00 PM
    istnow = get_current_utc_time() + timedelta(hours=5, minutes=30)
    now_hm = istnow.time().strftime("%H:%M").split(":")
    if ignore_check or (int(now_hm[0]) >= 8 and int(now_hm[0]) <= 22):
        try:
            r = requests.post(
                "https://"
                + exotel_sid
                + ":"
                + exotel_token
                + "@twilix.exotel.in/v1/Accounts/"
                + exotel_sid
                + "/Calls/connect",
                data={
                    "From": phone,
                    "CallerId": exo_phone,
                    "CallType": "trans",
                    "Url": "http://my.exotel.com/exoml/start/" + str(exo_appid),
                    "TimeLimit": "180",
                    "MaxRetries": "0",
                    "StatusCallback": "https://"
                    + admin_server_ip
                    + "/autocallciff/"
                    + str(exo_appid)
                    + "/"
                    + str(trial),
                },
            )
            app_logger.info(
                "Exotel Helper: Exotel response while making call to number %s: %s",
                phone,
                xmltodict.parse(r.text),
            )
        except Exception as error:
            app_logger.error(
                f"Exotel Helper: Exception occurred from Exotel call while making call to number {phone}. Error messege: {error}"
            )
    else:
        app_logger.warning(
            "Exotel Helper: Out of time range Error: %s. Not calling %s with appid %s",
            ":".join(now_hm),
            phone,
            exo_appid,
        )


def make_live_call(user_phone, agent_phone, exotel_phone, campaign):
    try:
        data = {
            "From": agent_phone,
            "To": user_phone,
            "CallerId": exotel_phone,
            "CallType": "trans",
            "Record": "true",
            "RecordingUrl": "true",
            "StatusCallback": "https://"
            + admin_server_ip
            + "/livecall/"
            + str(campaign.id),
        }

        r = requests.post(
            "https://"
            + exotel_call_recording_api_key
            + ":"
            + exotel_call_recording_token
            + "@api.exotel.com/v1/Accounts/"
            + exotel_sid
            + "/Calls/connect",
            data=data,
        )
        app_logger.info(
            "Exotel Helper: Exotel response while making live call to number %s: %s",
            user_phone,
            xmltodict.parse(r.text),
        )
        if r.status_code == requests.codes.ok:
            response_data = xmltodict.parse(r.content)["TwilioResponse"]["Call"]
            campaign.callsid = response_data["Sid"]
            campaign.attempted_timestamp = datetime.strptime(
                response_data["DateUpdated"], "%Y-%m-%d %H:%M:%S"
            )
            campaign.call_status = response_data["Status"]
            campaign.call_start_time = datetime.strptime(
                response_data["StartTime"], "%Y-%m-%d %H:%M:%S"
            )
            db.session.commit()
            return True, ""

        if r.status_code == requests.codes.forbidden:
            campaign.status = Campaign.Status.FAILED_DND
            db.session.commit()
            return False, "DND"

        campaign.status = Campaign.Status.FAILED_SYSTEM
        db.session.commit()
        return False, "FAILED"
    except Exception as error:
        app_logger.error(
            f"Exotel Helper: Exotel call exception while making live call to phone number {user_phone}. Error message: {error}"
        )
        return False, "FAILED"


def schedule_feedback_call(user_phone, exotel_phone, exo_appid, campaign):
    try:
        data = {
            "From": user_phone,
            "CallerId": exotel_phone,
            "CallType": "trans",
            "Url": "http://my.exotel.com/exoml/start/" + str(exo_appid),
            "TimeLimit": "180",
            "MaxRetries": "0",
            "StatusCallback": "https://"
            + admin_server_ip
            + "/livecall/"
            + str(campaign.id),
        }

        r = requests.post(
            "https://"
            + exotel_sid
            + ":"
            + exotel_token
            + "@api.exotel.com/v1/Accounts/"
            + exotel_sid
            + "/Calls/connect",
            data=data,
        )
        app_logger.info(
            "Exotel Helper: Exotel response while making feedback call to number %s: %s",
            user_phone,
            xmltodict.parse(r.text),
        )
        response_data = xmltodict.parse(r.content)["TwilioResponse"]["Call"]
        campaign.callsid = response_data["Sid"]
        campaign.attempted_timestamp = datetime.strptime(
            response_data["DateUpdated"], "%Y-%m-%d %H:%M:%S"
        )
        campaign.call_status = response_data["Status"]
        campaign.call_start_time = datetime.strptime(
            response_data["StartTime"], "%Y-%m-%d %H:%M:%S"
        )
        db.session.commit()
    except Exception as error:
        app_logger.error(
            f"Exotel Helper: Exotel call exception while making feedback call to phone number {user_phone}. Error message: {error}"
        )


# https://~exotel_sid~:~exotel_token~@twilix.exotel.in/v1/Accounts/~exotel_sid~/Calls/<CallSid>
def get_calldetails(callsid):
    r = requests.get(
        "https://"
        + exotel_sid
        + ":"
        + exotel_token
        + "@twilix.exotel.in/v1/Accounts/"
        + exotel_sid
        + "/Calls/"
        + callsid
    )
    calldict = xmltodict.parse(r.text)["TwilioResponse"]["Call"]
    return calldict["From"]


def retry_call(callsid, status, appid, trial):
    phone = get_calldetails(callsid)
    app_logger.info(
        "Exotel Helper: Scheduling backup call at - %s to %s", time.time(), phone
    )
    threading.Timer(1200, make_call, [phone, appid, int(trial) + 1]).start()


def missed_callback(phone, exo_phone):
    from dostadmin import db_helper

    if len(phone) > 10 and phone[0] == "0":
        phone = phone[1:]
    appid = db_helper.get_appid_for_userphone(phone, exo_phone)
    make_call(phone, appid, trial=3, ignore_check=True)


# https://~exotel_sid~:~exotel_token~@twilix.exotel.in/v1/Accounts/~exotel_sid~/Numbers/~number~
def check_dnd(plist):
    phoneinfo = []
    for phone in plist:
        r = requests.get(
            "https://"
            + exotel_sid
            + ":"
            + exotel_token
            + "@twilix.exotel.in/v1/Accounts/"
            + exotel_sid
            + "/Numbers/"
            + phone
        )
        phoneinfo.append(xmltodict.parse(r.text)["TwilioResponse"]["Numbers"])
    return phoneinfo


#  https://<sid>:<token>@twilix.exotel.in/v1/Accounts/<sid>/CustomerWhitelist/
def whitelist_numbers(phones):
    requests.post(
        "https://"
        + exotel_sid
        + ":"
        + exotel_token
        + "@twilix.exotel.in/v1/Accounts/"
        + exotel_sid
        + "/CustomerWhitelist",
        data={"VirtualNumber": exotel_phone, "Number[]": phones},
    )
