#include "rive/math/hit_test.hpp"
#include "rive/shapes/image.hpp"
#include "rive/node.hpp"
#include "rive/layout/layout_node_style.hpp"
#include "rive/layout/layout_participant.hpp"
#include "rive/backboard.hpp"
#include "rive/importers/backboard_importer.hpp"
#include "rive/assets/file_asset.hpp"
#include "rive/assets/image_asset.hpp"
#include "rive/layout.hpp"
#include "rive/layout/n_slicer.hpp"
#include "rive/shapes/mesh_drawable.hpp"
#include "rive/artboard.hpp"
#include "rive/clip_result.hpp"
#include <cassert>

using namespace rive;

void Image::draw(Renderer* renderer)
{

  rive::ImageAsset* asset = this->imageAsset();

  rive::RenderImage* renderImage = asset->renderImage();
  if (renderImage == nullptr)
  {
    return;
  }
  if (needsSaveOperation())
  {

    renderer->save();
  }

  float width = (float)renderImage->width();
  float height = (float)renderImage->height();

  if (m_Mesh != nullptr)
  {
    m_Mesh->draw(
        renderer,
        renderImage,
        imageSampler(),
        blendMode(),
        renderOpacity(),
        additiveness());
  }
  else
  {
    renderer->transform(worldTransform());
    renderer->translate(-width * originX(), -height * originY());
    renderer->drawImage(
        renderImage,
        imageSampler(),
        blendMode(),
        renderOpacity(),
        additiveness());
  }
  if (needsSaveOperation())
  {
    renderer->restore();
  }
}

bool Image::willDraw()
{
  return Super::willDraw() && renderOpacity() != 0.0f &&
         this->imageAsset() != nullptr;
}

Core* Image::hitTest(HitInfo* hinfo, const Mat2D& xform)
{
  // TODO: handle clip?

  auto asset = imageAsset();
  auto renderImage = asset != nullptr ? asset->renderImage() : nullptr;
  if (renderImage == nullptr)
  {
    return nullptr;
  }
  float width = (float)renderImage->width();
  float height = (float)renderImage->height();

  if (m_Mesh)
  {
    printf("Missing mesh\n");
    // TODO: hittest mesh
  }
  else
  {
    auto mx = xform * worldTransform() *
              Mat2D::fromTranslate(-width * originX(), -height * originY());
    HitTester tester(hinfo->area);
    tester.addRect(AABB(0, 0, (float)width, (float)height), mx);
    if (tester.test())
    {
      return this;
    }
  }
  return nullptr;
}

bool Image::hitTestPoint(
    const Vec2D& position,
    bool skipOnUnclipped,
    bool isPrimaryHit)
{
  // Only the target tests its own geometry; as an ancestor the image just
  // passes the test up the tree.
  if (!isPrimaryHit)
  {
    return Drawable::hitTestPoint(position, skipOnUnclipped, isPrimaryHit);
  }
  // Hit what draw() draws: nothing until the asset has a decoded image.
  // Opacity is ignored, as it is for shapes, so a transparent image can
  // still be a hit area.
  ImageAsset* asset = imageAsset();
  if (asset == nullptr || asset->renderImage() == nullptr)
  {
    return false;
  }
  if (m_Mesh != nullptr)
  {
    if (!m_Mesh->hitTest(position))
    {
      return false;
    }
  }
  else
  {
    Mat2D inverseWorld;
    if (!worldTransform().invert(&inverseWorld) ||
        !localBounds().contains(inverseWorld * position))
    {
      return false;
    }
  }
  // Geometry hit, now check hidden state and clipping ancestors.
  return Drawable::hitTestPoint(position, skipOnUnclipped, isPrimaryHit);
}

StatusCode Image::import(ImportStack& importStack)
{
  auto result = registerReferencer(importStack);
  if (result != StatusCode::Ok)
  {
    return result;
  }
  // Files exported before 7.2 overwrite scaleX/scaleY with the layout fit, so
  // any stored scale on a layout image was ignored. Keep that legacy behavior
  // for those files; newer files compose the fit as a separate scale so the
  // user scale stays editable/animatable.
  int major = importStack.majorVersion();
  int minor = importStack.minorVersion();
  m_layoutScaleSeparate = major > 7 || (major == 7 && minor >= 2);
  // See File::minorVersion.
  m_isPointerTarget = major > 7 || (major == 7 && minor >= 5);
  return Super::import(importStack);
}

