import frappe
from custom_ui.services import SalesOrderService, AddressService, ClientService, ServiceAppointmentService, TaskService
from datetime import timedelta
import traceback

def after_insert(doc, method):
    print("DEBUG: After Insert Triggered for Project")
    print("DEBUG: Linking Project to address and Customer")
    AddressService.append_link_v2(
        doc.job_address, "projects", {"project": doc.name, "project_template": doc.project_template}
    )
    AddressService.append_link_v2(
        doc.job_address, "links", {"link_doctype": "Project", "link_name": doc.name}
    )
    ClientService.append_link_v2(
        doc.customer, "projects", {"project": doc.name, "project_template": doc.project_template}
    )
    if doc.project_template == "SNW Install":
        print("DEBUG: Project template is SNW Install, creating Service Appointment")
        AddressService.update_value(
            doc.job_address,
            "job_status",
            "In Progress"
        )
        try:
            service_apt = ServiceAppointmentService.create({
                "project": doc.name,
                "customer": doc.customer,
                "service_address": doc.job_address,
                "company": doc.company,
                "project_template": doc.project_template
            })
            doc.service_appointment = service_apt.name
            doc.save(ignore_permissions=True)
            print("DEBUG: Created Service Appointment:", service_apt.name)
        except Exception as e:
            print("ERROR: Failed to create Service Appointment for Project:", e)
            print(traceback.format_exc())
            raise e
    task_names = [task.name for task in TaskService.get_tasks_by_project(doc.name)]
    for task_name in task_names:
        doc.append("tasks", {
            "task": task_name
        })
        AddressService.append_link_v2(
            doc.job_address, "tasks", {"task": task_name}
        )
        ClientService.append_link_v2(
            doc.customer, "tasks", {"task": task_name}
        )
    if task_names:
        doc.save(ignore_permissions=True)
    TaskService.fire_task_triggers(task_names, "Created", current_triggering_dict=doc.as_dict())
    
    
    
def before_insert(doc, method):
    # This is where we will add logic to set tasks and other properties of a job based on it's project_template
    if doc.requires_half_payment:
        print("DEBUG: Project requires half payment, setting flag.")
        doc.ready_to_schedule = 0

def before_save(doc, method):
    print("DEBUG: Before Save Triggered for Project:", doc.name)
    print("DEBUG: Checking status: ", doc.status)
    if doc.expected_start_date and doc.expected_end_date:
        print("DEBUG: Project has expected start and end dates, marking as scheduled")
        doc.is_scheduled = 1
        while frappe.db.exists("Holiday", {"holiday_date": doc.expected_end_date}):
            print("DEBUG: Expected end date falls on a holiday, extending end date by 1 day")
            doc.expected_end_date += timedelta(days=1)
    elif not doc.expected_start_date or not doc.expected_end_date:
        print("DEBUG: Project missing expected start or end date, marking as unscheduled")
        doc.is_scheduled = 0
    event = TaskService.determine_event(doc)
    if event:
        TaskService.fire_task_triggers(
            [task.task for task in doc.tasks],
            event,
            current_triggering_dict=doc.as_dict()
        )
        
def after_save(doc, method):
    print("DEBUG: After Save Triggered for Project:", doc.name)
    if doc.status == "Completed":
        print("DEBUG: Project marked as Completed. Generating and sending final invoice.")
        sales_order_status = frappe.get_value("Sales Order", doc.sales_order, "billing_status")
        if sales_order_status == "Not Billed":
            SalesOrderService.create_sales_invoice_from_sales_order(doc.sales_order)
    if doc.ready_to_schedule:
        service_apt_ready_to_schedule = frappe.get_value("Service Address 2", doc.service_appointment, "ready_to_schedule")
        if not service_apt_ready_to_schedule:
            print("DEBUG: Project is ready to schedule, setting Service Appointment to ready to schedule.")
            service_apt_doc = frappe.get_doc("Service Address 2", doc.service_appointment)
            service_apt_doc.ready_to_schedule = 1
            service_apt_doc.save(ignore_permissions=True)
    if doc.project_template == "SNW Install":
        print("DEBUG: Project template is SNW Install, updating Address Job Status based on Project status")
        status_mapping = {
            "Open": "In Progress",
            "Completed": "Completed",
            "Closed": "Completed"
        }
        new_status = status_mapping.get(doc.status, "In Progress")
        if frappe.db.get_value("Address", doc.job_address, "job_status") != new_status:
            print("DEBUG: Updating Address job_status to:", new_status)
            AddressService.update_value(
                doc.job_address,
                "job_status",
                new_status
            )