local CharacterFSMManager = require "app/module/character_fsm/character_fsm_manager"
local CharacterStateBase = require "app/module/character_fsm/states/character_state_base"
local CharacterStateDissolve = class("CharacterStateIce", CharacterStateBase)

local DISSOLVE_TEXTURE_PATH = "assets/arts/materials/textures/model_dissolve_turbulence.png"
local DISSOLVE_TEX_ID = CS.UnityEngine.Shader.PropertyToID("_dissolve_tex")
local DISSOLVE_PROGRESS_ID = CS.UnityEngine.Shader.PropertyToID("_d_progress")

function CharacterStateDissolve:enter(params)
    self.params = params
    self.dissolveFunc = function()
        local materials = self.characterObj:getCharacterMaterials()
        for _, material in ipairs(materials) do
            material:DisableKeyword(CharacterFSMManager.KEYWORD_NONE)
            material:DisableKeyword(CharacterFSMManager.KEYWORD_STONE)
            material:DisableKeyword(CharacterFSMManager.KEYWORD_ICE)
            material:DisableKeyword(CharacterFSMManager.KEYWORD_GLOW)
            material:EnableKeyword(CharacterFSMManager.KEYWORD_DISSOLVE)
        end

        self.sequence = self.characterObj:createBindTweenSequence()
        self.sequence:SetIntId(GConst.DOTWEEN_IDS.CHARACTER_EFFECT)
        local progress = 0
        local tween = DOTweenManager:createDOTweenTo(
            function()
                return progress
            end,
            function(x)
                progress = x
                if not self.characterObj or self.characterObj:isDestroyed() then
                    return
                end
                local renders = self.characterObj:getCharacterMeshRenderer()
                for _, render in ipairs(renders) do
                    local mpb = self.characterObj:getMaterialPropertyBlock()
                    render:GetPropertyBlock(mpb)
                    mpb:SetTexture(DISSOLVE_TEX_ID, self.dissolveTexture)
                    mpb:SetFloat(DISSOLVE_PROGRESS_ID, progress)
                    render:SetPropertyBlock(mpb)
                end
            end, 1, params.time)
        self.sequence:Append(tween)
        self.sequence:OnComplete(function()
            if params.callback then
                params.callback()
            end
            self.sequence = nil
        end)
        self.sequence.timeScale = self.characterObj.timeScale
    end

    if self.dissolveTexture then
        self:dissolveFunc()
    else
        TextureManager:loadTextureAsync(self.characterObj, DISSOLVE_TEXTURE_PATH, function(assetPath, texture)
            if self.characterObj then
                if self.dissolveTexture then
                    TextureManager:unLoadTexture(assetPath)
                else
                    self.dissolveTexture = texture
                end

                if self.dissolveFunc then
                    self:dissolveFunc()
                end
            else
                TextureManager:unLoadTexture(assetPath)
            end
        end)
    end
end

function CharacterStateDissolve:exit()
    self.dissolveFunc = nil
    if self.sequence then
        self.sequence:Kill()
        self.sequence = nil
        if self.params and self.params.needCallback then
            if self.params.callback then
                self.params.callback()
            end
        end
    end
    self.params = nil
end

function CharacterStateDissolve:clear()
    CharacterStateBase.clear(self)
    if self.dissolveTexture then
        TextureManager:unLoadTexture(DISSOLVE_TEXTURE_PATH)
        self.dissolveTexture = nil
    end
    self.dissolveFunc = nil
    if self.sequence then
        self.sequence:Kill()
        self.sequence = nil
        if self.params and self.params.needCallback then
            if self.params.callback then
                self.params.callback()
            end
        end
    end
    self.params = nil
end

return CharacterStateDissolve