<?php
/**
 * Copyright 2024 Adobe
 * All Rights Reserved.
 */
declare(strict_types=1);

namespace Magento\Catalog\Model\ResourceModel\Product;

use Exception;
use Magento\Catalog\Api\Data\ProductInterface;
use Magento\Framework\DB\Sql\Expression;
use Magento\Framework\EntityManager\MetadataPool;
use Magento\Store\Model\Store;

class MediaGalleryValue
{
    /**
     * @param Gallery $galleryResource
     * @param MetadataPool $metadataPool
     */
    public function __construct(
        private readonly Gallery $galleryResource,
        private readonly MetadataPool $metadataPool
    ) {
    }

    /**
     * Retrieve all gallery values for entity.
     *
     * @param int $entityId
     * @return array
     * @throws Exception
     */
    public function getAllByEntityId(int $entityId): array
    {
        $metadata = $this->metadataPool->getMetadata(ProductInterface::class);
        $connection = $this->galleryResource->getConnection();
        $select = $connection->select()
            ->from($this->galleryResource->getTable(Gallery::GALLERY_VALUE_TABLE))
            ->where($metadata->getLinkField() . ' = ?', $entityId);

        return $connection->fetchAll($select);
    }

    /**
     * Returns value IDs by entity ID and store ID.
     *
     * @param int $entityId
     * @param int $storeId
     * @return array
     */
    public function getAllByEntityIdAndStoreId(int $entityId, int $storeId): array
    {
        $metadata = $this->metadataPool->getMetadata(ProductInterface::class);
        $connection = $this->galleryResource->getConnection();
        $select = $connection->select()
            ->from($this->galleryResource->getTable(Gallery::GALLERY_VALUE_TABLE))
            ->where($metadata->getLinkField() . ' = ?', $entityId)
            ->where('store_id = ?', $storeId);

        return $connection->fetchAll($select);
    }

    /**
     * Create or update media gallery value record.
     *
     * @param array $data
     * @return void
     * @throws Exception
     */
    public function saveGalleryStoreValue(array $data): void
    {
        $metadata = $this->metadataPool->getMetadata(ProductInterface::class);
        $connection = $this->galleryResource->getConnection();
        $fields = $connection->describeTable($this->galleryResource->getTable(Gallery::GALLERY_VALUE_TABLE));
        if (isset($data['record_id'])) {
            $id = (int) $data['record_id'];
            $data = array_intersect_key($data, $fields);
            unset($data['record_id'], $data['value_id'], $data['store_id'], $data[$metadata->getLinkField()]);
            $connection->update(
                $this->galleryResource->getTable(Gallery::GALLERY_VALUE_TABLE),
                $data,
                [
                    'record_id = ?' => $id,
                ]
            );
        } else {
            if (isset($data['label'], $data['store_id'])
                && $data['label'] === ''
                && ((int)$data['store_id']) !== Store::DEFAULT_STORE_ID
            ) {
                /**
                 * Ensures empty label is saved as is in store level and not converted to NULL
                 * because NULL is treated as "use default value" in store scope.
                 * @see \Magento\Framework\DB\Adapter\AdapterInterface::prepareColumnValue
                 */
                $data['label'] = new Expression($connection->quote($data['label']));
            }
            $this->galleryResource->insertGalleryValueInStore($data);
        }
    }
}
