import frappe
import requests
import json
import uuid
from frappe.utils import nowdate, now_datetime
from invoice_az.auth import record_etaxes_activity, get_default_asan_login

# Constants
BASE_URL = "https://new.e-taxes.gov.az"
SERIAL_URL = f"{BASE_URL}/api/po/invoice/public/v1/generateSerialNumber/defaultInvoice"
INVOICE_URL = f"{BASE_URL}/api/po/invoice/public/v2/invoice"
SIGN_URL = f"{BASE_URL}/api/po/invoice/public/v1/invoice/sign/withAsanImza"
REMOVE_DRAFT_URL = f"{BASE_URL}/api/po/invoice/public/v1/common/removeDrafts"

DEFAULT_HEADERS = {
    "Accept": "application/json, text/plain, */*",
    "Accept-Language": "en-US,en;q=0.9",
    "Content-Type": "application/json",
    "Cache-Control": "no-cache",
    "Pragma": "no-cache"
}


@frappe.whitelist()
def send_sales_invoice_to_etaxes(sales_invoice_name):
    """
    Main function to create draft Sales Invoice on E-Taxes (Step 1 of 2)

    Workflow:
    1. Validate invoice
    2. Generate serial number
    3. Build payload
    4. Create draft invoice on E-Taxes (NOT signed yet)
    5. Create tracking record
    6. Update Sales Invoice with status "Created, not signed"

    Note: User must use "Sign Document" button to complete the process (Step 2)

    Args:
        sales_invoice_name: Name of Sales Invoice to send

    Returns:
        dict: Success/error response with details
    """
    try:
        # Record activity
        record_etaxes_activity()

        # Get Sales Invoice document
        doc = frappe.get_doc("Sales Invoice", sales_invoice_name)

        # Validate invoice
        validation_result = validate_invoice_for_sending(doc)
        if not validation_result.get("valid"):
            return {
                "success": False,
                "message": validation_result.get("message")
            }

        # Get authentication token
        asan_login = get_default_asan_login()
        if not asan_login.get("found") or not asan_login.get("main_token"):
            return {
                "success": False,
                "message": "E-Taxes authentication not found. Please login via ASAN."
            }

        token = asan_login.get("main_token")

        # Step 1: Generate serial number
        serial_result = generate_serial_number(token)
        if not serial_result.get("success"):
            return {
                "success": False,
                "message": f"Failed to generate serial number: {serial_result.get('message')}"
            }

        serial_number = serial_result.get("serial_number")

        # Step 2: Build invoice payload
        payload = build_invoice_payload(doc, serial_number)

        # Step 3: Create invoice on E-Taxes
        create_result = create_invoice_on_etaxes(token, payload, serial_number)
        if not create_result.get("success"):
            return {
                "success": False,
                "message": f"Failed to create invoice: {create_result.get('message')}"
            }

        invoice_id = create_result.get("invoice_id")

        # Step 4: Set status as draft (signing will be done separately via "Sign Document" button)
        verification_code = None
        final_status = "Created, not signed"

        # Step 5: Create tracking record
        create_outbox_record(
            sales_invoice_name,
            invoice_id,
            serial_number,
            verification_code,
            final_status,
            None  # No error message for draft creation
        )

        # Step 6: Update Sales Invoice

        # Use db.set_value to avoid triggering validation
        frappe.db.set_value("Sales Invoice", sales_invoice_name, {
            "etaxes_invoice_id": invoice_id,
            "etaxes_serial_number": serial_number,
            "etaxes_verification_code": verification_code,
            "etaxes_send_status": final_status
        })
        frappe.db.commit()

        success_message = f"Draft invoice created successfully. Serial: {serial_number}"
        success_message += " Please use 'Sign Document' button to complete the process."

        return {
            "success": True,
            "message": success_message,
            "invoice_id": invoice_id,
            "serial_number": serial_number,
            "verification_code": verification_code,
            "status": final_status
        }

    except Exception as e:
        frappe.log_error(
            f"Error sending Sales Invoice to E-Taxes: {str(e)}\n{frappe.get_traceback()}",
            "Send Sales Invoice Error"
        )
        return {
            "success": False,
            "message": f"An unexpected error occurred: {str(e)}"
        }


