"""Close document command — close a Fusion 360 document without the save dialog."""

import adsk.core


def handle_close_document(app: adsk.core.Application, args: dict) -> dict:
    """Close a document in Fusion 360 without triggering the save dialog.

    Args (all optional):
        name: Name of the document to close. If omitted, closes the active document.
        save: If True, save before closing. Default False (discard changes, no dialog).

    This is essential for automation — a normal close triggers a modal save dialog
    that blocks the Fusion main thread and hangs the add-in until the user clicks.
    """
    target_name = args.get("name")
    save_changes = args.get("save", False)

    try:
        if target_name:
            # Find the document by name
            doc = None
            for i in range(app.documents.count):
                d = app.documents.item(i)
                if d.name == target_name:
                    doc = d
                    break
            if doc is None:
                # List available docs for a helpful error
                available = [app.documents.item(i).name for i in range(app.documents.count)]
                return {
                    "success": False,
                    "error": f"Document '{target_name}' not found. Open documents: {available}",
                    "_hint": "Call fusion_document_info to list open documents, or use fusion_close_document with no name to close the active document.",
                }
        else:
            # Close the active document
            doc = app.activeDocument
            if doc is None:
                return {
                    "success": False,
                    "error": "No active document to close.",
                    "_hint": "Call fusion_document_info to check open documents — nothing is currently active.",
                }

        doc_name = doc.name

        # Check if document has unsaved changes (for reporting)
        is_saved = True
        try:
            is_saved = doc.isSaved
        except Exception:
            pass

        # Close the document. Passing False skips the save dialog entirely.
        doc.close(save_changes)

        remaining = app.documents.count
        new_active = None
        try:
            if app.activeDocument:
                new_active = app.activeDocument.name
        except Exception:
            pass

        return {
            "success": True,
            "output": f"Closed '{doc_name}' (save={save_changes}, had_unsaved={'yes' if not is_saved else 'no'}). {remaining} document(s) remaining.",
            "data": {
                "closedDocument": doc_name,
                "savedBeforeClose": save_changes,
                "hadUnsavedChanges": not is_saved,
                "remainingDocuments": remaining,
                "activeDocument": new_active,
            },
            "_hint": f"{remaining} document(s) still open."
                     + (f" Active: '{new_active}'. " if new_active else " No active document. ")
                     + "Use fusion_get_app_state to check workspace, or fusion_open_cloud_file to open another document.",
        }

    except Exception as e:
        return {
            "success": False,
            "error": f"Failed to close document: {e}",
            "_hint": "Retry with {\"save\": false} to discard changes, or call fusion_screenshot_fusion to check for a blocking Save dialog and dismiss it with fusion_send_key.",
        }


def handle_close_all_documents(app: adsk.core.Application, args: dict) -> dict:
    """Close ALL open documents without save dialogs.

    Closes every open document/tab in Fusion without triggering any save
    dialogs. Essential before restarting Fusion to avoid the 'Recovered
    Documents' modal on next launch.

    Args (all optional):
        save: If True, save each document before closing. Default False.
    """
    save_changes = args.get("save", False)

    closed = []
    errors = []
    skipped = []

    # Snapshot the current document list ONCE. Do NOT loop on app.documents.count,
    # because Fusion may auto-create an Untitled blank doc whenever all docs close,
    # which turns `while count > 0` into an infinite loop and times out the bridge.
    try:
        snapshot = []
        for i in range(app.documents.count):
            d = app.documents.item(i)
            snapshot.append(d)
    except Exception as e:
        return {
            "success": False,
            "error": f"Failed to enumerate documents: {e}",
            "_hint": "Retry with {\"save\": false} to discard changes, or call fusion_screenshot_fusion to check for a blocking Save dialog and dismiss it with fusion_send_key.",
        }

    for doc in snapshot:
        try:
            doc_name = doc.name
        except Exception:
            doc_name = "<unknown>"
        try:
            # Skip Untitled blank docs — Fusion recreates them, closing is pointless
            has_data_file = False
            try:
                has_data_file = doc.dataFile is not None
            except Exception:
                has_data_file = False
            if not has_data_file and doc_name.lower().startswith("untitled"):
                skipped.append(doc_name)
                continue
            doc.close(save_changes)
            closed.append(doc_name)
        except Exception as e:
            errors.append(f"{doc_name}: {e}")
            # Keep going — don't abort the whole batch on one failure

    return {
        "success": len(errors) == 0,
        "output": f"Closed {len(closed)} document(s)"
                  + (f", skipped {len(skipped)} Untitled" if skipped else "")
                  + (f", {len(errors)} error(s)" if errors else ""),
        "data": {
            "closed": closed,
            "skipped": skipped if skipped else None,
            "errors": errors if errors else None,
            "remainingDocuments": app.documents.count,
        },
    }
