#include <sstream>
#include <iomanip>
#include <array>

#include "rive/viewmodel/viewmodel_instance.hpp"
#include "rive/viewmodel/viewmodel.hpp"
#include "rive/viewmodel/viewmodel_instance_value.hpp"
#include "rive/viewmodel/viewmodel_instance_number.hpp"
#include "rive/viewmodel/viewmodel_instance_viewmodel.hpp"
#include "rive/viewmodel/viewmodel_instance_symbol_list_index.hpp"
#include "rive/file.hpp"
#include "rive/backboard.hpp"
#include "rive/importers/backboard_importer.hpp"
#include "rive/importers/artboard_importer.hpp"
#include "rive/viewmodel/viewmodel_property_viewmodel.hpp"
#include "rive/core_context.hpp"
#include "rive/refcnt.hpp"
#include "rive/artboard.hpp"

using namespace rive;

ViewModelInstance::~ViewModelInstance()
{
    for (auto& value : m_PropertyValues)
    {
        if (value->is<ViewModelInstanceViewModel>())
        {
            auto vmInstanceViewModel = value->as<ViewModelInstanceViewModel>();
            if (vmInstanceViewModel->referenceViewModelInstance())
            {
                vmInstanceViewModel->referenceViewModelInstance()->removeParent(
                    this);
            }
        }
    }
    m_PropertyValues.clear();
    if (m_ViewModel != nullptr)
    {
        m_ViewModel->unref();
    }
}

void ViewModelInstance::addValue(ViewModelInstanceValue* value)
{
    // Check if already added (can happen when both import() and onAddedDirty()
    // add the same value).
    for (const auto& existing : m_PropertyValues)
    {
        if (existing.get() == value)
        {
            return;
        }
    }
    if (value)
    {
        value->viewModelInstance(this);
    }
    if (value->viewModelProperty() != nullptr &&
        (SymbolType)value->viewModelProperty()->symbolTypeValue() !=
            SymbolType::none)
    {
        propertyValue((SymbolType)value->viewModelProperty()->symbolTypeValue(),
                      value);
    }
    m_PropertyValues.push_back(rcp<ViewModelInstanceValue>(value));
}

bool ViewModelInstance::removeValue(uint32_t propertyId)
{
    for (auto it = m_PropertyValues.begin(); it != m_PropertyValues.end(); ++it)
    {
        auto value = *it;
        if (value->viewModelPropertyId() != propertyId)
        {
            continue;
        }
        // Mirror the destructor cleanup for nested view model references.
        if (value->is<ViewModelInstanceViewModel>())
        {
            auto vmInstanceViewModel = value->as<ViewModelInstanceViewModel>();
            if (vmInstanceViewModel->referenceViewModelInstance())
            {
                vmInstanceViewModel->referenceViewModelInstance()->removeParent(
                    this);
            }
        }
        // Drop any symbol-table entry pointing at this value.
        for (auto sit = m_propertySymbols.begin();
             sit != m_propertySymbols.end();)
        {
            if (sit->second == value.get())
            {
                sit = m_propertySymbols.erase(sit);
            }
            else
            {
                ++sit;
            }
        }
        m_PropertyValues.erase(it); // rcp releases the value
        return true;
    }
    return false;
}

ViewModelInstanceValue* ViewModelInstance::propertyValue(const uint32_t id)
{
    for (auto value : m_PropertyValues)
    {
        if (value->viewModelPropertyId() == id)
        {
            return value.get();
        }
    }
    return nullptr;
}

bool ViewModelInstance::replaceViewModelByName(const std::string& name,
                                               rcp<ViewModelInstance> value)
{
    auto viewModelProperty = viewModel()->property(name);
    if (viewModelProperty != nullptr)
    {
        for (auto propertyValue : m_PropertyValues)
        {
            if (propertyValue->viewModelProperty() == viewModelProperty)
            {
                if (value->viewModelId() ==
                    viewModelProperty->as<ViewModelPropertyViewModel>()
                        ->viewModelReferenceId())
                {
                    auto previousViewModelInstance =
                        propertyValue->as<ViewModelInstanceViewModel>()
                            ->referenceViewModelInstance();
                    propertyValue->as<ViewModelInstanceViewModel>()
                        ->referenceViewModelInstance(value);
                    // Invalidate value-level dependents (e.g. scripted property
                    // wrappers) so cached references to the previous instance
                    // are dropped. Multiple dependents can share this property.
                    // Snapshot because relinkDataBind can mutate the dependents
                    // list.
                    auto dependentsSnapshot = propertyValue->dependents();
                    for (auto& dependent : dependentsSnapshot)
                    {
                        dependent->relinkDataBind();
                    }
                    rebindDependents();
                    if (previousViewModelInstance)
                    {
                        previousViewModelInstance->rebindProperties();
                    }
                    return true;
                }
                break;
            }
        }
    }
    return false;
}

bool ViewModelInstance::replaceViewModelByProperty(
    ViewModelInstanceViewModel* property,
    rcp<ViewModelInstance> value)
{
    for (auto& propertyValue : m_PropertyValues)
    {
        if (propertyValue.get() == property)
        {
            auto previousViewModelInstance =
                propertyValue->as<ViewModelInstanceViewModel>()
                    ->referenceViewModelInstance();
            propertyValue->as<ViewModelInstanceViewModel>()
                ->referenceViewModelInstance(value);
            // Invalidate value-level dependents (e.g. scripted property
            // wrappers) so cached references to the previous instance are
            // dropped. Multiple dependents can share this property. Snapshot
            // because relinkDataBind can mutate the dependents list.
            auto dependentsSnapshot = propertyValue->dependents();
            for (auto& dependent : dependentsSnapshot)
            {
                dependent->relinkDataBind();
            }
            rebindDependents();
            if (previousViewModelInstance)
            {
                previousViewModelInstance->rebindProperties();
            }
            return true;
        }
    }
    return false;
}

