<?php

namespace FiloBlu\ActiveCampaign\Helper;

use Exception;
use FiloBlu\ConsentsManager\Model\ConsentSubscriptionRepository;
use FiloBlu\ConsentsManager\Model\ConsentTypeRepository;
use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\Framework\App\Config\Storage\WriterInterface;
use Magento\Framework\App\Helper\AbstractHelper;
use Magento\Framework\App\Helper\Context;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Framework\Module\Manager;
use Magento\Framework\ObjectManagerInterface;
use Magento\Framework\UrlInterface;
use Magento\Sales\Model\ResourceModel\Order\CollectionFactory as OrderCollectionFactory;
use Magento\SalesRule\Api\Data\CouponInterface;
use Magento\Store\Model\ScopeInterface;
use Magento\Store\Model\StoreManagerInterface;
use Magento\Framework\App\ObjectManager;
use Magento\Catalog\Model\Product;
use Magento\Framework\Exception\LocalizedException;

/**
 * Class Data
 * @package FiloBlu\ActiveCampaign\Helper
 */
class Data extends AbstractHelper
{

    //GENERAL
    const FB_ACTIVECAMPAIGN_GENERAL_ENABLE = 'fb_activecampaign_general/general/enable';
    const FB_ACTIVECAMPAIGN_ENABLED_STORE_VIEWS = 'fb_activecampaign_general/general/enabled_store_views';
    const FB_ACTIVECAMPAIGN_GENERAL_REMOVE_PUB = 'fb_activecampaign_general/general/remove_pub';
    //OBSERVERS
    const FB_ACTIVECAMPAIGN_OBSERVER_ENABLE = 'fb_activecampaign_general/observers/enable';
    const FB_ACTIVECAMPAIGN_OBSERVER_SUBSCRIPTION_CHANGE = 'fb_activecampaign_general/observers/enable_subscription_change';
    const FB_ACTIVECAMPAIGN_OBSERVER_CUSTOMER_CHANGE = 'fb_activecampaign_general/observers/enable_customer_change';
    //REST
    const FB_ACTIVECAMPAIGN_REST_ENABLE = 'fb_activecampaign_general/rest/enable';
    const FB_ACTIVECAMPAIGN_REST_BASE_URL = 'fb_activecampaign_general/rest/base_url';
    const FB_ACTIVECAMPAIGN_REST_TOKEN = 'fb_activecampaign_general/rest/token';
    const FB_ACTIVECAMPAIGN_REST_WEBHOOK_CODE = 'fb_activecampaign_general/rest/webhook_code';
    const FB_ACTIVECAMPAIGN_REST_UNSUBSCRIBE_WEBHOOK_ENABLED = 'fb_activecampaign_general/rest/enable_unsubscriber_webhook';
    //GENDER
    const FB_ACTIVECAMPAIGN_CUSTOMER_MAPPING_GENDER = 'fb_activecampaign_customer/mapping/gender';
    //SUBSCRIBER
    const FB_ACTIVECAMPAIGN_CUSTOMER_MAPPING_SUBSCRIBER = 'fb_activecampaign_customer/mapping/subscriber';
    //ITEMS
    const FB_ACTIVECAMPAIGN_SALES_MAPPING_ITEMS = 'fb_activecampaign_sales/mapping/items';
    //CUSTOMER
    const FB_ACTIVECAMPAIGN_CUSTOMER_ENABLE = 'fb_activecampaign_customer/customer/enable';
    const FB_ACTIVECAMPAIGN_CUSTOMER_MAPPING_CUSTOMER = 'fb_activecampaign_customer/mapping/customer';
    const FB_ACTIVECAMPAIGN_CUSTOMER_MAPPING_BILLING = 'fb_activecampaign_customer/mapping/customer_billing_address';
    const FB_ACTIVECAMPAIGN_CUSTOMER_MAPPING_SHIPPING = 'fb_activecampaign_customer/mapping/customer_shipping_address';
    // BIRTHDAY COUPON
    const FB_ACTIVECAMPAIGN_BIRTHDAY_COUPON_ENABLE = 'fb_activecampaign_customer/birthday_coupon/enable';
    const FB_ACTIVECAMPAIGN_BIRTHDAY_COUPON_MAPPING_PREFIX ='fb_activecampaign_customer/birthday_coupon/mapping_';
    //QUOTE
    const FB_ACTIVECAMPAIGN_SALES_QUOTE_ENABLE = 'fb_activecampaign_sales/quote/enable';
    const FB_ACTIVECAMPAIGN_SALES_QUOTE_EXPORT_ONLY_SIMPLE = 'fb_activecampaign_sales/quote/export_only_simple';
    const FB_ACTIVECAMPAIGN_SALES_QUOTE_ABANDONED_CART_TIME = 'fb_activecampaign_sales/quote/abandoned_cart_time';
    //ORDER
    const FB_ACTIVECAMPAIGN_SALES_ORDER_ENABLE = 'fb_activecampaign_sales/order/enable';
    const FB_ACTIVECAMPAIGN_SALES_ORDER_EXPORT_ONLY_SIMPLE = 'fb_activecampaign_sales/order/export_only_simple';
    const FB_ACTIVECAMPAIGN_SALES_ORDER_STATUSES = 'fb_activecampaign_sales/order/order_statuses_to_export';
    //LIST
    const FB_ACTIVECAMPAIGN_LIST_CUSTOMER = 'fb_activecampaign_general/lists/customer';
    const FB_ACTIVECAMPAIGN_LIST_CUSTOMER_ENABLED = 'fb_activecampaign_general/lists/customer_list_enabled';
    const FB_ACTIVECAMPAIGN_LIST_SUBSCRIBER = 'fb_activecampaign_general/lists/subscriber';
    const FB_ACTIVECAMPAIGN_PROFILES_LIST_SUBSCRIBER = 'fb_activecampaign_general/lists/profiles_list';
    //CONNECTION
    const FB_ACTIVECAMPAIGN_CONNECTION_ID = 'fb_activecampaign_general/connection/id';
    const FB_ACTIVECAMPAIGN_CONNECTION_NAME = 'fb_activecampaign_general/connection/name';
    const FB_ACTIVECAMPAIGN_CONNECTION_EXTERNAL_ID = 'fb_activecampaign_general/connection/external_id';
    const FB_ACTIVECAMPAIGN_CONNECTION_URL = 'fb_activecampaign_general/connection/url';
    const FB_ACTIVECAMPAIGN_CONNECTION_LOGO = 'fb_activecampaign_general/connection/logo';
    //MODULE
    const FB_ACTIVECAMPAIGN_NEWSLETTER_MODULE = 'FiloBlu_Newsletter';
    const FB_ACTIVECAMPAIGN_REFILO_MODULE = 'FiloBlu_Refilo';

