#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 =
        importStack.latest<ScriptedObjectImporter>(ScriptedDrawable::typeKey);
    if (importer == nullptr)
    {
        return StatusCode::MissingObject;
    }
    importer->addInput(this);

    auto obj = scriptedObject();
    if (obj && obj->component() != nullptr)
    {
        // If the ScriptedObject is a Component, we need the ArtboardImporter
        // to add 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(); }