import base64
import hashlib
import hmac
import urllib.parse
from datetime import datetime, timedelta

import requests

from DepoT.settings import env


class EPay:
    payment_types = {
        "pay_credit_card": "credit_paydirect",
        "pay_epay": "paylogin",
    }

    @staticmethod
    def encode_message(message):
        encoded_data = base64.b64encode(message.encode("utf-8")).decode("utf-8")
        secret_key = env("EPAY_SECURITY_KEY")
        checksum = hmac.new(
            secret_key.encode("utf-8"), encoded_data.encode("utf-8"), hashlib.sha1
        ).hexdigest()
        return encoded_data, checksum

    @classmethod
    def generate_urls(self, invoice, amount):
        client_id = env("EPAY_CLIENT_ID")
        description = f"Invoice number: {invoice} with amount of {amount}"
        currency = "BGN"
        expiry = (
            datetime.today() + timedelta(days=int(env("INVOICE_EXPIRE_PERIOD")))
        ).strftime("%d.%m.%Y")

        if amount == 0:
            amount = 1000

        message = f"MIN={client_id}\nINVOICE={invoice}\nAMOUNT={amount}\nCURRENCY={currency}\nEXP_TIME={expiry}\nDESCR={description}"
        encoded_data, checksum = EPay.encode_message(message)
        result = {}
        for pay_type, keyword in EPay.payment_types.items():
            url = f"https://demo.epay.bg/?PAGE={keyword}&ENCODED={urllib.parse.quote(encoded_data)}&CHECKSUM={urllib.parse.quote(checksum)}"
            result[pay_type] = url
        return result

    @staticmethod
    def payment_result(encoded_data, checksum_received):
        secret_key = env("EPAY_SECURITY_KEY")
        decoded_data = base64.b64decode(encoded_data).decode("utf-8")
        checksum_calculated = hmac.new(
            secret_key.encode("utf-8"), encoded_data.encode("utf-8"), hashlib.sha1
        ).hexdigest()
        checksum_result = checksum_calculated == checksum_received

        fields = decoded_data.split(":")
        fields_dict = {}
        for field in fields:
            try:
                name, value = field.split("=")
            except ValueError:
                print(fields)
                print(field)

            fields_dict[name] = value

        return fields_dict, checksum_result

    @staticmethod
    def send_response(encoded_data, checksum):
        url = f"https://demo.epay.bg/?ENCODED={urllib.parse.quote(encoded_data)}&CHECKSUM={urllib.parse.quote(checksum)}"
        print(url)
        res = requests.post(url)

    @staticmethod
    def send_ok(invoice):
        message = f"INVOICE={invoice}:STATUS=OK"
        encoded_data, checksum = EPay.encode_message(message)
        print(f"OK {invoice}")
        EPay.send_response(encoded_data, checksum)

    @staticmethod
    def send_no(invoice):
        message = f"INVOICE={invoice}:STATUS=NO"
        encoded_data, checksum = EPay.encode_message(message)
        print(f"NO {invoice}")
        EPay.send_response(encoded_data, checksum)

    @staticmethod
    def send_err(invoice):
        message = f"INVOICE={invoice}:STATUS=ERR:ERR=BAD_CHECKSUM"
        encoded_data, checksum = EPay.encode_message(message)
        print(f"ERR {invoice}")
        EPay.send_response(encoded_data, checksum)