def validate_invoice_for_sending(doc):
    """
    Validate Sales Invoice before sending to E-Taxes

    Checks:
    - Invoice is submitted
    - Not already sent
    - Customer has TIN
    - Customer object name provided
    - All items have product codes
    - All items have UOM

    Args:
        doc: Sales Invoice document

    Returns:
        dict: {"valid": bool, "message": str}
    """
    try:
        # Check if submitted
        if doc.docstatus != 1:
            return {
                "valid": False,
                "message": "Sales Invoice must be submitted before sending to E-Taxes"
            }

        # Check if already sent
        if doc.etaxes_send_status == "Sent and Signed":
            return {
                "valid": False,
                "message": "This invoice has already been sent and signed on E-Taxes"
            }

        # Check customer TIN
        customer = frappe.get_doc("Customer", doc.customer)
        if not customer.tax_id:
            return {
                "valid": False,
                "message": f"Customer '{doc.customer}' does not have a TIN (tax_id). Please update customer details."
            }

        # Check customer object name
        if not doc.customer_object_name:
            return {
                "valid": False,
                "message": "Customer's legal company name is required. Please fill the 'Customer Object Name' field in the Sales Invoice."
            }

        # Validate items
        if not doc.items:
            return {
                "valid": False,
                "message": "Sales Invoice has no items"
            }

        missing_product_codes = []
        missing_units = []

        for item in doc.items:
            # Check product code
            item_master = frappe.get_doc("Item", item.item_code)
            if not item_master.product_group_code:
                missing_product_codes.append(item.item_code)

            # Check UOM
            if not item.uom:
                missing_units.append(item.item_code)

        if missing_product_codes:
            return {
                "valid": False,
                "message": f"Items missing product codes: {', '.join(missing_product_codes)}"
            }

        if missing_units:
            return {
                "valid": False,
                "message": f"Items missing units (UOM): {', '.join(missing_units)}"
            }

        return {"valid": True}

    except Exception as e:
        frappe.log_error(
            f"Error validating invoice: {str(e)}\n{frappe.get_traceback()}",
            "Sales Invoice Validation Error"
        )
        return {
            "valid": False,
            "message": f"Validation error: {str(e)}"
        }


def generate_serial_number(token):
    """
    Generate serial number from E-Taxes API

    Args:
        token: ASAN authentication token

    Returns:
        dict: {"success": bool, "serial_number": str, "message": str}
    """
    try:
        headers = DEFAULT_HEADERS.copy()
        headers["x-authorization"] = f"Bearer {token}"

        response = requests.get(SERIAL_URL, headers=headers, timeout=30)

        if response.status_code == 401:
            return {
                "success": False,
                "message": "Authentication expired. Please login again."
            }

        if response.status_code == 500:
            return {
                "success": False,
                "message": "E-Taxes service error. Please try again later."
            }

        response.raise_for_status()

        # Response: {"serialNumber":"MT25121128****"}
        result = response.json()
        serial_number = result.get("serialNumber")

        if not serial_number:
            # Fallback: try plain text response
            serial_number = response.text.strip().strip('"')

        return {
            "success": True,
            "serial_number": serial_number
        }

    except requests.exceptions.RequestException as e:
        frappe.log_error(
            f"Error generating serial number: {str(e)}",
            "Serial Number Generation Error"
        )
        return {
            "success": False,
            "message": f"Network error: {str(e)}"
        }
    except Exception as e:
        frappe.log_error(
            f"Unexpected error generating serial: {str(e)}\n{frappe.get_traceback()}",
            "Serial Number Error"
        )
        return {
            "success": False,
            "message": f"Error: {str(e)}"
        }


