#!/usr/bin/python3

import sys
import os

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

import paypalexpanded.api as paypal_api

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

PAYMETHOD_MODULE_NAME = "pmpaypalexpanded"

class PayPalWebhookCgi(paypal_api.PayPalBaseCgi):
    def need_auth(self):
        return False

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

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

    @property
    def input_content_type(self) -> InputContentType:
        return InputContentType.Json

    def parse_input(self):
        self._payment_id = self._find_payment(self.input["resource"]["supplementary_data"]["related_ids"]["order_id"])

    def elid(self) -> str:
        return str(self._payment_id)

    def _find_payment(self, external_id: str) -> int:
        return db.get_first_record_unwrap(
            "SELECT id FROM payment WHERE paymethod IN (SELECT id FROM paymethod WHERE module = %s) AND externalid LIKE %s",
            PAYMETHOD_MODULE_NAME,
           '%' + external_id + '%',
        ).as_int("id")

    def process(self):
        self.headers = {k: v for k, v in os.environ.items() if k.startswith('HTTP_')}
        auth = self.authenticate()
        webhook_id = self.paymethod_params.get('webhook_id')

        if not paypal_api.verify_webhook_event(auth, self.headers, self.input, webhook_id):# type: ignore
            logger.error(f"webhook verification is faild")
            self.send_error("Webhook verification failed", status=401)

        event_type = self.input.get("event_type")
        logger.info(f"Received webhook event: {event_type}")
        capture_id = self.payment_params['externalid'].split('/')[1]
        external_id = self.payment_params['externalid']
        payment_id = self._payment_id


        if event_type == "PAYMENT.CAPTURE.COMPLETED":
            resource = self.input["resource"]

            if "suspended_recurring_payments" in resource.get("seller_receivable_breakdown", {}):
                self.send_error("Payment is suspended")

            response = paypal_api.request_show_captured_payment_details(auth, capture_id)
            stored_token = paypal_api.parse_captures(response)
            
            if stored_token:
                recurring_info = payment.RecurringInfo(
                    status=payment.RecurringStatus.rsStored,
                    token=stored_token,
                    data1='',
                    data2=self.payment_params['payment_method'],
                    name=''
                )
                payment.set_paid(payment_id, external_id, recurring_info)
            else:
                payment.set_paid(payment_id, external_id)

            logger.info(f"Payment {payment_id} marked as paid via webhook")
            self.send_ok()

        elif event_type == "PAYMENT.CAPTURE.PENDING":
            payment_id = self._find_payment(capture_id)
            if payment_id:
                payment.set_in_pay(payment_id, external_id)
                logger.info(f"Payment {payment_id} marked as pending via webhook")

            self.send_ok()

        elif event_type in ("PAYMENT.CAPTURE.DENIED", "PAYMENT.CAPTURE.FAILED", "PAYMENT.CAPTURE.REFUNDED"):
            payment_id = self._find_payment(capture_id)
            if payment_id:
                logger.warning(f"Payment {payment_id} failed: {event_type}")
            self.send_ok()

        else:
            logger.info(f"Unhandled event type: {event_type}")
            self.send_ok()

    def send_ok(self):
        print("Content-Type: text/plain\n")
        print("OK")
        sys.exit(0)

    def send_error(self, msg, status=400):
        print(f"Status: {status}\nContent-Type: text/plain\n")
        print(msg)
        sys.exit(1)


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