#ifndef RENDER_IBL_RESOURCES_H
#define RENDER_IBL_RESOURCES_H

#include "texture.h"

#include <DirectXMath.h>
#include <d3d11.h>
#include <wrl/client.h>

class IBLResources final {
public:
    // global 约定。材质拥有t0-t7；阴影拥有 t8/s2/b3。
    // static constexpr UINT ConstantBufferSlot = 4; // b4
    // static constexpr UINT IrradianceTextureSlot = 9; // t9
    // static constexpr UINT PrefilteredTextureSlot = 10; // t10
    // static constexpr UINT BrdfLutTextureSlot = 11; // t11
    // static constexpr UINT SamplerSlot = 3; // s3
    static constexpr UINT TextureCount = 3;

    struct Settings {
        float intensity = 1.0f;
        float rotationRadians = 0.0f;
        bool enabled = true;
    };

public:
    [[nodiscard]] bool Initialize(ID3D11Device *device);

    // 包装器不被拥有，但保留它们的 SRV COM 对象。 prefilteredEnvironment 必须包含 GGX 粗糙度 mip 链
    [[nodiscard]] bool SetTextures(const TextureCube *irradiance,
                                   const TextureCube *prefilteredEnvironment,
                                   const Texture2D *brdfLut);
    void ClearTextures() noexcept;

    void SetIntensity(float intensity) noexcept;
    void SetRotationRadians(float radians) noexcept;
    void SetEnabled(bool enabled) noexcept;
    void SetSettings(const Settings &settings) noexcept;

    [[nodiscard]] bool IsReady() const noexcept;
    [[nodiscard]] const Settings &GetSettings() const noexcept { return m_settings; }
    [[nodiscard]] float PrefilterMaxMip() const noexcept { return m_prefilterMaxMip; }

    [[nodiscard]] bool BindMainPass(ID3D11DeviceContext *context) const;
    void UnbindShaderResources(ID3D11DeviceContext *context) const;

private:
    struct alignas(16) ConstantBufferData {
        // x=intensity, y=prefilter max mip, z=Y rotation, w=enabled
        DirectX::XMFLOAT4 params{};
    };
    static_assert(sizeof(ConstantBufferData) % 16 == 0);

private:
    Settings m_settings{};
    float m_prefilterMaxMip = 0.0f;

    Microsoft::WRL::ComPtr<ID3D11ShaderResourceView> m_irradianceSRV;
    Microsoft::WRL::ComPtr<ID3D11ShaderResourceView> m_prefilteredSRV;
    Microsoft::WRL::ComPtr<ID3D11ShaderResourceView> m_brdfLutSRV;

    Microsoft::WRL::ComPtr<ID3D11SamplerState> m_sampler;
    Microsoft::WRL::ComPtr<ID3D11Buffer> m_constantBuffer;
};

#endif // RENDER_IBL_RESOURCES_H