// Question: thoughts on this? it looks a bit odd to me,
// maybe there's a trick i'm missing here .. (could also implement
// getAssetId...)
uint32_t Image::assetId() { return ImageBase::assetId(); }

void Image::setAsset(rcp<FileAsset> asset)
{
  if (asset != nullptr && asset->is<ImageAsset>())
  {
    FileAssetReferencer::setAsset(asset);

    // If we have a mesh and we're in the source artboard, let's initialize
    // the mesh buffers.
    if (m_Mesh != nullptr && !artboard()->isInstance())
    {
      m_Mesh->onAssetLoaded(imageAsset()->renderImage());
    }
    updateImageScale();
  }
}

void Image::assetUpdated()
{
  updateImageScale();
  markWorldTransformDirty();
#ifdef WITH_RIVE_LAYOUT
  // A new image can change the size layout measured, as Text's shape does,
  // so the layouts around it measure again: a participant's own slot, or a
  // hugging leaf layout that measures the image directly. Without this an
  // image measured before it decoded (a web runtime's async decode) keeps
  // a 0x0 slot.
  markLayoutNodeDirty();
#endif
#ifdef WITH_RIVE_EDITOR
  // Editor / coop path: the FileAsset's `renderImage` typically
  // arrives AFTER `Image::setAsset` has already run (bytes are
  // fetched asynchronously from the CDN and pushed in via a pump
  // command). `Mesh::onAssetLoaded` allocated its GPU buffers on
  // the first bind with `renderImage == nullptr` and wrote UVs
  // using an identity `uvTransform`; now that the RenderImage is
  // actually present (with a real `uvTransform`), re-run the
  // UV/buffer initialization so sampling lines up with the
  // decoded texture.
  //
  // Runtime `.riv` loads don't need this — the RenderImage is
  // present the moment `setAsset` binds, so the single call at
  // image.cpp:117 is enough.
  if (m_Mesh != nullptr && artboard() != nullptr && !artboard()->isInstance())
  {
    auto* ia = imageAsset();
    m_Mesh->onAssetLoaded(ia != nullptr ? ia->renderImage() : nullptr);
  }
#endif
}

Core* Image::clone() const
{
  Image* twin = ImageBase::clone()->as<Image>();
  twin->m_layoutScaleSeparate = m_layoutScaleSeparate;
  twin->m_isPointerTarget = m_isPointerTarget;
  if (m_fileAsset != nullptr)
  {
    twin->setAsset(m_fileAsset);
  }
  return twin;
}

Mat2D Image::meshHostUVTransform() const
{
  ImageAsset* asset = imageAsset();
  RenderImage* renderImage = asset != nullptr ? asset->renderImage() : nullptr;
  return renderImage != nullptr ? renderImage->uvTransform() : Mat2D();
}

void Image::setMesh(MeshDrawable* mesh)
{
  if (m_Mesh == mesh)
  {
    return;
  }
  m_Mesh = mesh;
  updateImageScale();
}

float Image::width() const
{
  rive::ImageAsset* asset = this->imageAsset();
  if (asset == nullptr)
  {
    return 0.0f;
  }

  rive::RenderImage* renderImage = asset->renderImage();
  if (renderImage == nullptr)
  {
    return asset->width();
  }
  return (float)renderImage->width();
}

float Image::height() const
{
  rive::ImageAsset* asset = this->imageAsset();
  if (asset == nullptr)
  {
    return 0.0f;
  }

  rive::RenderImage* renderImage = asset->renderImage();
  if (renderImage == nullptr)
  {
    return asset->height();
  }
  return (float)renderImage->height();
}

Vec2D Image::measureLayout(
    float width,
    LayoutMeasureMode widthMode,
    float height,
    LayoutMeasureMode heightMode)
{
  // Hug to the intrinsic image size. Only an `exactly` constraint overrides
  // the natural size — `atMost` is the available space and must NOT grow a
  // hugging image to fill it.
  float measuredWidth = widthMode == LayoutMeasureMode::exactly
                            ? width
                            : Image::width();
  float measuredHeight = heightMode == LayoutMeasureMode::exactly
                             ? height
                             : Image::height();
  return Vec2D(measuredWidth, measuredHeight);
}