def get_customer_name_from_etaxes(customer):
    """
    Get customer name from E-Taxes Customers mapping

    Args:
        customer: Customer name (from Sales Invoice)

    Returns:
        str or None: E-Taxes customer name if found
    """
    try:
        # Get customer TIN
        customer_doc = frappe.get_doc("Customer", customer)
        tin = customer_doc.tax_id

        if not tin:
            return None

        # Search in E-Taxes Customers by TIN
        etaxes_customers = frappe.get_all(
            "E-Taxes Customers",
            filters={"etaxes_tax_id": tin},
            fields=["etaxes_party_name"],
            limit=1
        )

        if etaxes_customers:
            return etaxes_customers[0].etaxes_party_name

        return None

    except Exception as e:
        frappe.log_error(
            f"Error getting customer from E-Taxes: {str(e)}",
            "E-Taxes Customer Lookup Error"
        )
        return None


@frappe.whitelist()
def get_customer_objects(sales_invoice_name):
	"""
	Get customer objects from E-Taxes API for object selection dialog

	Args:
		sales_invoice_name: Name of Sales Invoice document

	Returns:
		dict: {
			"success": bool,
			"objects": list of objects (only active, status="A"),
			"message": str (error message if any),
			"customer_name": str,
			"tax_id": str
		}
	"""
	try:
		# Record activity for token renewal
		record_etaxes_activity()

		# Get Sales Invoice document
		doc = frappe.get_doc("Sales Invoice", sales_invoice_name)

		# Get customer details
		customer = frappe.get_doc("Customer", doc.customer)

		# Validate customer has tax_id
		if not customer.tax_id:
			return {
				"success": False,
				"message": f"Customer '{doc.customer}' does not have a TIN (tax_id). Please update customer details."
			}

		# Get authentication token
		asan_login = get_default_asan_login()
		if not asan_login.get("found") or not asan_login.get("main_token"):
			return {
				"success": False,
				"message": "E-Taxes authentication not found. Please login via ASAN."
			}

		token = asan_login.get("main_token")

		# Build API URL
		tax_id = customer.tax_id
		url = f"https://new.e-taxes.gov.az/api/po/profile/public/v1/taxpayer/{tax_id}/object/find"

		# Build headers
		headers = DEFAULT_HEADERS.copy()
		headers["x-authorization"] = f"Bearer {token}"

		# Build query parameters
		params = {
			"mainObjectOnly": "true"
		}

		# Make API request
		response = requests.get(url, headers=headers, params=params, timeout=30)

		# Handle 401 Unauthorized
		if response.status_code == 401:
			return {
				"success": False,
				"message": "Authentication expired. Please login again via ASAN."
			}

		# Handle 500 Server Error
		if response.status_code == 500:
			return {
				"success": False,
				"message": "E-Taxes service error. Please try again later."
			}

		# Handle 404 Not Found (customer not found or no objects)
		if response.status_code == 404:
			return {
				"success": True,
				"objects": [],
				"message": "No objects found for this customer.",
				"customer_name": customer.customer_name,
				"tax_id": tax_id
			}

		# Raise for other HTTP errors
		response.raise_for_status()

		# Parse response
		result = response.json()
		objects = result.get("objects", [])

		# Filter only active objects (status = "A")
		active_objects = [obj for obj in objects if obj.get("status") == "A"]

		return {
			"success": True,
			"objects": active_objects,
			"customer_name": customer.customer_name,
			"tax_id": tax_id
		}

	except requests.exceptions.RequestException as e:
		frappe.log_error(
			f"Error fetching customer objects: {str(e)}",
			"Get Customer Objects Error"
		)
		return {
			"success": False,
			"message": f"Network error: {str(e)}"
		}
	except Exception as e:
		frappe.log_error(
			f"Unexpected error getting customer objects: {str(e)}\n{frappe.get_traceback()}",
			"Get Customer Objects Error"
		)
		return {
			"success": False,
			"message": f"Error: {str(e)}"
		}


