<?php
/**
 * @author 1902 Software
 * @copyright Copyright © 2023 1902 Software (https://1902software.com/magento/)
 * @package WriteTextAI_WriteTextAI
 */

namespace WriteTextAI\WriteTextAI\Model;

use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Store\Model\ScopeInterface;
use Magento\Store\Model\StoreManagerInterface;
use Magento\Catalog\Model\ResourceModel\Product as ProductResource;
use Magento\Catalog\Model\CategoryRepository;
use WriteTextAI\WriteTextAI\Model\NewRecordsFactory;
use WriteTextAI\WriteTextAI\Api\NewRecordsRepositoryInterface;
use WriteTextAI\WriteTextAI\Model\ApiManager;
use WriteTextAI\WriteTextAI\Helper\Store as StoreHelper;
use WriteTextAI\WriteTextAI\Model\OptionSource\Filter\Fields;
use WriteTextAI\WriteTextAI\Helper\Data as HelperData;
use Magento\Catalog\Model\ProductRepository;
use WriteTextAI\WriteTextAI\Model\Magento\Category as MagentoCategory;
use WriteTextAI\WriteTextAI\ViewModel\Premium;

class NewRecordsManager
{
    /**
     * @var ScopeConfigInterface
     */
    protected $scopeConfig;

    /**
     * @var Settings
     */
    protected $settings;

    /**
     * @var NewRecordsFactory
     */
    protected $newRecordsFactory;

    /**
     * @var NewRecordsRepositoryInterface
     */
    protected $newRecordsRepository;

    /**
     * @var ApiManager
     */
    protected $apiManager;

    /**
     * @var StoreHelper
     */
    protected $storeHelper;

    /**
     * @var HelperData
     */
    protected $helperData;

    /**
     * @var ProductRepository
     */
    protected $productRepository;

    /**
     * @var MagentoCategory
     */
    protected $magentoCategory;

    /**
     * @var Premium
     */
    protected $premium;

    /**
     * @var StoreManagerInterface
     */
    protected $storeManager;

    /**
     * @var ProductResource
     */
    protected $productResource;

    /**
     * @var CategoryRepository
     */
    protected $categoryRepository;

    /**
     * @param ScopeConfigInterface $scopeConfig
     * @param NewRecordsFactory $newRecordsFactory
     * @param NewRecordsRepositoryInterface $newRecordsRepository
     * @param ApiManager $apiManager
     * @param StoreHelper $storeHelper
     * @param HelperData $helperData
     * @param ProductRepository $productRepository
     * @param MagentoCategory $magentoCategory
     * @param Premium $premium
     * @param StoreManagerInterface $storeManager
     * @param ProductResource $productResource
     * @param CategoryRepository $categoryRepository
     */
    public function __construct(
        ScopeConfigInterface $scopeConfig,
        NewRecordsFactory $newRecordsFactory,
        NewRecordsRepositoryInterface $newRecordsRepository,
        ApiManager $apiManager,
        StoreHelper $storeHelper,
        HelperData $helperData,
        ProductRepository $productRepository,
        MagentoCategory $magentoCategory,
        Premium $premium,
        StoreManagerInterface $storeManager,
        ProductResource $productResource,
        CategoryRepository $categoryRepository
    ) {
        $this->scopeConfig = $scopeConfig;
        $this->newRecordsFactory = $newRecordsFactory;
        $this->newRecordsRepository = $newRecordsRepository;
        $this->apiManager = $apiManager;
        $this->storeHelper = $storeHelper;
        $this->helperData = $helperData;
        $this->productRepository = $productRepository;
        $this->magentoCategory = $magentoCategory;
        $this->premium = $premium;
        $this->storeManager = $storeManager;
        $this->productResource = $productResource;
        $this->categoryRepository = $categoryRepository;
    }

    /**
     * Check if product is enabled in at least one store
     *
     * @param int $productId
     * @return bool
     */
    private function isProductEnabledInAnyStore($productId)
    {
        try {
            $stores = $this->storeManager->getStores();
            foreach ($stores as $store) {
                $storeId = $store->getId();
                $product = $this->productRepository->getById($productId, false, $storeId);
                if ($product->getStatus() == \Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED) {
                    return true;
                }
            }
            return false;
        } catch (\Exception $e) {
            return false;
        }
    }

    /**
     * Check if category is active in at least one store
     *
     * @param int $categoryId
     * @return bool
     */
    private function isCategoryActiveInAnyStore($categoryId)
    {
        try {
            $stores = $this->storeManager->getStores();
            foreach ($stores as $store) {
                $storeId = $store->getId();
                $category = $this->categoryRepository->get($categoryId, $storeId);
                if ($category->getIsActive() == 1) {
                    return true;
                }
            }
            return false;
        } catch (\Exception $e) {
            return false;
        }
    }

