#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"

#include <algorithm>

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)
    {
#ifdef WITH_RIVE_EDITOR
      if (prop->editorArena() != nullptr)
        continue;
#endif
      // 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();
  // Input binds join the converter's binds (addDataBindFromScriptedObject), so
  // they were bound above. Binding one again binds its converter again,
  // doubling the work at every scripted converter nested below it.
  const auto& binds = dataBinds();
  for (auto prop : m_customProperties)
  {
    auto input = ScriptInput::from(prop);
    if (input != nullptr && input->dataBind() != nullptr &&
        std::find(binds.begin(), binds.end(), input->dataBind()) == binds.end())
    {
      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)
{
  bool didAdvanceBinds = Super::advance(elapsedSeconds);
  if (elapsedSeconds == 0)
  {
    return didAdvanceBinds;
  }
  auto needsAdvance = scriptAdvance(elapsedSeconds);
  if (needsAdvance)
  {
    markConverterDirty();
  }
  return needsAdvance || didAdvanceBinds;
}

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;
}
#ifdef WITH_RIVE_EDITOR
void ScriptedDataConverter::editorPrepareForDestruction()
{
  scriptDispose();
  ScriptedObject::dataContext(nullptr);
  DataConverter::editorPrepareForDestruction();
}

#endif
