import os
from .__meta__ import getVersion
import bpy
import time

from .utils_web_project import getTimeout
from .external_process import exec_command_standalone

from .utils_debug import debug_err, debug_log
from .utils import getWebProjectPath

lastBugReportTime = 0
__minTimeBetweenBugReports = 20
__isExportingBug = False

def isExportingBug():
    global __isExportingBug
    return __isExportingBug

def canReportABug():
    projectDirectory = getWebProjectPath()
    if projectDirectory is None:
        return False
    helperDirectory = projectDirectory + "/node_modules/@needle-tools/helper"
    if not os.path.exists(helperDirectory):
        return False
    return True

def allowSendingBugReport():
    global lastBugReportTime, bugReportsSent
    currentTime = time.time()
    if currentTime - lastBugReportTime < __minTimeBetweenBugReports:
        return False
    return True


def __createPackedBlenderFile():
    try:
        __packedFilePath = bpy.data.filepath + ".packed.blend"
        if os.path.exists(__packedFilePath):
            os.remove(__packedFilePath)
        bpy.ops.file.pack_all()
        bpy.ops.wm.save_as_mainfile(filepath=__packedFilePath, check_existing=False)
        return __packedFilePath
    except Exception as e:
        debug_err("Failed to pack blend file:", e)
        if os.path.exists(__packedFilePath):
            return __packedFilePath
        return None

def reportBug():
    originalFilePath = bpy.data.filepath
    try:
        global __isExportingBug
        __isExportingBug = True
        packed = __createPackedBlenderFile()

        projectDirectory = getWebProjectPath()
        if projectDirectory is None:
            return
        
        helperDirectory = projectDirectory + "/node_modules/@needle-tools/helper"
        if not os.path.exists(helperDirectory):
            debug_log("Can not report bug because helper directory does not exist:", helperDirectory)
            return
        
        global lastBugReportTime
        currentTime = time.time()
        if currentTime - lastBugReportTime < __minTimeBetweenBugReports:
            debug_log("Can not report bug because last bug report was less than " + __minTimeBetweenBugReports + " seconds ago")
            return
        
        lastBugReportTime = currentTime
        if packed and os.path.exists(packed):
            pathToCurrentBlendFile = packed
        else:
            pathToCurrentBlendFile = originalFilePath
        description = bpy.context.scene.NEEDLE_bugreport_description
        extraInformationFilePath = __generateAdditionalInformationFile(bpy.context.scene.NEEDLE_bugreport_contact, description)
        cmd = "npm run tool:generate-bugreport -- --file \"" + pathToCurrentBlendFile + "\""
        if extraInformationFilePath:
            cmd += " --extra \"" + extraInformationFilePath + "\""
        cmd += " --extra \"" + projectDirectory + "\""
        cmd += " --description \"" + description + "\""
        cmd += " & " + getTimeout(5)
        exec_command_standalone(cmd, helperDirectory)
    finally:
        __isExportingBug = False
        if originalFilePath and os.path.exists(originalFilePath) and originalFilePath != bpy.data.filepath:
            bpy.ops.wm.open_mainfile(filepath=originalFilePath, load_ui=True)
        # remove the packed file after 10 seconds to give it some time to be zipped etc
        # not entirely sure if we need it but can't hurt
        if packed and os.path.exists(packed):
            delay = 10
            debug_log("Removing packed bugreport file in " + str(delay) + " seconds:", packed)
            bpy.app.timers.register(lambda: os.remove(packed), first_interval=delay)


def __generateAdditionalInformationFile(contact:str, description:str) -> str:
    tempFilePath = bpy.app.tempdir + "bugreport.txt"
    if os.path.exists(tempFilePath):
        os.remove(tempFilePath)
    text = ""
    text += "Contact: " + contact + "\n"
    text += "Description: " + description + "\n"
    if bpy.data.filepath:
        text += "Blendfile: " + bpy.data.filepath + "\n"
    else:
        text += "Blendfile: <unsaved>\n"
    text += "Blender Version: " + bpy.app.version_string + "\n"
    text += "Addon Version: " + getVersion() + "\n"
    # write
    with open(tempFilePath, "w") as f:
        f.write(text)
        f.close()
    return tempFilePath

class reportBugOP(bpy.types.Operator):
    bl_idname = "needle.report_bug"
    bl_label = "Report Bug"
    bl_options = {"REGISTER"}
    bl_description = "Report a bug to the Needle Tools team"

    def execute(self, context):
        reportBug()
        return {"FINISHED"}
    

def register():
    print("Registering bugreport utils")
    bpy.types.Scene.NEEDLE_bugreport_contact = bpy.props.StringProperty(name="Contact Information", default="", description="Your email address or other contact information (link to discord discussion or github issue)")
    bpy.types.Scene.NEEDLE_bugreport_description = bpy.props.StringProperty(name="Description", default="", description="Describe the bug you encountered in as much detail as possible")

def unregister():
    try:
        del bpy.types.Scene.NEEDLE_bugreport_contact
        del bpy.types.Scene.NEEDLE_bugreport_description
    except:
        pass