def build_invoice_payload(doc, serial_number):
    """
    Build JSON payload for E-Taxes invoice creation

    Args:
        doc: Sales Invoice document
        serial_number: Generated serial number

    Returns:
        dict: JSON payload for E-Taxes API
    """
    try:
        # Get customer details
        customer = frappe.get_doc("Customer", doc.customer)

        # Get customer name from E-Taxes (or use ERP name as fallback)
        etaxes_customer_name = get_customer_name_from_etaxes(doc.customer)
        if not etaxes_customer_name:
            etaxes_customer_name = customer.customer_name

        # Build receiver object
        receiver = {
            "name": etaxes_customer_name,
            "tin": customer.tax_id,
            "objectName": doc.customer_object_name
        }

        # Build items array
        items = []
        for item in doc.items:
            item_master = frappe.get_doc("Item", item.item_code)

            # Map VAT fields to E-Taxes format
            vat18 = item.vat_18_percent_with_amount if hasattr(item, 'vat_18_percent_with_amount') and item.vat_18_percent_with_amount else None
            vat0 = item.vat_0_percent_with_amount if hasattr(item, 'vat_0_percent_with_amount') and item.vat_0_percent_with_amount else None
            vat_free = item.vat_free_amount if hasattr(item, 'vat_free_amount') and item.vat_free_amount else None
            exempt = item.amount_without_vat if hasattr(item, 'amount_without_vat') and item.amount_without_vat else None

            item_payload = {
                "id": str(uuid.uuid4()),
                "productGroupCode": item_master.product_group_code,
                "productName": item.item_name,
                "unit": item.uom,  # Use UOM name as text
                "unitCode": None,  # Not required per user confirmation
                "quantity": item.qty,
                "pricePerUnit": item.rate,
                "cost": item.amount,
                "exciseRate": None,
                "excise": None,
                "vat18": vat18,
                "vat0": vat0,
                "vatFree": vat_free,
                "exempt": exempt,
                "roadTax": None,
                "barcode": None,
                "returnReasonCode": None,
                "packagingGoodsNumber": None,
                "sourceInvoiceSerialNumber": None,
                "sourceInvoiceItemId": None,
                "serviceCost": None,
                "commission": None,
                "kind": None
            }

            items.append(item_payload)

        # Build complete payload
        payload = {
            "type": "current",
            "serialNumber": serial_number,
            "invoiceComment": doc.comment if hasattr(doc, 'comment') and doc.comment else "",
            "invoiceComment2": doc.additional_comment if hasattr(doc, 'additional_comment') and doc.additional_comment else "",
            "receiver": receiver,
            "senderObjectCode": "",
            "vehicleRegistrationNumber": "",
            "items": items,
            "kind": "defaultInvoice",
            "modificationReasonCode": "",
            "resaleType": None,
            "sourceInvoices": None,
            "selectedProducts": [],
            "senderObjectName": "",
            "sourceSystem": "lk"
        }

        return payload

    except Exception as e:
        frappe.log_error(
            f"Error building invoice payload: {str(e)}\n{frappe.get_traceback()}",
            "Build Payload Error"
        )
        raise


def create_invoice_on_etaxes(token, payload, serial_number):
    """
    Create invoice on E-Taxes system

    Args:
        token: ASAN authentication token
        payload: Invoice JSON payload
        serial_number: Serial number for logging

    Returns:
        dict: {"success": bool, "invoice_id": str, "message": str}
    """
    try:
        headers = DEFAULT_HEADERS.copy()
        headers["x-authorization"] = f"Bearer {token}"

        response = requests.post(
            INVOICE_URL,
            data=json.dumps(payload),
            headers=headers,
            timeout=60
        )

        if response.status_code == 401:
            return {
                "success": False,
                "message": "Authentication expired. Please login again."
            }

        if response.status_code == 500:
            return {
                "success": False,
                "message": "E-Taxes service error. Please try again later."
            }

        # Handle errors with E-Taxes message format
        # Accept both 200 (OK) and 201 (Created) as success
        if response.status_code not in [200, 201]:
            try:
                error_data = response.json()
                # Try to get Azerbaijani message first
                if isinstance(error_data, dict) and "message" in error_data:
                    if isinstance(error_data["message"], dict) and "az" in error_data["message"]:
                        return {
                            "success": False,
                            "message": error_data["message"]["az"]
                        }
                    elif isinstance(error_data["message"], str):
                        return {
                            "success": False,
                            "message": error_data["message"]
                        }
            except:
                pass

            return {
                "success": False,
                "message": f"E-Taxes error (status {response.status_code})"
            }

        response.raise_for_status()

        result = response.json()
        invoice_id = result.get("id")

        if not invoice_id:
            return {
                "success": False,
                "message": "No invoice ID returned from E-Taxes"
            }

        return {
            "success": True,
            "invoice_id": invoice_id
        }

    except requests.exceptions.RequestException as e:
        frappe.log_error(
            f"Error creating invoice on E-Taxes: {str(e)}\nPayload: {json.dumps(payload, indent=2)}",
            "Create Invoice Error"
        )
        return {
            "success": False,
            "message": f"Network error: {str(e)}"
        }
    except Exception as e:
        frappe.log_error(
            f"Unexpected error creating invoice: {str(e)}\n{frappe.get_traceback()}",
            "Create Invoice Error"
        )
        return {
            "success": False,
            "message": f"Error: {str(e)}"
        }


