import os
from ..blender_materials import createImageWithColor
import bpy
from ..utils_debug import debug_log
import shutil

def copyFileFromTo(source: str, target:str):
    source = bpy.path.abspath(source)
    target = bpy.path.abspath(target)
    shutil.copyfile(source, target)

def tryGetSkyboxPath(blender_scene):
    world = blender_scene.world
    if world is not None:
        if world.use_nodes == False:
            return None
        node_tree = world.node_tree
        if node_tree is not None:
            nodes = node_tree.nodes
            for node in nodes:
                if node.type == 'TEX_ENVIRONMENT':
                    image = node.image
                    if image is not None:
                        return image.filepath
    return None

class EnvironmentImage:
    name = None
    path = None
    image = None

class SkyboxSettings:
    background_color = None
    environment_image = None | EnvironmentImage
    blur = None
    intensity = 1
    rotation = 0
    opacity = None

    def __init__(self) -> None:
        self.environment_image = None
        pass

def tryGetViewportSkyboxSettings() -> SkyboxSettings:
    # TODO: this should probably return the scene world light settings / EXR settings if they're assigned
    world = bpy.context.scene.world
    for area in bpy.context.screen.areas: # iterate through areas in current screen
        if area.type == 'VIEW_3D':
            for space in area.spaces: # iterate through spaces in current VIEW_3D area
                if space.type == 'VIEW_3D':

                    result = SkyboxSettings()
                    
                    # EXPORT WORLD LIGHTING SETTINGS
                    if space.shading.use_scene_world:
                        if world is None:
                            debug_log("No world found")
                            return None
                        space.shading.background_type = "THEME"
                        result.background_color = world.color
                        
                        # first try if we can find a texture node
                        nodes = world.node_tree.nodes
                        isUsingImageBackground = False
                        strength = 1
                        for node in nodes:
                            if node.type == 'BACKGROUND':
                                strength = node.inputs['Strength'].default_value
                                continue
                            if node.type == 'TEX_IMAGE' or node.type == 'TEX_ENVIRONMENT':
                                image = node.image
                                if image is not None:
                                    isUsingImageBackground = True
                                    canUseImage = True
                                    # check if the image exists on disc
                                    
                                    fullPath = bpy.path.abspath(image.filepath)
                                    filepath = fullPath
                                    # if we're exporting an EXR or HDR we need the file on disc
                                    if not os.path.exists(fullPath):
                                        # check if the image is packed
                                        if image.packed_file is not None:
                                            canUseImage = False
                                            import tempfile
                                            tempDir = tempfile.gettempdir()
                                            # save to disc at temp path
                                            filename = image.name
                                            dir = os.path.join(tempDir, "Needle", "Blender", "Temp")
                                            if not os.path.exists(dir):
                                                os.makedirs(dir)
                                            # check if the file already exists
                                            newFilePath = os.path.join(dir, filename)
                                            needsWrite = True
                                            if os.path.exists(newFilePath):
                                                file_size = os.path.getsize(newFilePath)
                                                if file_size == image.packed_file.size:
                                                    needsWrite = False # < file exists and has the same size
                                            if needsWrite:
                                                debug_log(f"Image {image.name} is packed: will unpack to {newFilePath}")
                                                with open(newFilePath, "wb") as f:
                                                    f.write(image.packed_file.data)
                                            # check if the file exists
                                            if os.path.exists(newFilePath):
                                                filepath = newFilePath
                                                canUseImage = True
                                                debug_log(f"Use packed image from {newFilePath}")
                                            
                                    result.environment_image = EnvironmentImage()
                                    result.environment_image.name = image.name
                                    result.environment_image.image = image
                                    if canUseImage:
                                        result.environment_image.path = filepath
                                    result.opacity = 1
                                    result.intensity = strength
                                    # target_path = texture_directory + "/" + image.name
                                    # copyFileFromTo(image.filepath, target_path)
                                    # return (image.name, False)
                                    # skyboxImage = loadImage(image.filepath)
                                    # applyFactor(skyboxImage, strength)
                                    # return (skyboxImage, True)
                        
                        # if not try to find a color node
                        if not isUsingImageBackground:
                            for node in nodes:
                                if node.type == 'BACKGROUND':
                                    colorValue = node.inputs[0].default_value
                                    strengthValue = node.inputs[1].default_value
                                    color = (
                                        colorValue[0] * strengthValue,
                                        colorValue[1] * strengthValue,
                                        colorValue[2] * strengthValue,
                                        colorValue[3])
                                    result.background_color = color
                                    # TODO: we need to create an image from this color and pass it out for the lightmap extension
                                    # image = bpy.data.images.new(name="Color", width=width, height=height, float_buffer=True)
                                    # image = createImageWithColor(color, 64, 64, "skybox_color")
                                    # result["environment_image"] = image


                    # EXPORT VIEWPORT LIGHTING SETTINGS
                    else:
                        selected_light = space.shading.selected_studio_light
                        if selected_light.name == "Default":
                            for light in bpy.context.preferences.studio_lights:
                                if light.path and light.name == "forest.exr":
                                    if light.path.endswith(".hdr") or light.path.endswith(".exr"):
                                        selected_light = light
                                        break
                        if selected_light and selected_light.path:
                            result.environment_image = EnvironmentImage()
                            result.environment_image.path = selected_light.path
                            result.environment_image.name = selected_light.name
                        else:
                            debug_log("Could not find a viewport skybox...")
                        result.blur = space.shading.studiolight_background_blur
                        result.intensity = space.shading.studiolight_intensity
                        result.rotation = space.shading.studiolight_rotate_z
                        result.opacity = space.shading.studiolight_background_alpha

                        if result.opacity < .5 and space.shading.background_type == "THEME":
                            debug_log("Set background type to world because the environment opacity is < 0.5")
                            space.shading.background_type = "WORLD"
                        
                        if world:
                            result.background_color = world.color
                        # get world viewport display color
                        # color = space.shading.studiolight_background_color
                    
                    return result