    // BIRTHDAY COUPON CONFIG PREFIXES
    const COUPON_ENABLED = 'enabled_';
    const COUPON_STORE_FIELD = 'store_field_';
    const COUPON_COUPON_FIELD = 'coupon_field_';
    const COUPON_DOB_FIELD = 'dob_field_';
    const COUPON_LIST_ID = 'list_id_';

    /**
     * @var array
     */
    protected $contactTypeMapping, $birthdayCouponTypeEnabled, $storeFieldId, $couponFieldId, $subscriberFieldId, $monthDayFieldId, $happyBirthdayListId;
    /**
     * @var SerializerHelper
     */
    public $serializer;
    /**
     * @var WriterInterface
     */
    protected $configWriter;
    /**
     * @var StoreManagerInterface
     */
    protected $storeManager;
    /**
     * @var ObjectManagerInterface
     */
    protected $objectManager;
    /**
     * @var null|mixed
     */
    protected $refiloHelperData = null;
    /**
     * @var ProductRepositoryInterface
     */
    protected $productRepository;
    /**
     * @var Manager
     */
    private $moduleManager;
    /**
     * @var ConsentSubscriptionRepository
     */
    private $consentSubscriptionRepository;
    /**
     * @var ConsentTypeRepository
     */
    private $consentTypeRepository;
    /**
     * @var OrderCollectionFactory
     */
    private $orderCollectionFactory;
    /**
     * @var Context
     */
    private $context;