    /**
     * Send new records to the API
     *
     * @param string $entityType
     * @return array
     */
    public function sendNewRecords($entityType)
    {
        try {
            if (!$this->premium->getHasProAccess()) {
                return [];
            }
            //$defaultCutoffDate = $this->scopeConfig->getValue('writetextai_settings/new_records/cutoff_date');
            $currDateTime = (new \DateTime())->format(\Magento\Framework\Stdlib\DateTime::DATETIME_PHP_FORMAT);
            $oneWeekAgo = (new \DateTime())
                ->modify('-1 week')
                ->setTime(0, 0, 0)
                ->format(\Magento\Framework\Stdlib\DateTime::DATETIME_PHP_FORMAT);
            $newRecords = $this->newRecordsFactory->create();

            $collection = $newRecords->getCollection()
                ->addFieldToFilter('entity_type', $entityType)
                ->addFieldToFilter('email_sent', 0);
                // ->addFieldToFilter('created_at', ['gteq' => $oneWeekAgo])
                // ->addFieldToFilter('created_at', ['lteq' => $currDateTime]);

            $records = [];
            $items = $collection->getItems();
            $disabledRecords = [];
            foreach ($items as $item) {
                if ($entityType === 'Product') {
                    if (!$this->isProductEnabledInAnyStore($item->getRecordId())) {
                        $disabledRecords[] = $item->getRecordId();
                        continue;
                    }
                    $records[] = [
                        "id" => $item->getRecordId(),
                        "sku" => $item->getSku()
                    ];
                } elseif ($entityType === 'Category') {
                    if (!$this->isCategoryActiveInAnyStore($item->getRecordId())) {
                        $disabledRecords[] = $item->getRecordId();
                        continue;
                    }
                    $records[] = [
                        "id" => $item->getRecordId()
                    ];
                } else {
                    continue;
                }
            }

            if (empty($records)) {
                return [];
            }

            $fields = [];
            if ($entityType == 'Product') {
                $mappingSettings = $this->helperData->getMappingSettings();
                $fields = [
                    Fields::PAGE_TITLE,
                    Fields::PAGE_DESCRIPTION,
                    Fields::PRODUCT_DESCRIPTION,
                    Fields::EXCERPT
                ];
                if (isset($mappingSettings['open_graph'])) {
                    $fields[] = Fields::OPEN_GRAPH;
                }
            } else {
                $fields = [
                    Fields::CATEGORY_PAGE_TITLE,
                    Fields::CATEGORY_PAGE_DESCRIPTION,
                    Fields::CATEGORY_DESCRIPTION
                ];
            }
            $storeId = (string) \Magento\Store\Model\Store::DEFAULT_STORE_ID;
            $dataToSend = [
                "type" => $entityType,
                "storeId" => $storeId,
                "language" => $this->storeHelper->getFormattedLanguage($storeId),
                "records" => $records,
                "fields" => $fields
            ];

            $response = $this->apiManager->reportNewRecords($dataToSend);
            if (isset($response['newRecords'])) {
                $itemIds = [];
                foreach ($items as $item) {
                    if (in_array($item->getRecordId(), $disabledRecords)) {
                        continue;
                    }
                    $itemIds[] = $item->getId();
                }
                
                if (!empty($itemIds)) {
                    $collection->getConnection()
                        ->update(
                            $collection->getMainTable(),
                            ['email_sent' => 1, 'updated_at' => $currDateTime],
                            ['id IN (?)' => $itemIds]
                        );
                }
            }
            return $records;
        } catch (\Exception $e) {
            return [];
        }
    }

    /**
     * Trigger email sending for new products
     */
    public function sendEmail()
    {
        try {
            $response = $this->apiManager->emailNewProducts();
            return true;
        } catch (\Exception $e) {
            return false;
        }
    }

    /**
     * Save new records to the database
     *
     * @param int $recordId
     * @param string $entityType
     * @param string|null $sku
     * @return void
     */
    public function saveNewRecords($recordId, $entityType, $sku = null)
    {
        $currDateTime = (new \DateTime())->format(\Magento\Framework\Stdlib\DateTime::DATETIME_PHP_FORMAT);
        $newRecords = $this->newRecordsFactory->create();

        $existing = $newRecords->getCollection()
            ->addFieldToFilter('record_id', $recordId)
            ->addFieldToFilter('entity_type', $entityType)
            ->getFirstItem();

        if ($existing->getId()) {
            // Update the existing record
            $existing->setRecordId($recordId);
            $existing->setEntityType($entityType);
            $existing->setUpdatedAt($currDateTime);
            if ($sku) {
                $existing->setSku($sku);
            }
            $newRecords = $existing;
        } else {
            // Record not found, create a new one
            $data = [
                'record_id' => $recordId,
                'entity_type' => $entityType,
                'created_at' => $currDateTime,
                'updated_at' => $currDateTime
            ];
            if ($sku) {
                $data['sku'] = $sku;
            }
            $newRecords->setData($data);
        }

        $this->newRecordsRepository->save($newRecords);
    }

    /**
     * Delete records from the database
     *
     * @param int $recordId
     * @param string $entityType
     * @return void
     */
    public function deleteRecord($recordId, $entityType)
    {
        try {
            $newRecords = $this->newRecordsFactory->create();
            $collection = $newRecords->getCollection()
                ->addFieldToFilter('record_id', $recordId)
                ->addFieldToFilter('entity_type', $entityType);

            foreach ($collection as $record) {
                $this->newRecordsRepository->delete($record);
            }
        } catch (\Exception $e) {
            // Do nothing
            return;
        }
    }
}
