import frappe
from custom_ui.services import DbService, AddressService, ClientService


def before_save(doc, method):
    print("DEBUG: before_save hook triggered for Sales Order", doc.name)
    if doc.docstatus == 1:
        if doc.requires_half_payment:
            half_down_is_paid = doc.custom_halfdown_is_paid or doc.advance_paid >= doc.custom_halfdown_amount or doc.advance_paid >= doc.grand_total / 2
            if half_down_is_paid and not doc.custom_halfdown_is_paid:
                doc.custom_halfdown_is_paid = 1


def before_insert(doc, method):
    print("DEBUG: Before Insert triggered for Sales Order: ", doc.name)
    if doc.custom_project_template == "SNW Install":
        print("DEBUG: Sales Order uses SNW Install template, checking for duplicates.")
        address_doc = AddressService.get_or_throw(doc.custom_job_address)
        for link in address_doc.sales_orders:
            if link.project_template == "SNW Install":
                raise frappe.ValidationError("A Sales Order with project template 'SNW Install' is already linked to this address.")
    print("DEBUG: before_insert hook triggered for Sales Order")
    if doc.requires_half_payment:
        print("DEBUG: Sales Order requires half payment, calculating half-down amount.")
        half_down_amount = doc.grand_total / 2
        doc.custom_halfdown_amount = half_down_amount
        print("DEBUG: Half-down amount set to:", half_down_amount)



def on_submit(doc, method):
    print("DEBUG: on_submit hook triggered for Sales Order:", doc.name)
    print("DEBUG: Info from Sales Order")
    print(f"Sales Order Name: {doc.name}")
    print(f"Grand Total: {doc.grand_total}")
    print(f"Company: {doc.company}")
    print(f"Requires Half Payment: {doc.requires_half_payment}")
    print(f"Customer: {doc.customer}")
    print(f"Job Address: {doc.custom_job_address}")
    print(f"Project Template: {doc.custom_project_template}")
    # Create Invoice and Project from Sales Order
    try:
        print("Creating Project from Sales Order",  doc.name)
        if doc.custom_project_template or doc.project_template:
            new_job = frappe.get_doc({
                "doctype": "Project",
                "custom_job_address": doc.custom_job_address,
                "project_name": f"{doc.custom_project_template} - {doc.custom_job_address}",
                "project_template": doc.custom_project_template,
                "custom_warranty_duration_days": 90,
                "customer": doc.customer,
                "job_address": doc.custom_job_address,
                "sales_order": doc.name,
                "requires_half_payment": doc.requires_half_payment
            })
            # attatch the job to the sales_order links
            new_job.insert()
            # frappe.db.commit()
    except Exception as e:
        print("ERROR creating Project from Sales Order:", str(e))


def after_insert(doc, method):
    print("DEBUG: after_insert hook triggered for Sales Order:", doc.name)
    AddressService.append_link_v2(
        doc.custom_job_address, "sales_orders", {"sales_order": doc.name, "project_template": doc.custom_project_template}
    )
    AddressService.append_link_v2(
        doc.custom_job_address, "links", {"link_doctype": "Sales Order", "link_name": doc.name}
    )
    ClientService.append_link_v2(
        doc.customer, "sales_orders", {"sales_order": doc.name, "project_template": doc.custom_project_template}
    )
    
    # Send down payment email if required
    if doc.requires_half_payment:
        try:
            print("DEBUG: Sales Order requires half payment, preparing to send down payment email")
            from custom_ui.services.email_service import EmailService
            
            # Use EmailService to send the down payment email
            EmailService.send_downpayment_email(doc.name)
            
        except Exception as e:
            print(f"ERROR: Failed to send down payment email: {str(e)}")
            # Don't raise the exception - we don't want to block the sales order creation
            frappe.log_error(f"Failed to send down payment email for {doc.name}: {str(e)}", "Down Payment Email Error")
        

def on_update_after_submit(doc, method):
    print("DEBUG: on_update_after_submit hook triggered for Sales Order:", doc.name)
    if doc.requires_half_payment and doc.custom_halfdown_is_paid:
        project_is_scheduable = frappe.get_value("Project", doc.project, "ready_to_schedule")
        if not project_is_scheduable:
            print("DEBUG: Half-down payment made, setting Project to ready to schedule.")
            project_doc = frappe.get_doc("Project", doc.project)
            project_doc.ready_to_schedule = 1
            project_doc.save()



def create_sales_invoice_from_sales_order(doc, method):
    pass
    # try:
        # print("DEBUG: after_submit hook triggered for Sales Order:", doc.name)
    #     invoice_ammount = doc.grand_total / 2 if doc.requires_half_payment else doc.grand_total
    #     items = []
    #     for so_item in doc.items:
    #     # proportionally reduce rate if half-payment
    #         rate = so_item.rate / 2 if doc.requires_half_payment else so_item.rate
    #         qty = so_item.qty  # usually full qty, but depends on half-payment rules
    #         items.append({
    #             "item_code": so_item.item_code,
    #             "qty": qty,
    #             "rate": rate,
    #             "income_account": so_item.income_account,
    #             "cost_center": so_item.cost_center,
    #             "so_detail": so_item.name  # links item to Sales Order
    #         })
    #     invoice = frappe.get_doc({
    #         "doctype": "Sales Invoice",
    #         "customer": doc.customer,
    #         "company": doc.company,
    #         "posting_date": frappe.utils.nowdate(),
    #         "due_date": frappe.utils.nowdate(),  # or calculate from payment terms
    #         "currency": doc.currency,
    #         "update_stock": 0,
    #         "items": items,
    #         "sales_order": doc.name,  # link invoice to Sales Order
    #         "ignore_pricing_rule": 1,
    #         "payment_schedule": doc.payment_schedule if not half_payment else []  # optional
    #     })

    #     invoice.insert()
    #     invoice.submit()
    #     frappe.db.commit()
    #     return invoice
    # except Exception as e:
    #     print("ERROR creating Sales Invoice from Sales Order:", str(e))
    #     frappe.log_error(f"Error creating Sales Invoice from Sales Order {doc.name}: {str(e)}", "Sales Order after_submit Error")