void ViewModelInstance::propertyValue(const SymbolType symbolType,
                                      ViewModelInstanceValue* value)
{
    if (symbolType != SymbolType::none)
    {
        m_propertySymbols[symbolType] = value;
    }
}

ViewModelInstanceValue* ViewModelInstance::propertyValue(
    const SymbolType symbolType)
{

    auto propertyIt = m_propertySymbols.find(symbolType);
    if (propertyIt != m_propertySymbols.end())
    {
        return propertyIt->second;
    }
    return nullptr;
}

ViewModelInstanceValue* ViewModelInstance::propertyValue(
    const std::string& name)
{
    for (auto value : m_PropertyValues)
    {
        if (value->viewModelProperty() &&
            value->viewModelProperty()->name() == name)
        {
            return value.get();
        }
    }
    return nullptr;
}

void ViewModelInstance::viewModel(ViewModel* value)
{
    if (m_ViewModel != nullptr)
    {
        m_ViewModel->unref();
    }
    value->ref();
    m_ViewModel = value;
}

ViewModel* ViewModelInstance::viewModel() const { return m_ViewModel; }

void ViewModelInstance::onComponentDirty(Component* component) {}

void ViewModelInstance::setAsRoot(rcp<ViewModelInstance> instance)
{
    setRoot(instance);
}

void ViewModelInstance::setRoot(rcp<ViewModelInstance> value)
{
    for (auto propertyValue : m_PropertyValues)
    {
        propertyValue->setRoot(value);
    }
}

const std::vector<rcp<ViewModelInstanceValue>>& ViewModelInstance::
    propertyValues()
{
    return m_PropertyValues;
}

Core* ViewModelInstance::clone() const
{
    auto cloned = new ViewModelInstance();
    cloned->copy(*this);

    // If we have an artboard, it means we will be in the artboard's object
    // list which will clone our property values for us
    if (artboard() == nullptr)
    {
        for (auto propertyValue : m_PropertyValues)
        {
            auto clonedValue =
                propertyValue->clone()->as<ViewModelInstanceValue>();
            cloned->addValue(clonedValue);
        }
    }
    cloned->viewModel(viewModel());
    return cloned;
}

StatusCode ViewModelInstance::import(ImportStack& importStack)
{
    auto backboardImporter =
        importStack.latest<BackboardImporter>(Backboard::typeKey);
    if (backboardImporter == nullptr)
    {
        return StatusCode::MissingObject;
    }

    backboardImporter->addViewModelInstance(this);

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

    // Only add ViewModelInstances at the File level if they are not
    // in the Component hierarchy.
    auto file = backboardImporter->file();
    if (file != nullptr)
    {
        file->addFileViewModelInstance(this);
    }

    return StatusCode::Ok;
}

ViewModelInstanceValue* ViewModelInstance::propertyFromPath(
    std::vector<uint32_t>* path,
    size_t index)
{
    if (index < path->size())
    {
        auto propertyId = (*path)[index];
        auto property = propertyValue(propertyId);
        if (property != nullptr)
        {
            if (index == path->size() - 1)
            {
                return property;
            }
            if (property->is<ViewModelInstanceViewModel>())
            {
                auto propertyViewModel =
                    property->as<ViewModelInstanceViewModel>();
                auto viewModelInstance =
                    propertyViewModel->referenceViewModelInstance();
                return viewModelInstance->propertyFromPath(path, index + 1);
            }
        }
    }
    return nullptr;
}

void ViewModelInstance::advanced()
{
    for (auto value : m_PropertyValues)
    {
        value->advanced();
    }
}

void ViewModelInstance::addParent(ViewModelInstance* parent)
{
    if (!parent)
    {
        return;
    }
    auto p = std::find(m_parents.begin(), m_parents.end(), parent);
    if (p == m_parents.end())
    {
        m_parents.push_back(parent);
    }
}

void ViewModelInstance::removeParent(ViewModelInstance* parent)
{
    m_parents.erase(std::remove(m_parents.begin(), m_parents.end(), parent),
                    m_parents.end());
}

void ViewModelInstance::addDependent(DataBindContainer* dependent)
{
    if (!dependent)
    {
        return;
    }
    auto p = std::find(m_dependents.begin(), m_dependents.end(), dependent);
    if (p == m_dependents.end())
    {
        m_dependents.push_back(dependent);
    }
}

void ViewModelInstance::removeDependent(DataBindContainer* dependent)
{
    m_dependents.erase(
        std::remove(m_dependents.begin(), m_dependents.end(), dependent),
        m_dependents.end());
}

void ViewModelInstance::rebindProperties()
{
    for (auto& property : m_PropertyValues)
    {
        auto dependents = property->dependents();
        for (auto& dependent : dependents)
        {
            dependent->relinkDataBind();
        }
        if (property->is<ViewModelInstanceViewModel>())
        {
            auto viewModelInstance = property->as<ViewModelInstanceViewModel>()
                                         ->referenceViewModelInstance();
            if (viewModelInstance)
            {
                viewModelInstance->rebindProperties();
            }
        }
    }
}

void ViewModelInstance::rebindDependents()
{
    for (auto& dependent : m_dependents)
    {
        dependent->relinkDataContext();
    }
    for (auto& parent : m_parents)
    {
        parent->rebindDependents();
    }
}