def sign_invoice_on_etaxes(token, invoice_id):
    """
    Sign invoice with ASAN Imza

    Args:
        token: ASAN authentication token
        invoice_id: Invoice ID to sign

    Returns:
        dict: {"success": bool, "verification_code": str, "message": str}
    """
    try:
        headers = DEFAULT_HEADERS.copy()
        headers["x-authorization"] = f"Bearer {token}"

        payload = {
            "type": "send",
            "invoiceIds": [invoice_id]
        }

        response = requests.post(
            SIGN_URL,
            data=json.dumps(payload),
            headers=headers,
            timeout=60
        )

        if response.status_code == 401:
            return {
                "success": False,
                "message": "Authentication expired during signing"
            }

        if response.status_code == 500:
            return {
                "success": False,
                "message": "E-Taxes service error during signing"
            }

        response.raise_for_status()

        result = response.json()

        if result.get("status") == "ok":
            verification_code = result.get("verificationCode")
            return {
                "success": True,
                "verification_code": verification_code
            }
        else:
            error_msg = result.get("error", "Unknown signing error")
            return {
                "success": False,
                "message": f"Signing failed: {error_msg}"
            }

    except requests.exceptions.RequestException as e:
        frappe.log_error(
            f"Error signing invoice {invoice_id}: {str(e)}",
            "Sign Invoice Error"
        )
        return {
            "success": False,
            "message": f"Network error during signing: {str(e)}"
        }
    except Exception as e:
        frappe.log_error(
            f"Unexpected error signing invoice: {str(e)}\n{frappe.get_traceback()}",
            "Sign Invoice Error"
        )
        return {
            "success": False,
            "message": f"Signing error: {str(e)}"
        }


def create_outbox_record(sales_invoice_name, invoice_id, serial_number,
                        verification_code, status, error_message=None):
    """
    Create E-Taxes Sales Outbox tracking record

    Args:
        sales_invoice_name: Sales Invoice reference
        invoice_id: E-Taxes invoice ID
        serial_number: Serial number
        verification_code: Verification code (if signed)
        status: Send status
        error_message: Error message if any
    """
    try:
        # Check if record already exists
        existing = frappe.db.exists(
            "E-Taxes Sales Outbox",
            {"sales_invoice": sales_invoice_name}
        )

        if existing:
            # Update existing record
            doc = frappe.get_doc("E-Taxes Sales Outbox", existing)
            doc.etaxes_invoice_id = invoice_id
            doc.serial_number = serial_number
            doc.verification_code = verification_code
            doc.status = status
            doc.error_message = error_message
            doc.save()
        else:
            # Create new record
            doc = frappe.new_doc("E-Taxes Sales Outbox")
            doc.sales_invoice = sales_invoice_name
            doc.etaxes_invoice_id = invoice_id
            doc.serial_number = serial_number
            doc.verification_code = verification_code
            doc.send_date = now_datetime()
            doc.status = status
            doc.error_message = error_message
            doc.insert()

        frappe.db.commit()

    except Exception as e:
        frappe.log_error(
            f"Error creating outbox record: {str(e)}\n{frappe.get_traceback()}",
            "Outbox Record Error"
        )
        # Don't fail the whole process if outbox creation fails


