import maya.OpenMaya as om
import maya.OpenMayaMPx as ompx
import maya.cmds as cmds
import os
import subprocess
import sys

# Global variable to store the scriptJob ID
playblast_job_id = None
original_playblast = cmds.playblast

def get_plugin_directory():
    # Get the path of the currently loaded plugin
    plugin_name = "tinyblast"
    plugin_path = cmds.pluginInfo(plugin_name, query=True, path=True)
    return os.path.dirname(plugin_path)

def custom_playblast(*args, **kwargs):
    print("Running playblast...")

    kwargs['format'] = 'avi'
    kwargs['percent'] = 100
    kwargs['quality'] = 100
    kwargs['widthHeight'] = (1920, 1080)

    result = original_playblast(*args, **kwargs)
    print(f"{result}")

    if result:
        try:
            ffmpeg_path = os.path.join(get_plugin_directory(), 'ffmpeg.exe')
            print(f"ffmpeg path: {ffmpeg_path}")
            if not os.path.exists(ffmpeg_path):
                raise FileNotFoundError(f"FFmpeg binary not found at {ffmpeg_path}")

            input_file = result  # The file output by playblast
            #output_directory = os.path.dirname(result)  # Get the directory path
            output_directory = os.path.dirname(cmds.file(query=True, sceneName=True))
            input_filename = os.path.basename(result)  # Get the filename with extension

            # Change the extension to .mp4
            output_filename = os.path.splitext(input_filename)[0] + ".mp4"

            # Define the full path for the converted output file
            output_file = os.path.join(output_directory, output_filename)

            # Run FFmpeg conversion
            subprocess.run([ffmpeg_path,
                            '-i', input_file,
                            '-vcodec', 'libx264',
                            '-pix_fmt', 'yuv420p',
                            '-strict', 'experimental',
                            '-b:v', '1m',
                            output_file,
                            '-y'], check=True, shell=True)
            print(f"Video conversion to {output_file} successful!")
            # os.remove(input_file) # Running into permission issues trying to delete from AppData
            # print(f"Original playblast deleted: {input_file}")
        except subprocess.CalledProcessError as e:
            print(f"Error during FFmpeg conversion: {e}")

class WindowWatcher:
    """ A class to watch for a particular window in Maya """

    def __init__(self, window_title, on_open_callback, on_close_callback=None):
        self.window_title = window_title
        self.on_open_callback = on_open_callback
        self.on_close_callback = on_close_callback
        self.window_opened = False

    def check_for_window_open(self):
        if not self.window_opened:
            window = self.get_window_by_title(self.window_title)
            if window:
                self.on_open_callback()
                self.window_opened = True
        else:
            window = self.get_window_by_title(self.window_title)
            if not window:
                self.window_opened = False
                if self.on_close_callback:
                    self.on_close_callback()

    def get_window_by_title(self, title):
        # Check all open windows and return the one that matches the title
        windows = cmds.lsUI(windows=True)
        for window in windows:
            if cmds.window(window, query=True, title=True) == title:
                return window
        return None


def add_custom_button_to_playblast():
    # Get the Playblast Options window
    window = get_playblast_options_window()

    if window:
        # Find the layout of the Playblast Options window
        layout = cmds.columnLayout(adjustableColumn=True)
        if layout:
            # Add a custom button below existing UI
            cmds.setParent(layout)  # Set the parent to the top-level layout
            cmds.columnLayout(adjustableColumn=True)
            cmds.button(label="Tinyblast", command=custom_button_action)
        else:
            print("Couldn't find the layout for the Playblast Options window.")
    else:
        print("Playblast Options window not found.")


def custom_button_action(*args):
    cmds.playblast()


def get_playblast_options_window():
    # Check if the Playblast Options window is open
    windows = cmds.lsUI(windows=True)
    for window in windows:
        if cmds.window(window, query=True, title=True) == "Playblast Options":  # Exact title match
            return window
    return None

def setup_script_job():
    global playblast_job_id

    # Kill any previously running scriptJob
    if playblast_job_id is not None and cmds.scriptJob(exists=playblast_job_id):
        cmds.scriptJob(kill=playblast_job_id, force=True)
        print(f"Killed previous scriptJob with ID: {playblast_job_id}")

    # Watch for the Playblast Options window by title
    playblast_watcher = WindowWatcher(
        window_title="Playblast Options",  # Exact window title to look for
        on_open_callback=add_custom_button_to_playblast
    )

    # Set up a new scriptJob
    playblast_job_id = cmds.scriptJob(event=["idle", playblast_watcher.check_for_window_open])

class Tinyblast(ompx.MPxCommand):
    def __init__(self):
        ompx.MPxCommand.__init__(self)

    def doIt(selfself, args):
        print("Executing custom playblast command.")
        cmds.playblast()

    @staticmethod
    def cmdCreator():
        return ompx.asMPxPtr(Tinyblast())

def initializePlugin(mobject):
    try:
        mplugin = ompx.MFnPlugin(mobject, "Jack Christensen", "1.0.0", "Any")
        mplugin.registerCommand("tinyblast", Tinyblast.cmdCreator)
        om.MGlobal.displayInfo("Tinyblast plugin loaded.")
        setup_script_job()
        cmds.playblast = custom_playblast
    except Exception as e:
        om.MGlobal.displayError(f"Failed to initialize plugin: {str(e)}")
        raise

def uninitializePlugin(mobject):
    try:
        mplugin = ompx.MFnPlugin(mobject)
        mplugin.deregisterCommand("tinyblast")
        om.MGlobal.displayInfo("Tinyblast plugin unloaded.")
    except Exception as e:
        om.MGlobal.displayError(f"Failed to uninitialize plugin: {str(e)}")
        raise