    /**
     * Data constructor.
     * @param Context $context
     * @param WriterInterface $configWriter
     * @param StoreManagerInterface $storeManager
     * @param ObjectManagerInterface $objectManager
     * @param ProductRepositoryInterface $productRepository
     * @param SerializerHelper $serializer
     * @param ConsentSubscriptionRepository $consentSubscriptionRepository
     * @param ConsentTypeRepository $consentTypeRepository
     */
    public function __construct(
        Context $context,
        WriterInterface $configWriter,
        StoreManagerInterface $storeManager,
        ObjectManagerInterface $objectManager,
        ProductRepositoryInterface $productRepository,
        SerializerHelper $serializer,
        ConsentSubscriptionRepository $consentSubscriptionRepository,
        ConsentTypeRepository $consentTypeRepository,
        OrderCollectionFactory $orderCollectionFactory
    )
    {
        parent::__construct($context);
        $this->configWriter = $configWriter;
        $this->moduleManager = $context->getModuleManager();
        $this->storeManager = $storeManager;
        $this->objectManager = $objectManager;
        $this->productRepository = $productRepository;
        $this->serializer = $serializer;
        $this->consentSubscriptionRepository = $consentSubscriptionRepository;
        $this->consentTypeRepository = $consentTypeRepository;
        $this->orderCollectionFactory = $orderCollectionFactory;
        $this->context = $context;
    }

    /**
     * @return bool
     */
    public function isEnabled(): bool
    {
        return $this->scopeConfig->isSetFlag(self::FB_ACTIVECAMPAIGN_GENERAL_ENABLE);
    }

    /**
     * @return string
     */
    public function getEnabledStoreViews(): string
    {
        return $this->scopeConfig->getValue(self::FB_ACTIVECAMPAIGN_ENABLED_STORE_VIEWS) ?? '';
    }

    /**
     * @return bool
     */
    public function isObserverEnabled(): bool
    {
        return $this->scopeConfig->isSetFlag(self::FB_ACTIVECAMPAIGN_OBSERVER_ENABLE);
    }

    /**
     * @return bool
     */
    public function isCustomerSaveObserverEnabled(): bool
    {
        return $this->scopeConfig->isSetFlag(self::FB_ACTIVECAMPAIGN_OBSERVER_CUSTOMER_CHANGE);
    }

    /**
     * @return bool
     */
    public function isSubscriptionChangeObserverEnabled(): bool {
        return $this->scopeConfig->isSetFlag(self::FB_ACTIVECAMPAIGN_OBSERVER_SUBSCRIPTION_CHANGE);
    }

    /**
     * @return bool
     */
    public function isRestEnabled(): bool {
        return $this->scopeConfig->isSetFlag(self::FB_ACTIVECAMPAIGN_REST_ENABLE);
    }

    /**
     * @return mixed
     */
    public function getRestBaseUrl() {
        return $this->scopeConfig->getValue(self::FB_ACTIVECAMPAIGN_REST_BASE_URL);
    }

    /**
     * @return mixed
     */
    public function getRestToken() {
        return $this->scopeConfig->getValue(self::FB_ACTIVECAMPAIGN_REST_TOKEN);
    }

    /**
     * @return bool
     */
    public function isQuoteEnabled(): bool
    {
        return $this->scopeConfig->isSetFlag(self::FB_ACTIVECAMPAIGN_SALES_QUOTE_ENABLE);
    }

    /**
     * @return bool
     */
    public function quoteExportOnlySimple(): bool
    {
        return $this->scopeConfig->isSetFlag(self::FB_ACTIVECAMPAIGN_SALES_QUOTE_EXPORT_ONLY_SIMPLE);
    }

    /**
     * @return mixed
     */
    public function getAbandonedCartTime() {
        return $this->scopeConfig->getValue(self::FB_ACTIVECAMPAIGN_SALES_QUOTE_ABANDONED_CART_TIME);
    }

    /**
     * @return bool
     */
    public function isOrderEnabled(): bool
    {
        return $this->scopeConfig->isSetFlag(self::FB_ACTIVECAMPAIGN_SALES_ORDER_ENABLE);
    }

    /**
     * @return bool
     */
    public function isCustomerListEnabled(): bool
    {
        return $this->scopeConfig->isSetFlag(self::FB_ACTIVECAMPAIGN_LIST_CUSTOMER_ENABLED);
    }

    /**
     * @return bool
     */
    public function orderExportOnlySimple(): bool
    {
        return $this->scopeConfig->isSetFlag(self::FB_ACTIVECAMPAIGN_SALES_ORDER_EXPORT_ONLY_SIMPLE);
    }

