#include "rive/assets/script_asset.hpp"
#include "rive/component_dirt.hpp"
#include "rive/data_bind/data_bind.hpp"
#include "rive/data_bind/data_bind_context.hpp"
#include "rive/data_bind/data_values/data_type.hpp"
#include "rive/data_bind/data_values/data_value.hpp"
#include "rive/data_bind/data_values/data_value_boolean.hpp"
#include "rive/data_bind/data_values/data_value_color.hpp"
#include "rive/data_bind/data_values/data_value_number.hpp"
#include "rive/data_bind/data_values/data_value_string.hpp"
#include "rive/scripted/scripted_data_converter.hpp"

using namespace rive;

ScriptedDataConverter::~ScriptedDataConverter()
{
    disposeScriptInputs();
    if (m_dataValue)
    {
        delete m_dataValue;
    }
}

void ScriptedDataConverter::disposeScriptInputs()
{
    auto props = m_customProperties;
    ScriptedObject::disposeScriptInputs();
    for (auto prop : props)
    {
        auto scriptInput = ScriptInput::from(prop);
        if (scriptInput != nullptr)
        {
            // ScriptedDataConverters need to delete their own inputs
            // because they are not components
            delete scriptInput;
        }
    }
}

#ifdef WITH_RIVE_SCRIPTING

void ScriptedDataConverter::didHydrateScriptInputs()
{
    addScriptedDirt(ComponentDirt::Bindings);
}

DataValue* ScriptedDataConverter::applyConversion(DataValue* value,
                                                  const std::string& method)
{
    if (m_vm == nullptr || !m_vm->valid() || m_self == 0)
    {
        return value;
    }
    ScriptBackend::ScriptDataResult result;
    if (!m_vm->callDataConvert(this, m_self, method.c_str(), value, &result))
    {
        // Assumed for legacy files but not implemented; pass the value through
        // unchanged (same as !dataConverts()).
        return value;
    }
    switch (result.kind)
    {
        case ScriptBackend::ScriptDataResult::Kind::number:
            storeData<DataValueNumber>(result.number);
            break;
        case ScriptBackend::ScriptDataResult::Kind::string:
            storeData<DataValueString>(result.string);
            break;
        case ScriptBackend::ScriptDataResult::Kind::boolean:
            storeData<DataValueBoolean>(result.boolean);
            break;
        case ScriptBackend::ScriptDataResult::Kind::color:
            storeData<DataValueColor>(result.color);
            break;
        case ScriptBackend::ScriptDataResult::Kind::none:
            break;
    }
    if (!m_dataValue)
    {
        m_dataValue = new DataValue();
    }
    return m_dataValue;
}

DataValue* ScriptedDataConverter::convert(DataValue* value, DataBind* dataBind)
{
    if (dataConverts())
    {
        return applyConversion(value, "convert");
    }
    return value;
}

DataValue* ScriptedDataConverter::reverseConvert(DataValue* value,
                                                 DataBind* dataBind)
{
    if (dataReverseConverts())
    {
        return applyConversion(value, "reverseConvert");
    }
    return value;
}
#endif

void ScriptedDataConverter::bindFromContext(DataContext* dataContext,
                                            DataBind* dataBind)
{
    Super::bindFromContext(dataContext, dataBind);
    reinit();
    for (auto prop : m_customProperties)
    {
        auto input = ScriptInput::from(prop);
        if (input != nullptr)
        {
            if (input->dataBind() != nullptr)
            {
                input->dataBind()->as<DataBindContext>()->bindFromContext(
                    dataContext);
            }
        }
    }
}

bool ScriptedDataConverter::advanceComponent(float elapsedSeconds,
                                             AdvanceFlags flags)
{
    if (!enums::is_flag_set(flags, AdvanceFlags::AdvanceNested))
    {
        elapsedSeconds = 0;
    }
    return advance(elapsedSeconds);
}

bool ScriptedDataConverter::advance(float elapsedSeconds)
{

    if (elapsedSeconds == 0)
    {
        return false;
    }
    auto needsAdvance = scriptAdvance(elapsedSeconds);
    if (needsAdvance)
    {
        markConverterDirty();
    }
    return needsAdvance;
}

void ScriptedDataConverter::addProperty(CustomProperty* prop)
{
    auto scriptInput = ScriptInput::from(prop);
    if (scriptInput != nullptr)
    {
        scriptInput->scriptedObject(this);
    }
    CustomPropertyContainer::addProperty(prop);
}

StatusCode ScriptedDataConverter::import(ImportStack& importStack)
{
    auto result = registerReferencer(importStack);
    if (result != StatusCode::Ok)
    {
        return result;
    }
    return Super::import(importStack);
}

Core* ScriptedDataConverter::clone() const
{
    ScriptedDataConverter* twin =
        ScriptedDataConverterBase::clone()->as<ScriptedDataConverter>();
    if (m_fileAsset != nullptr)
    {
        twin->setAsset(m_fileAsset);
    }
    for (auto prop : m_customProperties)
    {
        auto clonedValue = prop->clone()->as<CustomProperty>();
        twin->addProperty(clonedValue);
        auto scriptedInputClone = ScriptInput::from(clonedValue);
        auto scriptedInputSource = ScriptInput::from(prop);
        auto thisDataBinds = dataBinds();
        auto twinDataBinds = twin->dataBinds();
        if (scriptedInputClone && scriptedInputSource)
        {
            if (scriptedInputSource->dataBind())
            {
                int index = 0;
                // Data binds are cloned in the data converters, and assigned to
                // the right target here
                for (auto& dataBind : thisDataBinds)
                {
                    if (dataBind->target() == prop)
                    {
                        if (index < twinDataBinds.size())
                        {
                            twinDataBinds[index]->target(clonedValue);
                            scriptedInputClone->dataBind(twinDataBinds[index]);
                        }
                    }
                    index++;
                }
            }
        }
    }
    return twin;
}

bool ScriptedDataConverter::addDataBindFromScriptedObject(DataBind* dataBind)
{
    addDataBind(dataBind);
    return true;
}