#include "rive/data_bind/data_bind.hpp"
#include "rive/artboard.hpp"
#include "rive/data_bind_flags.hpp"
#include "rive/generated/core_registry.hpp"
#include "rive/data_bind/bindable_property_artboard.hpp"
#include "rive/data_bind/bindable_property_asset.hpp"
#include "rive/data_bind/bindable_property_number.hpp"
#include "rive/data_bind/bindable_property_string.hpp"
#include "rive/data_bind/bindable_property_color.hpp"
#include "rive/data_bind/bindable_property_enum.hpp"
#include "rive/data_bind/bindable_property_list.hpp"
#include "rive/data_bind/bindable_property_boolean.hpp"
#include "rive/data_bind/bindable_property_trigger.hpp"
#include "rive/data_bind/bindable_property_integer.hpp"
#include "rive/data_bind/bindable_property_viewmodel.hpp"
#include "rive/data_bind/data_bind_container.hpp"
#include "rive/data_bind/context/context_value.hpp"
#include "rive/data_bind/context/context_value_any.hpp"
#include "rive/data_bind/context/context_value_asset_image.hpp"
#include "rive/data_bind/context/context_value_asset_font.hpp"
#include "rive/data_bind/context/context_value_asset_blob.hpp"
#include "rive/data_bind/context/context_value_artboard.hpp"
#include "rive/data_bind/context/context_value_boolean.hpp"
#include "rive/data_bind/context/context_value_number.hpp"
#include "rive/data_bind/context/context_value_string.hpp"
#include "rive/data_bind/context/context_value_enum.hpp"
#include "rive/data_bind/context/context_value_list.hpp"
#include "rive/data_bind/context/context_value_color.hpp"
#include "rive/data_bind/context/context_value_trigger.hpp"
#include "rive/data_bind/context/context_value_symbol_list_index.hpp"
#include "rive/data_bind/context/context_value_viewmodel.hpp"
#include "rive/data_bind/data_values/data_type.hpp"
#include "rive/data_bind/converters/data_converter.hpp"
#include "rive/data_bind/converters/formula/formula_token.hpp"
#include "rive/constraints/scrolling/scroll_constraint.hpp"
#include "rive/animation/transition_viewmodel_condition.hpp"
#include "rive/animation/state_machine.hpp"
#include "rive/artboard_component_list.hpp"
#include "rive/generated/node_base.hpp"
#include "rive/importers/artboard_importer.hpp"
#include "rive/importers/state_machine_importer.hpp"
#include "rive/importers/backboard_importer.hpp"
#include "rive/component.hpp"

using namespace rive;

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

    return StatusCode::Ok;
}

