# SmedgeRender.py
#
# Smedge integration with Maya
#
# Smedge
# Copyright Uberware. All Rights Reserved

"""Simple Smedge submit interface for Maya.

It will use the Smedge Python API, which expects the Smedge "python" folder to be in your PYTHONPATH environment.

To integrate with the Maya menus, ...
"""


from pathlib import Path
from typing import Any, Dict, List
from uuid import UUID

import smedge
from maya import cmds, OpenMayaUI as omui
from maya.app.renderSetup.model import renderSetup

try:
    # Maya 2025+ (PySide6)
    from PySide6 import QtWidgets, QtCore, QtGui
    from shiboken6 import wrapInstance
except ImportError:
    # Maya <= 2024 (PySide2)
    from PySide2 import QtWidgets, QtCore, QtGui
    from shiboken2 import wrapInstance


def maya_main_window():
    """Return the main Maya main window."""
    ptr = omui.MQtUtil.mainWindow()
    if ptr is None:
        return None
    return wrapInstance(int(ptr), QtWidgets.QWidget)


class SmedgeSubmitWindow(smedge.SmedgeSubmitWindow):
    """A dialog box to override some details about how the job gets submitted."""

    def __init__(self):
        """Initialize a new SmedgeSubmitWindow object."""
        # Ensure we are in a valid context to run this GUI
        main_window = maya_main_window()
        if not main_window:
            raise RuntimeError("No Maya GUI available")
        scene = cmds.file(query=True, sceneName=True)
        if not scene:
            raise RuntimeError("You must save the scene before it can be rendered on the farm")
        cmds.file(save=True, force=True)
        self.scene_path = Path(scene)
        # Close previous instances to avoid conflicts
        if cmds.window("SmedgeSubmitWindow", exists=True):
            cmds.deleteUI("SmedgeSubmitWindow")
        if cmds.workspaceControl("SmedgeSubmitWindow_WorkspaceControl", exists=True):
            cmds.deleteUI("SmedgeSubmitWindow_WorkspaceControl")
        # Set up the window
        self.mode = None
        start_frame = int(cmds.getAttr('defaultRenderGlobals.startFrame'))
        end_frame = int(cmds.getAttr('defaultRenderGlobals.endFrame'))
        super().__init__(frame_range=(start_frame, end_frame), parent=main_window)
        self.setObjectName("SmedgeSubmitWindow")

    def add_properties(self, properties: dict[str, QtWidgets.QWidget]):
        """Customize to add the Maya specific properties."""
        # Add the mode to the list of job properties
        self.mode = QtWidgets.QComboBox()
        self.mode.addItems(["A single job", "One job for each Render Layer"])
        self.mode.setToolTip("Choose one job for the scene or one job for each render layer")
        properties["Mode"] = self.mode
        # Use the scene file name as the default job name
        self.name.setText(self.scene_path.name)
        super().add_properties(properties)

    def submit(self, job: Dict[str, Any]) -> List[UUID]:
        """Submit button callback to do the work."""
        # Build the base job
        job["Type"] = "Maya"
        job["Scene"] = self.scene_path
        # Create the list of jobs to submit
        jobs = []
        if self.mode.currentIndex() == 0:
            # One job for the whole scene
            jobs.append(job)
        else:
            # One job for each write node
            rs = renderSetup.instance()
            for layer in (layer for layer in rs.getRenderLayers() if layer.isRenderable()):
                node_job = job.copy()
                node_job["Name"] += " :: " + layer.name()
                node_job["Extra"] = f"-rl {layer.name()}"
                jobs.append(node_job)
        # Send to the farm
        return smedge.submit_jobs(jobs, self.paused.isChecked())