@frappe.whitelist()
def retry_signing_invoice(sales_invoice_name):
    """
    Sign an invoice that was created as draft (Step 2 of 2)

    This is the second step of the workflow, called when user clicks "Sign Document" button.
    First step is send_sales_invoice_to_etaxes() which creates the draft.

    Args:
        sales_invoice_name: Sales Invoice name

    Returns:
        dict: Success/error response with verification code
    """
    try:
        # Record activity
        record_etaxes_activity()

        # Get Sales Invoice
        doc = frappe.get_doc("Sales Invoice", sales_invoice_name)

        # Check status
        if doc.etaxes_send_status != "Created, not signed":
            return {
                "success": False,
                "message": "Invoice is not in 'Created, not signed' status"
            }

        if not doc.etaxes_invoice_id:
            return {
                "success": False,
                "message": "No E-Taxes invoice ID found"
            }

        # Get token
        asan_login = get_default_asan_login()
        if not asan_login.get("found") or not asan_login.get("main_token"):
            return {
                "success": False,
                "message": "E-Taxes authentication not found"
            }

        token = asan_login.get("main_token")

        # Try signing
        sign_result = sign_invoice_on_etaxes(token, doc.etaxes_invoice_id)

        if sign_result.get("success"):
            verification_code = sign_result.get("verification_code")

            # Update Sales Invoice
            frappe.db.set_value("Sales Invoice", sales_invoice_name, {
                "etaxes_verification_code": verification_code,
                "etaxes_send_status": "Sent and Signed"
            })

            # Update outbox record
            outbox = frappe.db.get_value(
                "E-Taxes Sales Outbox",
                {"sales_invoice": sales_invoice_name},
                "name"
            )
            if outbox:
                frappe.db.set_value("E-Taxes Sales Outbox", outbox, {
                    "verification_code": verification_code,
                    "status": "Sent and Signed",
                    "error_message": None
                })

            frappe.db.commit()

            return {
                "success": True,
                "message": "Invoice signed successfully",
                "verification_code": verification_code
            }
        else:
            return {
                "success": False,
                "message": sign_result.get("message")
            }

    except Exception as e:
        frappe.log_error(
            f"Error retrying signing: {str(e)}\n{frappe.get_traceback()}",
            "Retry Signing Error"
        )
        return {
            "success": False,
            "message": f"Error: {str(e)}"
        }