StatusCode DataBind::import(ImportStack& importStack)
{
    auto backboardImporter =
        importStack.latest<BackboardImporter>(Backboard::typeKey);
    if (backboardImporter == nullptr)
    {
        return StatusCode::MissingObject;
    }
    file(backboardImporter->file());
    backboardImporter->addDataConverterReferencer(this);
    if (target())
    {
        initialize();
        auto input = ScriptInput::from(target());
        if (input != nullptr)
        {
            bool ownsDataBind = true;
            if (input->scriptedObject() != nullptr)
            {
                if (input->scriptedObject()->component() != nullptr)
                {
                    auto importer = importStack.latest<ArtboardImporter>(
                        ArtboardBase::typeKey);
                    if (importer != nullptr)
                    {
                        ownsDataBind = false;
                        importer->addDataBind(this);
                    }
                }
                else if (input->scriptedObject()->addDataBindFromScriptedObject(
                             this))
                {
                    ownsDataBind = false;
                }
            }
            input->dataBind(this, ownsDataBind);
        }
        else if (target()->is<DataConverter>())
        {
            target()->as<DataConverter>()->addDataBind(this);
        }
        else if (target()->is<FormulaToken>())
        {
            target()->as<FormulaToken>()->addDataBind(this);
        }
        else
        {
            switch (target()->coreType())
            {
                case BindablePropertyNumberBase::typeKey:
                case BindablePropertyStringBase::typeKey:
                case BindablePropertyBooleanBase::typeKey:
                case BindablePropertyEnumBase::typeKey:
                case BindablePropertyArtboardBase::typeKey:
                case BindablePropertyColorBase::typeKey:
                case BindablePropertyTriggerBase::typeKey:
                case BindablePropertyIntegerBase::typeKey:
                case BindablePropertyAssetBase::typeKey:
                case BindablePropertyViewModelBase::typeKey:
                case BindablePropertyListBase::typeKey:
                case TransitionPropertyViewModelComparatorBase::typeKey:
                case StateTransitionBase::typeKey:
                {
                    auto stateMachineImporter =
                        importStack.latest<StateMachineImporter>(
                            StateMachineBase::typeKey);
                    if (stateMachineImporter != nullptr)
                    {
                        stateMachineImporter->addDataBind(
                            std::unique_ptr<DataBind>(this));
                        return Super::import(importStack);
                    }
                    break;
                }
                default:
                {
                    // Prefer the artboard that actually owns the target object.
                    // Relying on latest<ArtboardImporter> can attach binds to
                    // the wrong source artboard when multiple artboards are
                    // loaded.
                    if (target()->is<Component>())
                    {
                        auto comp = target()->as<Component>();
                        auto parentArtboard = comp->artboard();
                        if (parentArtboard != nullptr)
                        {
                            parentArtboard->addDataBind(this);
                            return Super::import(importStack);
                        }
                    }

                    auto artboardImporter =
                        importStack.latest<ArtboardImporter>(
                            ArtboardBase::typeKey);
                    if (artboardImporter != nullptr)
                    {
                        artboardImporter->addDataBind(this);
                        return Super::import(importStack);
                    }
                    break;
                }
            }
        }
    }

    return Super::import(importStack);
}

DataType DataBind::outputType()
{
    if (converter() && converter()->outputType() != DataType::input &&
        converter() && converter()->outputType() != DataType::none)
    {
        return converter()->outputType();
    }
    return sourceOutputType();
}

DataType DataBind::sourceOutputType()
{
    if (m_Source != nullptr)
    {
        switch (m_Source->coreType())
        {
            case ViewModelInstanceNumberBase::typeKey:
                return DataType::number;
            case ViewModelInstanceStringBase::typeKey:
                return DataType::string;
            case ViewModelInstanceEnumBase::typeKey:
                return DataType::enumType;
            case ViewModelInstanceColorBase::typeKey:
                return DataType::color;
            case ViewModelInstanceBooleanBase::typeKey:
                return DataType::boolean;
            case ViewModelInstanceListBase::typeKey:
                return DataType::list;
            case ViewModelInstanceTriggerBase::typeKey:
                return DataType::trigger;
            case ViewModelInstanceSymbolListIndexBase::typeKey:
                return DataType::symbolListIndex;
            case ViewModelInstanceAssetImageBase::typeKey:
                return DataType::assetImage;
            case ViewModelInstanceAssetFontBase::typeKey:
                return DataType::assetFont;
            case ViewModelInstanceAssetBlobBase::typeKey:
                return DataType::assetBlob;
            case ViewModelInstanceArtboardBase::typeKey:
                return DataType::artboard;
            case ViewModelInstanceViewModelBase::typeKey:
                return DataType::viewModel;
        }
    }
    return DataType::none;
}

void DataBind::source(rcp<ViewModelInstanceValue> value)
{
    if (!bindsOnce())
    {
        value->addDependent(this);
    }
    m_Source = value;

    // We treat this as a special case. If an ArtboardComponentList's list
    // property is bound to a number instance, we know that the component
    // will be provided with dettached view model instances that need to be
    // advanced explicitly
    if (m_Source && target() && target()->is<ArtboardComponentList>())
    {
        target()->as<ArtboardComponentList>()->shouldResetInstances(
            m_Source->coreType() == ViewModelInstanceNumberBase::typeKey);
    }
}

void DataBind::clearSource()
{
    if (m_Source != nullptr)
    {

        if (!bindsOnce())
        {
            m_Source->removeDependent(this);
        }
        m_Source = nullptr;
    }
}

DataBind::~DataBind()
{
    unbind();
    delete m_ContextValue;
    m_ContextValue = nullptr;
    delete m_dataConverter;
    m_dataConverter = nullptr;
}

