#!/usr/bin/python3

import decimal
import sys
from string import Template

sys.path.insert(0, "/usr/local/mgr5/lib/python")
from billmgr.modules.paymentcgi import PageType, PaymentCgi, PaymentCgiType, run_cgi
import billmgr.logger as logging
import billmgr.payment as payment

import paypal.api as paypal_api

logging.init_logging('ppcheckoutrecurring')
logger = logging.get_logger('ppcheckoutrecurring')


ACTION_ORDER = 'order'

PAYMENT_FORM_FILE = 'etc/paymethods/paypal_checkout.html'

MIN_AMOUNT = decimal.Decimal('0.01')
MIN_AMOUNT_CURRENCY = 'USD'

class PayPalRecurringCgi(PaymentCgi):
    def __init__(self):
        PaymentCgi.__init__(self)

    def cgi_type(self) -> PaymentCgiType:
        return PaymentCgiType.NewRecurring

    # Для привязки без оплаты, используем схему с созданием платежа с минимальной суммой и возвратом после успешного
    # создания привязки. Дело в том, что при использовании api, который предоставляет PayPal для генерации только токена,
    # без оплаты - нет возможности использовать готовую кнопку для оплаты банковской картой, необходимо строить свою
    # кастомную форму со всеми полями для карты, вручную обрабатывать введенные данные.
    # Для простоты используем ту форму, что предоставляет сам PayPal
    def process(self):
        logger.info(f'paymethod_params = {self.paymethod_params}')
        logger.info(f'recurring_params = {self.recurring_params}')
        logger.info(f'success page = {self.get_page(PageType.Success)}')
        logger.info(f'fail page = {self.get_page(PageType.Fail)}')

        if "action" not in self.input:
            client_id = self.paymethod_params['client_id']
            with open(PAYMENT_FORM_FILE, 'r') as f:
                form = Template(f.read())
                form = form.substitute(
                    main_cgi = '/mancgi/ppcheckoutrecurring',
                    result_cgi = '/mancgi/ppcheckoutrecurringresult',
                    amount = str(MIN_AMOUNT),
                    sdk_url = paypal_api.js_paypal_sdk_url(client_id, MIN_AMOUNT_CURRENCY)
                )
                sys.stdout.write(form)

        elif self.input["action"] == ACTION_ORDER:
            auth = paypal_api.authenticate(paypal_api.AuthData(
                self.paymethod_params["client_id"],
                self.paymethod_params["secret"],
                self.paymethod_params["test"] == "on"
            ))

            response = paypal_api.request_create_order(
                auth,
                paypal_api.Order(
                    amount=MIN_AMOUNT,
                    currency_iso=MIN_AMOUNT_CURRENCY,
                    reference_id=f'r{self.elid()}',
                    need_save=True,
                    urls=paypal_api.Urls(
                        return_url=self.get_page(PageType.Success),
                        cancel_url=self.get_page(PageType.Fail),
                    )
                )
            )

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

            payment.save_recurring_info(int(self.elid()), payment.RecurringInfo(
                name='',
                status=status,
                token='',
                data1=response.json()['id'],
                data2=''
            ))

            sys.stdout.write(response.text)

    def content_type(self):
        if self.input.get("action") == ACTION_ORDER:
            return "application/json"
        else:
            return PaymentCgi.content_type(self)


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