#!/usr/bin/python3

import os
import sys
from typing import Optional

sys.path.insert(0, "/usr/local/mgr5/lib/python")
from billmgr.exception import log_backtrace
from billmgr.modules.paymentcgi import PageType, run_cgi, RecurringPaymentCGI
from billmgr.logger import init_logging, get_logger, Logger
from billmgr.payment import save_recurring_info, RecurringStatus, RecurringInfo

from paymaster.api.client import PayMasterAPI
from paymaster.api.parameters import RecurringGetURLParameters
from paymaster.exceptions import PayMasterException
from paymaster.utils import (
    format_email, generate_notification_token, get_notification_url, json_dict
)


MODULE: str = "paymasterv2recurring"

init_logging(MODULE)
logger: Logger = get_logger(MODULE)


class PayMasterRecurringCGI(RecurringPaymentCGI):

    def __init__(self):
        super().__init__()

        is_test_mode: bool = self.paymethod_params["testmode"] == "on"
        callback_url: Optional[str] = None
        are_notifications_enabled: bool = self.paymethod_params["allownotifications"] == "on"
        if are_notifications_enabled:
            recurring_status = RecurringStatus(int(self.recurring_params["status"]))
            is_auto_payment: bool = recurring_status is RecurringStatus.rsAdd
            callback_url = get_notification_url(
                custom_url=self.paymethod_params.get("notification_url"),
                hostname=os.environ["HTTP_HOST"],
                autopayment="yes" if is_auto_payment else None,
                recurringid=self.elid(),
                notificationtoken=generate_notification_token(
                    merchant_id=self.paymethod_params["merchant_id"],
                    api_token=self.paymethod_params["api_token"],
                    id_=int(self.elid())
                )
            )

        self.get_url_parameters = RecurringGetURLParameters(
            purpose="Create stored payment method",
            payment_method=self.paymethod_params["payment_method"],
            customer=RecurringGetURLParameters.Customer(
                account=str(self.user_params["user_id"]),
                email=format_email(self.user_params.get("email"))
            ),
            test_mode=is_test_mode,
            return_url=self.get_page(PageType.Pending),
            callback_url=callback_url
        )

    def process(self):
        logger.debug(f"user_params = {self.user_params}")
        logger.debug(f"recurring_params = {self.recurring_params}")
        logger.debug(f"currency_params = {self.currency_params}")
        logger.debug(f"paymethod_params = {self.paymethod_params}")

        try:
            api = PayMasterAPI(
                merchant_id=self.paymethod_params["merchant_id"],
                auth_token=self.paymethod_params["api_token"],
                logger=logger
            )
            response: json_dict = api.recurring.get_url(self.get_url_parameters)

            if self.is_stored_paymethod(RecurringStatus(int(self.recurring_params["status"]))):
                status = RecurringStatus.rsStoring
            else:
                status = RecurringStatus.rsAdd

            save_recurring_info(
                recurring_id=int(self.elid()),
                recurring_info=RecurringInfo(
                    name=None,
                    status=status,
                    token=response["tokenId"],  # type: ignore
                    data1=response.get("url"),  # type: ignore
                )
            )
            self.redirect_to_url(str(response.get("url")))
        except PayMasterException as error:
            logger.error(error)
            self.redirect_to_url(self.get_page(PageType.Fail))
        except Exception:
            log_backtrace()
            self.redirect_to_url(self.get_page(PageType.Fail))


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