import frappe
from custom_ui.services import DbService, StripeService
from dataclasses import dataclass
from custom_ui.models import PaymentData
    


class PaymentService:
    
    @staticmethod
    def create_payment_entry(data: PaymentData) -> frappe._dict:
        """Create a Payment Entry document based on the reference document."""
        print(f"DEBUG: Creating Payment Entry for {data.reference_doc_name} with data: {data}")
        reference_doctype = PaymentService.determine_reference_doctype(data.reference_doc_name)
        reference_doc = DbService.get_or_throw(reference_doctype, data.reference_doc_name)
        account = StripeService.get_stripe_settings(data.company).custom_account
        pe = frappe.get_doc({
            "doctype": "Payment Entry",
            "company": data.company,
            "payment_type": "Receive",
            "party_type": "Customer",
            "mode_of_payment": data.mode_of_payment or "Stripe",
            "party": reference_doc.customer,
            "party_name": reference_doc.customer,
            "paid_to": account,
            "reference_no": data.reference_no,
            "reference_date": data.reference_date or frappe.utils.nowdate(),
            "paid_amount": data.received_amount,
            "received_amount": data.received_amount,
            "paid_currency": "USD",
            "received_currency": "USD",
            "references": [{
                "reference_doctype": reference_doc.doctype,
                "reference_name": reference_doc.name,
                "allocated_amount": data.received_amount,
            }]
        })
        pe.insert()
        print(f"DEBUG: Created Payment Entry with name: {pe.name}")
        return pe
    
    @staticmethod
    def determine_reference_doctype(reference_doc_name: str) -> str:
        """Determine the reference doctype based on the document name pattern."""
        print(f"DEBUG: Determining reference doctype for document name: {reference_doc_name}")
        if DbService.exists("Sales Order", reference_doc_name):
            return "Sales Order"
        elif DbService.exists("Sales Invoice", reference_doc_name):
            return "Sales Invoice"
        else:
            frappe.throw("Unable to determine reference doctype from document name.")
    