    /**
     * @return mixed
     */
    public function getOrderStatuses() {
        return $this->scopeConfig->getValue(self::FB_ACTIVECAMPAIGN_SALES_ORDER_STATUSES);
    }

    /**
     * @return bool
     */
    public function isCustomerEnabled(): bool
    {
        return $this->scopeConfig->isSetFlag(self::FB_ACTIVECAMPAIGN_CUSTOMER_ENABLE);
    }

    /**
     * @return mixed
     */
    public function getGenderMapping(): array
    {
        return $this->getSerializedValue($this->scopeConfig->getValue(self::FB_ACTIVECAMPAIGN_CUSTOMER_MAPPING_GENDER),'gender');
    }

    /**
     * @return mixed
     */
    public function getCustomerMapping(): array
    {
        return $this->getSerializedValue($this->scopeConfig->getValue(self::FB_ACTIVECAMPAIGN_CUSTOMER_MAPPING_CUSTOMER), 'customer');
    }

    /**
     * @return mixed
     */
    public function getCustomerBillingAddressMapping(): array
    {
        return $this->getSerializedValue($this->scopeConfig->getValue(self::FB_ACTIVECAMPAIGN_CUSTOMER_MAPPING_BILLING), 'customer_billing_address');
    }

    /**
     * @return mixed
     */
    public function getCustomerShippingAddressMapping(): array
    {
        return $this->getSerializedValue($this->scopeConfig->getValue(self::FB_ACTIVECAMPAIGN_CUSTOMER_MAPPING_SHIPPING), 'customer_shipping_address');
    }

    /**
     * @return mixed
     */
    public function getSubscriberMapping(): array
    {
        return $this->getSerializedValue($this->scopeConfig->getValue(self::FB_ACTIVECAMPAIGN_CUSTOMER_MAPPING_SUBSCRIBER), 'subscriber');
    }

    /**
     * @param $value
     * @return array
     */
    protected function getSerializedValue($value,$entity): array
    {
        $map = [];
        if(empty($value)){
            return $map;
        }

        if (interface_exists(\Magento\Framework\Serialize\SerializerInterface::class)) {
            $datas = $this->unserialize($value);
        } else {
            $datas = unserialize($value);
        }

        foreach ($datas as $data) {
            $map[$data[$entity.'_magento_field']] = $data[$entity.'_activecampaign_field'];
        }
        return $map;
    }

    /**
     * @param $value
     * @return bool
     */
    public function isAdditional($value): bool
    {
        $val = substr($value,0,1);
        return $val === '_';
    }

    /**
     * @param $value
     * @return string
     */
    public function snakeToCamelCase($value): string
    {
        return ucfirst(str_replace(' ', '', ucwords(str_replace('_', ' ', strtolower($value)))));
    }

    /**
     * @param array $conditions
     * @return string
     */
    public function arrayToWhereString(array $conditions): string
    {
        $whereArray = [];
        $where = '';
        if(count($conditions)==0){
            return $where;
        }
        foreach ($conditions as $key => $val) {
            $whereArray[] = $key." = '".$val."'";
        }
        $where = implode(' AND ',$whereArray);
        return $where;
    }

    /**
     * @param $id
     */
    public function writeConnectionId($id) {
        $this->configWriter->save(self::FB_ACTIVECAMPAIGN_CONNECTION_ID,$id);
    }

    /**
     * @return mixed
     */
    public function getConnectionId() {
        return $this->scopeConfig->getValue(self::FB_ACTIVECAMPAIGN_CONNECTION_ID);
    }

    /**
     * @return mixed
     */
    public function getConnectionName() {
        return $this->scopeConfig->getValue(self::FB_ACTIVECAMPAIGN_CONNECTION_NAME);
    }

    /**
     * @return mixed
     */
    public function getConnectionExternalId() {
        return $this->scopeConfig->getValue(self::FB_ACTIVECAMPAIGN_CONNECTION_EXTERNAL_ID);
    }

    /**
     * @return mixed
     */
    public function getConnectionUrl() {
        return $this->scopeConfig->getValue(self::FB_ACTIVECAMPAIGN_CONNECTION_URL);
    }

