#include "rive/importers/backboard_importer.hpp"
#include "rive/importers/import_stack.hpp"
#include "rive/importers/scripted_object_importer.hpp"
#include "rive/scripted/scripted_drawable.hpp"
#include "rive/script_input_artboard.hpp"
#include "rive/custom_property_container.hpp"

using namespace rive;

ScriptInputArtboard::~ScriptInputArtboard()
{
  auto obj = scriptedObject();
  if (obj != nullptr)
  {
    obj->removeProperty(this);
  }
  m_referencedArtboard = nullptr;
}

StatusCode ScriptInputArtboard::import(ImportStack& importStack)
{
  auto backboardImporter = importStack.latest<BackboardImporter>(
      Backboard::typeKey);
  if (backboardImporter == nullptr)
  {
    return StatusCode::MissingObject;
  }
  auto importer = ScriptInput::ownerImporter(importStack, this);
  if (importer == nullptr)
  {
    return StatusCode::MissingObject;
  }
  importer->addInput(this);

  auto obj = scriptedObject();
  if (obj && obj->component() != nullptr)
  {
    // If the ScriptedObject is a Component, this input is an artboard
    // child (File::readObjects gave it a slot, see takesArtboardSlot), so
    // import it as a Component, otherwise, return Ok
    StatusCode code = Super::import(importStack);
    if (code != StatusCode::Ok)
    {
      return code;
    }
  }
  // Registered last, and only once this object is certain to survive.
  backboardImporter->addArtboardReferencer(this);
  return StatusCode::Ok;
}

void ScriptInputArtboard::initScriptedValue()
{
  ScriptInput::initScriptedValue();
  syncReferencedArtboard();
}

bool ScriptInputArtboard::validateForColdScriptInit() { return true; }

bool ScriptInputArtboard::validateHydrationPrerequisites()
{
  return m_referencedArtboard != nullptr;
}

bool ScriptInputArtboard::hydrateScriptInput()
{
  initScriptedValue();
  return m_referencedArtboard != nullptr;
}

void ScriptInputArtboard::syncReferencedArtboard()
{

  if (m_referencedArtboard == nullptr)
  {
    return;
  }
  auto obj = scriptedObject();
  if (obj)
  {
    obj->setArtboardInput(name(), m_referencedArtboard);
  }
}

StatusCode ScriptInputArtboard::onAddedClean(CoreContext* context)
{
  StatusCode code = Super::onAddedClean(context);
  if (code != StatusCode::Ok)
  {
    return code;
  }

  auto p = parent();
  if (p != nullptr)
  {
    auto scriptedObj = ScriptedObject::from(p);
    if (scriptedObj != nullptr)
    {
      scriptedObj->addProperty(this);
    }
  }

  return StatusCode::Ok;
}

Core* ScriptInputArtboard::clone() const
{
  ScriptInputArtboard* twin = ScriptInputArtboardBase::clone()
                                  ->as<ScriptInputArtboard>();
  if (m_referencedArtboard != nullptr)
  {
    twin->referencedArtboard(m_referencedArtboard);
    twin->file(m_file);
  }
  return twin;
}

void ScriptInputArtboard::artboardIdChanged()
{
  if (m_file)
  {
    m_referencedArtboard = m_file->artboard(artboardId());
    syncReferencedArtboard();
  }
}

void ScriptInputArtboard::updateArtboard(
    ViewModelInstanceArtboard* viewModelInstanceArtboard)
{
  auto referencedArtboard = findArtboard(
      viewModelInstanceArtboard,
      artboard(),
      m_file);
  if (referencedArtboard)
  {
    m_referencedArtboard = referencedArtboard;
    syncReferencedArtboard();
  }
}

int ScriptInputArtboard::referencedArtboardId() { return artboardId(); }