@frappe.whitelist()
def cancel_invoice_on_etaxes(sales_invoice_name):
    """
    Cancel/Remove draft invoice on E-Taxes system

    This function removes a draft invoice from E-Taxes using the removeDrafts API.
    Can be called manually or automatically during Sales Invoice cancellation.

    Args:
        sales_invoice_name: Name of Sales Invoice to cancel on E-Taxes

    Returns:
        dict: Success/error response
    """
    try:
        # Record activity
        record_etaxes_activity()

        # Get Sales Invoice
        doc = frappe.get_doc("Sales Invoice", sales_invoice_name)

        # Check if invoice has E-Taxes ID
        if not doc.etaxes_invoice_id:
            return {
                "success": False,
                "message": "This invoice was not sent to E-Taxes or has no E-Taxes Invoice ID"
            }

        # Get authentication token
        asan_login = get_default_asan_login()
        if not asan_login.get("found") or not asan_login.get("main_token"):
            return {
                "success": False,
                "message": "E-Taxes authentication not found. Please login via ASAN."
            }

        token = asan_login.get("main_token")
        invoice_id = doc.etaxes_invoice_id

        # Build headers
        headers = DEFAULT_HEADERS.copy()
        headers["x-authorization"] = f"Bearer {token}"

        # Build payload - array with invoice ID (API expects array of IDs)
        payload = [invoice_id]

        # Make DELETE request
        response = requests.delete(
            REMOVE_DRAFT_URL,
            data=json.dumps(payload),
            headers=headers,
            timeout=30
        )

        # Check response
        if response.status_code == 204:
            # Success - invoice removed
            # Clear E-Taxes fields in Sales Invoice
            frappe.db.set_value("Sales Invoice", sales_invoice_name, {
                "etaxes_invoice_id": None,
                "etaxes_serial_number": None,
                "etaxes_verification_code": None,
                "etaxes_send_status": "Not Sent",
                "customer_object_name": None
            })

            # Delete outbox record if exists
            outbox_name = frappe.db.get_value(
                "E-Taxes Sales Outbox",
                {"sales_invoice": sales_invoice_name},
                "name"
            )
            if outbox_name:
                frappe.delete_doc("E-Taxes Sales Outbox", outbox_name, force=True)

            frappe.db.commit()

            return {
                "success": True,
                "message": "Invoice successfully removed from E-Taxes"
            }

        elif response.status_code == 401:
            return {
                "success": False,
                "message": "Authentication expired. Please login again."
            }

        elif response.status_code == 404:
            # Invoice not found on E-Taxes - might be already deleted
            # Clear fields anyway
            frappe.db.set_value("Sales Invoice", sales_invoice_name, {
                "etaxes_invoice_id": None,
                "etaxes_serial_number": None,
                "etaxes_verification_code": None,
                "etaxes_send_status": "Not Sent",
                "customer_object_name": None
            })
            frappe.db.commit()

            return {
                "success": True,
                "message": "Invoice not found on E-Taxes (may be already deleted). Local fields cleared."
            }

        else:
            # Other error - try to get Azerbaijani message
            error_msg = f"E-Taxes returned status {response.status_code}"
            try:
                error_data = response.json()
                if isinstance(error_data, dict) and "message" in error_data:
                    if isinstance(error_data["message"], dict) and "az" in error_data["message"]:
                        error_msg = error_data["message"]["az"]
                    elif isinstance(error_data["message"], str):
                        error_msg = error_data["message"]
            except:
                pass

            return {
                "success": False,
                "message": f"Failed to remove invoice from E-Taxes: {error_msg}"
            }

    except requests.exceptions.RequestException as e:
        frappe.log_error(
            f"Error cancelling invoice on E-Taxes: {str(e)}",
            "Cancel Invoice Network Error"
        )
        return {
            "success": False,
            "message": f"Network error: {str(e)}"
        }
    except Exception as e:
        frappe.log_error(
            f"Unexpected error cancelling invoice on E-Taxes: {str(e)}\n{frappe.get_traceback()}",
            "Cancel Invoice Error"
        )
        return {
            "success": False,
            "message": f"Error: {str(e)}"
        }


def on_cancel_sales_invoice(doc, method):
    """
    Hook called when Sales Invoice is cancelled
    Prompts user to also cancel on E-Taxes if invoice was sent
    """
    try:
        # Check if invoice was sent to E-Taxes
        if doc.etaxes_invoice_id and doc.etaxes_send_status in ["Created, not signed", "Sent and Signed"]:
            # User should manually cancel on E-Taxes using the 'Cancel on E-Taxes' button
            pass
    except Exception as e:
        frappe.log_error(
            f"Error in on_cancel_sales_invoice hook: {str(e)}\n{frappe.get_traceback()}",
            "On Cancel Hook Error"
        )


def on_delete_sales_invoice(doc, method):
    """Deletes related E-Taxes Sales Outbox record when Sales Invoice is deleted or cancelled"""
    try:
        # Find all E-Taxes Sales Outbox records linked to this Sales Invoice
        outbox_records = frappe.get_all(
            "E-Taxes Sales Outbox",
            filters={"sales_invoice": doc.name},
            fields=["name"]
        )

        if outbox_records:
            for record in outbox_records:
                frappe.delete_doc('E-Taxes Sales Outbox', record.name, ignore_permissions=True, force=True)

            frappe.db.commit()

    except Exception as e:
        frappe.log_error(
            f"Error deleting E-Taxes Sales Outbox for Sales Invoice {doc.name}: {str(e)}\n{frappe.get_traceback()}",
            "Sales Invoice Delete Error"
        )