    /**
     * @return mixed
     */
    public function getConnectionLogo() {
        return $this->scopeConfig->getValue(self::FB_ACTIVECAMPAIGN_CONNECTION_LOGO);
    }

    /**
     * @return mixed
     */
    public function getCustomerList() {
        return $this->scopeConfig->getValue(self::FB_ACTIVECAMPAIGN_LIST_CUSTOMER);
    }

    /**
     * @return mixed
     */
    public function getSubscriberList() {
        return $this->scopeConfig->getValue(self::FB_ACTIVECAMPAIGN_LIST_SUBSCRIBER);
    }

    /**
     * @return bool
     */
    public function isNewsletterExtensionEnabled(): bool
    {
        return $this->moduleManager->isEnabled(self::FB_ACTIVECAMPAIGN_NEWSLETTER_MODULE);
    }

    /**
     * @param $price
     * @return float|int
     */
    public function formatPrice($price){
        return (float)$price * 100;
    }

    /**
     * @return bool
     */
    public function removePub(): bool
    {
        return $this->scopeConfig->isSetFlag(self::FB_ACTIVECAMPAIGN_GENERAL_REMOVE_PUB);
    }

    /**
     * @param $storeId
     * @return string
     * @throws NoSuchEntityException
     */
    public function getMediaUrl($storeId) {
        $store = $this->storeManager->getStore($storeId);
        $storeUrl = $store->getBaseUrl(UrlInterface::URL_TYPE_MEDIA);
        if($this->removePub()) {
            $storeUrl = str_replace('/pub/','/',$storeUrl);
        }
        return $storeUrl;
    }

    /**
     * @return bool
     */
    public function isUnsubscriberWebhookEnabled() {
        return $this->scopeConfig->isSetFlag(self::FB_ACTIVECAMPAIGN_REST_UNSUBSCRIBE_WEBHOOK_ENABLED);
    }

    /**
     * @param $code
     * @return bool
     */
    public function checkWebhookCode($code) {
        $webhook_code = $this->scopeConfig->getValue(self::FB_ACTIVECAMPAIGN_REST_WEBHOOK_CODE);
        if($webhook_code!=$code){
            return false;
        }
        return true;
    }

    /**
     * @param $date
     * @return false|string
     */
    public function getACDatetimeFormat($date) {
        return date('c',strtotime($date));
    }

    /**
     * @return bool
     */
    public function isRefiloExtensionEnabled() {
        return $this->moduleManager->isEnabled(self::FB_ACTIVECAMPAIGN_REFILO_MODULE);
    }

    /**
     * @param $product
     */
    public function getProductUrl($product,$store_id) {
        if($this->isRefiloExtensionEnabled()) {
            $helper = $this->getRefiloHelperData();
            if(method_exists($helper,'getProductStorefrontUrl')){
                return $helper->getProductStorefrontUrl($product,$store_id);
            }
        }
        return $product->getProductUrl();
    }

    /**
     * @return mixed|null
     */
    protected function getRefiloHelperData() {
        if(empty($this->refiloHelperData)){
            $this->refiloHelperData = $this->objectManager->create('FiloBlu\Refilo\Helper\Data');
        }
        return $this->refiloHelperData;
    }

    /**
     * @param $productId
     */
    public function getProduct($productId) {
        return $this->productRepository->getById($productId);
    }

    /**
     * @param $data
     * @return string
     */
    public function serialize($data)
    {
        return $this->serializer->serialize($data);
    }

    /**
     * @param $data
     * @return mixed
     */
    private function unserialize($data)
    {
        return $this->serializer->unserialize($data);
    }

    /**
     * @return mixed
     */
    public function getItemsExtraAttributesMapping(): array
    {
        return $this->getSerializedValue($this->scopeConfig->getValue(self::FB_ACTIVECAMPAIGN_SALES_MAPPING_ITEMS), 'item');
    }

    /**
     * @param Product $product
     * @param string $eavField
     * @return string
     */
    public function getEavAttribute(Product $product, string $eavField): string
    {
        try {
            if ($product->getId()) {
                if ($optionId = $product->getData($eavField)) {
                    $value = $product->getResource()->getAttribute($eavField)->getSource()->getOptionText($optionId);
                }
            }
        } catch (LocalizedException $e) {
        }

        return $value ?? '';
    }