void DataBind::bind()
{
    delete m_ContextValue;
    m_ContextValue = nullptr;
    switch (outputType())
    {
        case DataType::number:
            m_ContextValue = new DataBindContextValueNumber(this);
            break;
        case DataType::string:
            m_ContextValue = new DataBindContextValueString(this);
            break;
        case DataType::boolean:
            m_ContextValue = new DataBindContextValueBoolean(this);
            break;
        case DataType::color:
            m_ContextValue = new DataBindContextValueColor(this);
            break;
        case DataType::enumType:
            m_ContextValue = new DataBindContextValueEnum(this);
            break;
        case DataType::list:
            m_ContextValue = new DataBindContextValueList(this);
            break;
        case DataType::trigger:
            m_ContextValue = new DataBindContextValueTrigger(this);
            break;
        case DataType::symbolListIndex:
            m_ContextValue = new DataBindContextValueSymbolListIndex(this);
            break;
        case DataType::assetImage:
            m_ContextValue = new DataBindContextValueAssetImage(this);
            break;
        case DataType::assetFont:
            m_ContextValue = new DataBindContextValueAssetFont(this);
            break;
        case DataType::assetBlob:
            m_ContextValue = new DataBindContextValueAssetBlob(this);
            break;
        case DataType::artboard:
            m_ContextValue = new DataBindContextValueArtboard(this);
            break;
        case DataType::viewModel:
            m_ContextValue = new DataBindContextValueViewModel(this);
            break;
        case DataType::any:
            m_ContextValue = new DataBindContextValueAny(this);
            break;
        default:
            break;
    }
    if (m_dataConverter)
    {
        m_dataConverter->reset();
    }
    // if this is a toSource bind on a push-capable target,
    // subscribe to the target's notifyPropertyChanged stream instead of
    // relying on per-frame polling. The container consults targetSupportsPush()
    // to decide whether to also enroll the bind in m_persistingDataBinds.
    //
    // bind() can be called more than once on the same DataBind (e.g. when
    // ArtboardComponentList rebinds list items as the viewmodel changes).
    // Unsubscribe first if we previously subscribed — otherwise
    // addPropertyObserver would prepend the same node twice and form a cycle
    // that makes notifyPropertyChanged loop forever. The Observing flag
    // gates this so we don't deref m_target when we never subscribed (which
    // would be a UAF if the target was freed first).
    if (hasFlag(Flag::Observing) && m_target != nullptr)
    {
        m_target->removePropertyObserver(this);
        setFlag(Flag::Observing, false);
    }
    if (toSource() && m_target != nullptr && targetSupportsPush())
    {
        m_target->addPropertyObserver(this);
        setFlag(Flag::Observing, true);
    }
    // (Re)bind is a reconcile, not a one-sided change: mark every direction the
    // bind supports so both sides sync in favor order (as before origin gating
    // existed). A one-sided change instead marks only its own direction bit.
    addDirt(reconcileDirt(), true);
}

void DataBind::target(Core* value)
{
    if (m_target == value)
    {
        return;
    }
    // Drop the subscription only when we actually have one — otherwise
    // dereferencing m_target is a UAF if the old target was freed before us
    // (we wouldn't have been notified via onTargetDestroyed because we
    // weren't in its observer list).
    if (hasFlag(Flag::Observing) && m_target != nullptr)
    {
        m_target->removePropertyObserver(this);
        setFlag(Flag::Observing, false);
    }
    m_target = value;
    if (toSource() && m_target != nullptr && targetSupportsPush())
    {
        m_target->addPropertyObserver(this);
        setFlag(Flag::Observing, true);
    }
}

void DataBind::unbind()
{
    clearSource();
    if (hasFlag(Flag::Observing) && m_target != nullptr)
    {
        m_target->removePropertyObserver(this);
        setFlag(Flag::Observing, false);
    }
    if (m_dataConverter != nullptr)
    {
        m_dataConverter->unbind();
    }
    if (m_ContextValue != nullptr)
    {
        delete m_ContextValue;
        m_ContextValue = nullptr;
    }
}

