#!/usr/bin/python3
import sys
import os
from typing import Dict

sys.path.insert(0, "/usr/local/mgr5/lib/python")

import billmgr.db
import billmgr.logger as logging
import billmgr.exception
# from billmgr.exception import log_backtrace

from billmgr import payment
from billmgr.modules.paymentcgi import RegularPaymentCGI, run_cgi

from payssion.api import PayssionAPI

MODULE = "payssionpayment"
logging.init_logging(MODULE)
logger = logging.get_logger(MODULE)


class PayssionPaymentCgi(RegularPaymentCGI):
    def process(self):
        logger.info("run payment cgi")

        api_key: str = self.paymethod_params["api_key"]
        secret_key: str = self.paymethod_params["secret_key"]

        is_test: bool = False if self.paymethod_params["test"] == "off" else True

        logger.info(f"selected paymethod: {self.payment_params['pm_id']}")

        if is_test:
            pm: str = "payssion_test"
        else:
            pm: str = self.payment_params["pm_id"]

        api = PayssionAPI(api_key=api_key, secret_key=secret_key, is_test=is_test)

        logger.info(f"payment params: {self.payment_params}")

        
        # get the url if payment already exists
        if int(self.payment_params["status"]) == int(payment.PaymentStatus.psInPay.value):
            logger.info("payment already in pay")
            invoice_url = api.get_unfinished_payment_url(self.payment_params.get("externalid"), self.payment_params.get("number"))
            logger.info(f"invoice url = {invoice_url}")

            self.redirect_to_url(invoice_url)

        # else generate a new url using Payssion API (basically assuming status NEWLY_CREATED)
        else:
            paymethod = pm
            logger.info(f"paymethod_params: \n {self.paymethod_params}")
            logger.info(f"payment_params: \n {self.payment_params}")
            logger.info(f"paymethod = {paymethod}")
            amount = self.payment_params["paymethodamount"]
            order_id = self.payment_params["number"]
            description = self.payment_params["description"]

            currency = billmgr.db.get_first_record(f"""
                SELECT iso FROM currency
                WHERE id = {self.paymethod_params['currency']}
            """)

            logger.info(f"iso currency: {currency.as_str('iso')}")

            if currency is None:
                raise billmgr.exception.XmlException("payssion_missed_currency")

            try:
                invoice: Dict = api.get_invoice(
                    paymethod=paymethod,
                    amount=amount,
                    currency=currency.as_str("iso"),
                    description=description,
                    order_id=order_id,
                    return_url=(f"https://{os.environ['HTTP_HOST']}/mancgi/payssionresult"
                                 f"?elid={self.payment_params['id']}"),
                    payer_email=self.payment_params["useremail"],
                    payer_name=self.payment_params["userrealname"]
                )
            except Exception as e:
                billmgr.exception.log_backtrace()
                raise billmgr.exception.XmlException("payssion_no_url_provided") from e

            # invoice order_id of payment on Payssion is assigned to billmgr payment as externalid
            payment.set_in_pay(
                int(self.elid()),
                info="",
                external_id=str(invoice.get("transaction").get("transaction_id"))
            )

            self.redirect_to_url(str(invoice.get("redirect_url")))

if __name__ == "__main__":
    run_cgi(PayssionPaymentCgi)