    /**
     * @param $product
     * @return string
     */
    public function getCategory($product): string
    {
        if (!empty($cl1 = $this->getEavAttribute($product, 'category_level_1'))) {
            return $cl1;
        }

        $collection = $product->getCategoryCollection()->addAttributeToSelect('name');

        return $collection->getFirstItem()->getName() ?? '';
    }

    /**
     * @param string $type
     * @param int $storeId
     * @return bool
     */
    public function isBirthdayCouponSendingEnabled(string $type, int $storeId = 0): bool
    {
        if (!isset($this->birthdayCouponEnabled[$type][$storeId])) {
            $this->birthdayCouponEnabled[$type][$storeId] = $this->scopeConfig->isSetFlag(
                self::FB_ACTIVECAMPAIGN_BIRTHDAY_COUPON_ENABLE,
                ScopeInterface::SCOPE_STORE,
                $storeId
            ) ?? false;

            if ($this->birthdayCouponEnabled[$type][$storeId]) {
                $this->birthdayCouponEnabled[$type][$storeId] = $this->isTypeEnabled($type, $storeId);
            }
        }

        return $this->birthdayCouponEnabled[$type][$storeId];
    }

    /**
     * @param string $type
     * @param int $storeId
     * @return mixed
     */
    public function getContactTypeMapping(string $type, int $storeId = 0)
    {
        if (!isset($this->contactTypeMapping[$type][$storeId])) {
            $serializedMapping = $this->scopeConfig->getValue(
                self::FB_ACTIVECAMPAIGN_BIRTHDAY_COUPON_MAPPING_PREFIX . $type ,
                ScopeInterface::SCOPE_STORE,
                $storeId
            ) ?? [];
            $mapping = $this->serializer->unserialize($serializedMapping);
            $this->contactTypeMapping[$type][$storeId] = array_shift($mapping);
        }

        return $this->contactTypeMapping[$type][$storeId];
    }

    /**
     * @param string $type
     * @param int $storeId
     * @return bool
     */
    public function isTypeEnabled(string $type, int $storeId = 0)
    {
        if (!isset($this->birthdayCouponTypeEnabled[$type][$storeId])) {
            $this->contactTypeMapping[$type][$storeId] = $this->getContactTypeMapping($type, $storeId);
            $this->birthdayCouponTypeEnabled[$type][$storeId] =
                (bool) $this->contactTypeMapping[$type][$storeId][self::COUPON_ENABLED . $type] ?? false;
        }

        return $this->birthdayCouponTypeEnabled[$type][$storeId];
    }

    /**
     * @param int $storeId
     * @param string $type
     * @return int
     */
    public function getStoreFieldId(string $type, int $storeId = 0)
    {
        if (!isset($this->storeFieldId[$type][$storeId])) {
            $this->contactTypeMapping[$type][$storeId] = $this->getContactTypeMapping($type, $storeId);
            $this->storeFieldId[$type][$storeId] =
                (int) $this->contactTypeMapping[$type][$storeId][self::COUPON_STORE_FIELD . $type] ?? 0;

        }

        return $this->storeFieldId[$type][$storeId];
    }

    /**
     * @param string $type
     * @param int $storeId
     * @return int
     */
    public function getCouponFieldId(string $type, int $storeId = 0)
    {
        if (!isset($this->couponFieldId[$storeId])) {
            $this->contactTypeMapping[$type][$storeId] = $this->getContactTypeMapping($type, $storeId);
            $this->couponFieldId[$type][$storeId] =
                (int) $this->contactTypeMapping[$type][$storeId][self::COUPON_COUPON_FIELD . $type] ?? 0;
        }

        return $this->couponFieldId[$type][$storeId];
    }

    /**
     * @param string $type
     * @param int $storeId
     * @return int
     */
    public function getMonthDayField(string $type, int $storeId = 0): int
    {
        if (!isset($this->monthDayFieldId[$storeId])) {
            $this->contactTypeMapping[$type][$storeId] = $this->getContactTypeMapping($type, $storeId);
            $this->monthDayFieldId[$type][$storeId] =
                (int) $this->contactTypeMapping[$type][$storeId][self::COUPON_DOB_FIELD . $type] ?? 0;
        }

        return $this->monthDayFieldId[$type][$storeId];
    }