bool DataBind::targetSupportsPush() const
{
    if (m_target == nullptr)
    {
        return false;
    }
    // Push works for any property whose value is exposed via a generated
    // setter that calls notifyPropertyChanged (i.e. anything in *_base.hpp).
    // The following targets are computed/derived and don't fit the push
    // model — leave them on the polling path:
    //
    //   * Solo's activeComponentId — derived from active child, no setter
    //   * BindablePropertyAsset's image — loaded asynchronously, no setter
    //   * BindablePropertyViewModel's value — set via dedicated method
    //   * ViewModelInstanceViewModel's reference — set via dedicated method
    //   * Node's computed* properties — written multiple times per frame by
    //     the transform/layout pipeline; pushing on every intermediate write
    //     triggers dependent binds mid-computation and shifts per-frame
    //     ordering. Polling at end of frame captures only the settled value.
    auto key = propertyKey();
    if (key == SoloBase::activeComponentIdPropertyKey ||
        key == NodeBase::computedLocalXPropertyKey ||
        key == NodeBase::computedLocalYPropertyKey ||
        key == NodeBase::computedWorldXPropertyKey ||
        key == NodeBase::computedWorldYPropertyKey ||
        key == NodeBase::computedRootXPropertyKey ||
        key == NodeBase::computedRootYPropertyKey ||
        key == NodeBase::computedWidthPropertyKey ||
        key == NodeBase::computedHeightPropertyKey ||
        key == ShapeBase::lengthPropertyKey ||
        key == ScrollConstraintBase::scrollIndexPropertyKey ||
        key == ScrollConstraintBase::scrollPercentXPropertyKey ||
        key == ScrollConstraintBase::scrollPercentYPropertyKey ||
        key == ScrollConstraintBase::velocityXPropertyKey ||
        key == ScrollConstraintBase::velocityYPropertyKey ||
        key == ScrollConstraintBase::scrollActivePropertyKey ||
        key == ScrollConstraintBase::computedContentWidthPropertyKey ||
        key == ScrollConstraintBase::computedContentHeightPropertyKey)
    {
        return false;
    }
    auto t = m_target->coreType();
    if (t == BindablePropertyAssetBase::typeKey ||
        t == BindablePropertyViewModelBase::typeKey ||
        t == ViewModelInstanceViewModelBase::typeKey)
    {
        return false;
    }
    return true;
}

bool DataBind::canSkip()
{
    return m_target && m_target->is<Component>() &&
           m_target->as<Component>()->isCollapsed() &&
           propertyKey() != LayoutComponentStyleBase::displayValuePropertyKey;
}

void DataBind::update(ComponentDirt value)
{
    if (m_Source != nullptr && m_ContextValue != nullptr)
    {
        if ((value & ComponentDirt::Bindings) == ComponentDirt::Bindings)
        {
            // TODO: @hernan review how dirt and mode work together. If dirt is
            // not set for certain modes, we might be able to skip the mode
            // validation.
            auto flagsValue = static_cast<DataBindFlags>(flags());
            if (toTarget())
            {
                // Alternative A: a TwoWay bind subscribes to its target via
                // Core::notifyPropertyChanged. Without suppression, writing
                // the target here would push-notify ourselves and add a
                // spurious dirt entry, causing an extra updateSourceBinding
                // pass in the same frame (silver tests collapse_data_binds-
                // test_2 / virtualize_blendmode regress). Mirror the
                // suppressDirt pattern used by the source-apply path.
                suppressDirt(true);
                m_ContextValue->apply(m_target,
                                      propertyKey(),
                                      (flagsValue & DataBindFlags::Direction) ==
                                          DataBindFlags::ToTarget,
                                      this);
                // We just wrote the target; sync the cached target value so it
                // reflects what we wrote instead of what was there before.
                m_ContextValue->refreshTargetValue(this);
                suppressDirt(false);
            }
        }
    }
}

void DataBind::updateDependents()
{
    if (m_dataConverter)
    {
        m_dataConverter->update();
    }
}

void DataBind::updateSourceBinding(bool invalidate)
{
    if (toSource() && m_target && m_ContextValue != nullptr)
    {
        if (invalidate)
        {
            m_ContextValue->invalidate();
        }
        m_ContextValue->applyToSource(m_target,
                                      propertyKey(),
                                      isMainToSource(),
                                      this);
    }
}