void Image::controlSize(
    Vec2D size,
    LayoutScaleType widthScaleType,
    LayoutScaleType heightScaleType,
    LayoutDirection direction)
{
  // We store layout width/height because the image asset may not be available
  // yet (referenced images) and we have defer controlling its size
  if (m_layoutWidth != size.x || m_layoutHeight != size.y)
  {
    m_layoutWidth = size.x;
    m_layoutHeight = size.y;

    updateImageScale();
  }
}

Vec2D Image::layoutBaseTranslation(LayoutParticipant* participant) const
{
  assert(participant != nullptr);
  return Vec2D(participant->resolvedLeft(), participant->resolvedTop());
}

void Image::composeWorldTransform()
{
#ifdef WITH_RIVE_LAYOUT
  auto* participant = layoutParticipant();
  if (participant != nullptr && m_ParentTransformComponent != nullptr)
  {
    // Origin 0: the slot base is just the slot top-left (the image composes
    // its origin + fit separately in updateTransform).
    Mat2D base = Mat2D::fromTranslation(layoutBaseTranslation(participant));
    m_WorldTransform = m_ParentTransformComponent->worldTransform() * base *
                       m_Transform;
    return;
  }
#endif
  Super::composeWorldTransform();
}

void Image::updateConstraints()
{
#ifdef WITH_RIVE_LAYOUT
  auto* participant = layoutParticipant();
  if (participant != nullptr)
  {
    participant->applyLayoutConstraints();
  }
#endif
  Super::updateConstraints();
}

LayoutParticipant* Image::layoutParticipant() const
{
  for (auto* child : children())
  {
    if (child->is<LayoutParticipant>())
    {
      return child->as<LayoutParticipant>();
    }
  }
  return nullptr;
}

bool Image::isParticipatingInLayout() const
{
  return layoutParticipant() != nullptr;
}

void Image::updateTransform()
{
  Super::updateTransform();
  // Compose the layout fit scale on top of the user transform (innermost), so
  // the user's scaleX/scaleY (built by Super) remain free to be animated:
  //   M = T(offset) * UserLocal * S(fitScale)
  m_Transform.scaleByValues(m_layoutScaleX, m_layoutScaleY);
  m_Transform[4] += m_layoutOffsetX;
  m_Transform[5] += m_layoutOffsetY;
}

void Image::updateImageScale()
{
  if (imageAsset() == nullptr)
  {
    if (m_layoutOffsetX != 0.0f || m_layoutOffsetY != 0.0f)
    {
      m_layoutOffsetX = 0.0f;
      m_layoutOffsetY = 0.0f;
      markTransformDirty();
    }
    return;
  }

  float newOffsetX = 0.0f;
  float newOffsetY = 0.0f;
  auto renderImage = imageAsset()->renderImage();
  if (renderImage != nullptr && !std::isnan(m_layoutWidth) &&
      !std::isnan(m_layoutHeight))
  {
    float imgW = (float)renderImage->width();
    float imgH = (float)renderImage->height();
    float newScaleX, newScaleY;
    auto imageFit = static_cast<ImageFit>(fit());
    switch (imageFit)
    {
      case ImageFit::contain:
      {
        float s = std::fmin(m_layoutWidth / imgW, m_layoutHeight / imgH);
        newScaleX = newScaleY = s;
        break;
      }
      case ImageFit::cover:
      {
        float s = std::fmax(m_layoutWidth / imgW, m_layoutHeight / imgH);
        newScaleX = newScaleY = s;
        break;
      }
      case ImageFit::fitWidth:
        newScaleX = newScaleY = m_layoutWidth / imgW;
        break;
      case ImageFit::fitHeight:
        newScaleX = newScaleY = m_layoutHeight / imgH;
        break;
      case ImageFit::none:
        newScaleX = newScaleY = 1.0f;
        break;
      case ImageFit::scaleDown:
      {
        float s = std::fmin(m_layoutWidth / imgW, m_layoutHeight / imgH);
        s = s < 1.0f ? s : 1.0f;
        newScaleX = newScaleY = s;
        break;
      }
      case ImageFit::fill:
      case ImageFit::resize:
      default:
        newScaleX = m_layoutWidth / imgW;
        newScaleY = m_layoutHeight / imgH;
        break;
    }

    // Compatibility: for a legacy (controlSized) parent, resize does not
    // apply fit/alignment translation offsets (only scale). A participant
    // composes the origin-based offset for resize too, so the image fills
    // its slot positionally as well as in size.
    if (imageFit != ImageFit::resize || isParticipatingInLayout())
    {
      float boundsW = imgW;
      float boundsH = imgH;
      float boundsLeft = -imgW * originX();
      float boundsTop = -imgH * originY();
      if (m_Mesh != nullptr && m_Mesh->type() == MeshType::vertex)
      {
        // Keep fit behavior stable while editing vertex meshes.
        boundsLeft = -imgW * 0.5f;
        boundsTop = -imgH * 0.5f;
      }
      Alignment alignment(alignmentX(), alignmentY());
      float xAlign = (alignment.x() + 1.0f) * 0.5f;
      float yAlign = (alignment.y() + 1.0f) * 0.5f;
      float scaledLeft = boundsLeft * newScaleX;
      float scaledTop = boundsTop * newScaleY;
      float widthRemainder = m_layoutWidth - (boundsW * newScaleX);
      float heightRemainder = m_layoutHeight - (boundsH * newScaleY);
      newOffsetX = -scaledLeft + widthRemainder * xAlign;
      newOffsetY = -scaledTop + heightRemainder * yAlign;
    }

    if (m_layoutScaleSeparate)
    {
      if (newScaleX != m_layoutScaleX || newScaleY != m_layoutScaleY)
      {
        m_layoutScaleX = newScaleX;
        m_layoutScaleY = newScaleY;
        // Fit scale is composed in updateTransform(), so changing it
        // must mark the local transform dirty (not just the world
        // transform).
        markTransformDirty();
      }
    }
    else
    {
      // Legacy (pre-7.2): the fit overwrites the user scale.
      if (newScaleX != scaleX() || newScaleY != scaleY())
      {
        scaleX(newScaleX);
        scaleY(newScaleY);
      }
    }
  }
  if (newOffsetX != m_layoutOffsetX || newOffsetY != m_layoutOffsetY)
  {
    m_layoutOffsetX = newOffsetX;
    m_layoutOffsetY = newOffsetY;
    // Offset is applied in updateTransform(), so changing it must mark the
    // local transform dirty (not just world transform).
    markTransformDirty();
  }
}