    /**
     * @param string $type
     * @param int $storeId
     * @return int
     */
    public function getHappyBirthdayListId(string $type, int $storeId = 0): int
    {
        if (!isset($this->happyBirthdayListId[$storeId])) {
            $this->contactTypeMapping[$type][$storeId] = $this->getContactTypeMapping($type, $storeId);
            $this->happyBirthdayListId[$type][$storeId] =
                (int) $this->contactTypeMapping[$type][$storeId][self::COUPON_LIST_ID . $type] ?? 0;
        }

        return $this->happyBirthdayListId[$type][$storeId];
    }

    /**
     * @param array $bulkData
     * @param string $type
     * @return array
     */
    public function generateBulkPayloadForBirthdayCoupon(array $bulkData, string $type): array
    {
        $payload = [];
        foreach ($bulkData as $dataset) {
            $subscriberArray = $dataset['contact'];
            if (!$this->isBirthdayCouponSendingEnabled($type, (int) $subscriberArray['store_id'])) {
                continue;
            }

            $payload['contacts'][] = $this->formatContact($dataset['contact'], $dataset['coupon'], $type);
        }

        return $payload;
    }

    /**
     * @param array $contact
     * @param string $couponCode
     * @param string $type
     * @return array
     */
    public function formatContact(array $contact, string $couponCode, string $type): array
    {
        $contactsArray = [];
        try {
            $store = $this->storeManager->getStore($contact['store_id']);
        } catch (NoSuchEntityException $e) {
            $store = null;
        }

        $contactsArray['email'] = $contact['email'];
        $contactsArray['fields'] = [
            [
                "id" => $this->getStoreFieldId($type, $contact['store_id']),
                "value" => $store ? $store->getCode() : 'default'
            ],
            [
                "id" => $this->getCouponFieldId($type, $contact['store_id']),
                "value" => $couponCode
            ],
            [
                "id" => $this->getMonthDayField($type, $contact['store_id']),
                "value" => $this->getMonthDayFromDate($contact['dob'])
            ]
        ];
        $contactsArray['subscribe'] = [
            [
                'listid' => $this->getHappyBirthdayListId($type, $contact['store_id'])
            ]
        ];

        return $contactsArray;
    }

    /**
     * @param string $date
     * @return string
     */
    public function getMonthDayFromDate(string $date): string
    {
        $time = strtotime($date);
        $month = date("m", $time);
        $day = date("d", $time);

        return $month . '-' . $day;
    }

    public function getProfileList()
    {
        $profiles = $this->scopeConfig->getValue(self::FB_ACTIVECAMPAIGN_PROFILES_LIST_SUBSCRIBER);

        return $profiles ? $this->unserialize($profiles) : [];
    }

    public function getSubscriberConsentsList($email, $storeId, $typeId = null)
    {
        return $this->consentSubscriptionRepository->retrieveByEmailAndType($email, $typeId);
    }

    public function getConsentTypeInfo($typeId)
    {
        return $this->consentTypeRepository->getById($typeId);
    }

    public function getDefaultCountryByWebsite($websiteId)
    {
        return $this->scopeConfig->getValue('general/country/default', ScopeInterface::SCOPE_WEBSITE, $websiteId);
    }

    public function getEmailLastOrder($email)
    {
        try {
            return $this->orderCollectionFactory->create()
                ->addAttributeToFilter('customer_email', $email)->getLastItem();
        } catch (Exception $e) {
            return false;
        }
    }

    public function processFieldsMap($fieldsMap, $customerSubscription, $result)
    {
        foreach ($fieldsMap ?? [] as $constant => $config) {
            $fieldId = $this->getActiveCampaignFieldId($constant);

            if ($fieldId) {
                $method = $config['method'];

                if (!empty($config['valueCallback'])) {
                    $value = $customerSubscription->$method();
                    $fieldValue = $config['valueCallback']($value);
                }

                if (array_key_exists('value', $config)) {
                    $fieldValue = $config['value'];
                }

                $result['create_update_contact']['request']['contact']['fieldValues'][] = [
                    "field" => $fieldId,
                    "value" => $fieldValue
                ];
            }
        }

        return $result;
    }

    public function isConsentsManagerEnabled(): bool
    {
        return $this->moduleManager->isEnabled('FiloBlu_ConsentsManager');
    }
}