bool DataBind::isMainToSource()
{
    auto flagsValue = static_cast<DataBindFlags>(flags());
    return (flagsValue & DataBindFlags::Direction) == DataBindFlags::ToSource;
}

bool DataBind::sourceToTargetRunsFirst()
{
    auto flagsValue = static_cast<DataBindFlags>(flags());
    return (flagsValue & DataBindFlags::SourceToTargetRunsFirst) ==
           DataBindFlags::SourceToTargetRunsFirst;
}

ComponentDirt DataBind::reconcileDirt()
{
    return (toTarget() ? ComponentDirt::Bindings : ComponentDirt::None) |
           (toSource() ? ComponentDirt::BindingsTarget : ComponentDirt::None);
}

void DataBind::addDirt(ComponentDirt value, bool recurse)
{
    if (hasFlag(Flag::SuppressDirt) || (m_Dirt & value) == value)
    {
        // Already marked.
        return;
    }

    // Latch the direction this change came from so a converter that re-dirties
    // us over multiple frames (interpolators) re-asserts the same direction —
    // per-frame dirt gets cleared and can't carry the origin forward. Placed
    // after the guards above so a suppressed self-notify (from applying either
    // direction) can't flip the origin. Record a single origin, never the OR:
    // a reconcile marks both bits, in which case the favored direction wins.
    bool hasSource = enums::is_flag_set(value, ComponentDirt::Bindings);
    bool hasTarget = enums::is_flag_set(value, ComponentDirt::BindingsTarget);
    if (hasSource && hasTarget)
    {
        setFlag(Flag::TargetOrigin, !sourceToTargetRunsFirst());
    }
    else if (hasTarget)
    {
        setFlag(Flag::TargetOrigin, true);
    }
    else if (hasSource)
    {
        setFlag(Flag::TargetOrigin, false);
    }

    m_Dirt |= value;
#ifdef WITH_RIVE_TOOLS
    if (m_changedCallback != nullptr)
    {
        m_changedCallback();
    }
#endif
    if (enums::is_flag_set(m_Dirt, ComponentDirt::Dependents) &&
        m_ContextValue != nullptr)
    {
        m_ContextValue->invalidate();
    }
    if (m_container && !hasFlag(Flag::Collapsed))
    {
        m_container->addDirtyDataBind(this);
    }
}

void DataBind::container(DataBindContainer* container)
{
    m_container = container;
}

void DataBind::relinkDataBind() { m_container->rebuildDataBind(this); }

bool DataBind::bindsOnce()
{
    auto flagsValue = static_cast<DataBindFlags>(flags());
    return enums::is_flag_set(flagsValue, DataBindFlags::Once);
}

bool DataBind::toSource()
{
    auto flagsValue = static_cast<DataBindFlags>(flags());
    return enums::any_flag_set(flagsValue,
                               DataBindFlags::TwoWay | DataBindFlags::ToSource);
}

bool DataBind::toTarget()
{
    auto flagsValue = static_cast<DataBindFlags>(flags());
    return enums::is_flag_set(flagsValue, DataBindFlags::TwoWay) ||
           !enums::is_flag_set(flagsValue, DataBindFlags::ToSource);
}

bool DataBind::isNameBased()
{
    auto flagsValue = static_cast<DataBindFlags>(flags());
    return enums::is_flag_set(flagsValue, DataBindFlags::NameBased);
}

bool DataBind::advance(float elapsedTime)
{
    if (converter() && m_Source && !hasFlag(Flag::Collapsed))
    {
        return converter()->advance(elapsedTime);
    }
    return false;
}

void DataBind::file(File* value) { m_file = value; };

File* DataBind::file() const { return m_file; };

void DataBind::collapse(bool isCollapsed)
{
    if (hasFlag(Flag::Collapsed) == isCollapsed ||
        propertyKey() == LayoutComponentStyleBase::displayValuePropertyKey ||
        !targetSupportsPush())
    {
        return;
    }
    setFlag(Flag::Collapsed, isCollapsed);
    if (!isCollapsed && m_Dirt != ComponentDirt::None && m_container)
    {
        m_container->addDirtyDataBind(this);
    }
}

void DataBind::initialize()
{
    if (target() && target()->is<Component>())
    {
        target()->as<Component>()->addCollapsable(this);
    }
}