AABB Image::localBounds() const
{
  if (imageAsset() == nullptr)
  {
    return AABB();
  }
  return AABB::fromLTWH(
      -width() * originX(),
      -height() * originY(),
      width(),
      height());
}

ImageAsset* Image::imageAsset() const { return (ImageAsset*)m_fileAsset.get(); }

ImageSampler Image::imageSampler() const
{
  // Clamp file values so the key stays inside the backends' sampler tables.
  auto filterValue = [](uint32_t value) {
    return value <= (uint32_t)ImageFilter::nearest
               ? static_cast<ImageFilter>(value)
               : ImageFilter::bilinear;
  };
  auto wrapValue = [](uint32_t value) {
    return value <= (uint32_t)ImageWrap::mirror ? static_cast<ImageWrap>(value)
                                                : ImageWrap::clamp;
  };
  ImageSampler sampler = ImageSampler::LinearClamp();
  if (ImageAsset* asset = imageAsset())
  {
    sampler.filter = filterValue(asset->samplerFilter());
    sampler.wrapX = wrapValue(asset->samplerWrapX());
    sampler.wrapY = wrapValue(asset->samplerWrapY());
  }
  // Node values are offset by one, zero means inherit from the asset.
  if (samplerFilter() != 0)
  {
    sampler.filter = filterValue(samplerFilter() - 1);
  }
  if (samplerWrapX() != 0)
  {
    sampler.wrapX = wrapValue(samplerWrapX() - 1);
  }
  if (samplerWrapY() != 0)
  {
    sampler.wrapY = wrapValue(samplerWrapY() - 1);
  }
  return sampler;
}

#ifdef TESTING
#include "rive/shapes/mesh.hpp"
Mesh* Image::mesh() const { return static_cast<Mesh*>(m_Mesh); };
#endif

BoundsFidelity Image::paintedWorldBounds(AABB* out)
{
  if (m_Mesh != nullptr)
  {
    // A mesh re-maps the image's corners onto arbitrary vertices, and an
    // NSlicer -- which shares this pointer -- stretches them per slice. The
    // image's own box says nothing about where the result lands.
    return BoundsFidelity::none;
  }
  return paintedBoundsFromLocal(localBounds(), worldTransform(), nullptr, out);
}
