<?php

namespace FiloBlu\Flow\Model\Channel\In;

use Exception;
use FiloBlu\Flow\Helper\Data;
use FiloBlu\Flow\Helper\LoggerProvider;
use FiloBlu\Flow\Model\Channel\ConfigFactory;
use Magento\Framework\Mail\Template\TransportBuilder;
use Magento\Framework\ObjectManagerInterface;
use Magento\Framework\Translate\Inline\StateInterface;

/**
 * Class Price
 * @package FiloBlu\Flow\Model\Channel\In
 */
class Price extends AbstractModel
{
    /**
     * @var Data
     */
    protected $helperFlow;

    /**
     * @var array
     */
    protected $zeroPriceAlerts = [];

    /**
     * @var TransportBuilder
     */
    private $transportBuilder;

    /**
     * @var StateInterface
     */
    private $inlineTranslation;

    /**
     * @param LoggerProvider $loggerProvider
     * @param ConfigFactory $channelConfigFactory
     * @param ObjectManagerInterface $objectManager
     * @param Data $helperFlow
     * @param StateInterface $inlineTranslation
     * @param TransportBuilder $transportBuilder
     */
    public function __construct(
        LoggerProvider         $loggerProvider,
        ConfigFactory          $channelConfigFactory,
        ObjectManagerInterface $objectManager,
        Data                   $helperFlow,
        StateInterface         $inlineTranslation,
        TransportBuilder       $transportBuilder
    )
    {
        $this->helperFlow = $helperFlow;
        $this->inlineTranslation = $inlineTranslation;
        $this->transportBuilder = $transportBuilder;
        parent::__construct($loggerProvider, $channelConfigFactory, $objectManager);
    }


    /**
     * @param $data
     * @return bool
     */
    public function insertData($data)
    {
        $flow = $this->getFile()->getData('flow');
        $model = $this->objectManager->create('FiloBlu\Flow\Model' . "\\" . $flow);

        if (!$model) {
            return false;
        }

        $checkMappingCount = $this->getParser()->checkMappingCount();

        $model->setData('meta_file', $this->getFile()->getId());
        $model->setData('sku', $data['sku']);

        // No check mapping count, working as CSV headers -> table columns
        if (!$checkMappingCount || $this->map->isDirectInsert()) {
            // No map is checked here
            $this->directInsert($data, $model);
            // Do not go further
            return true;
        }

        foreach ($data as $field => $value) {
            if (!$this->getChannelConfig()->getAllowProcessZeroPrices()) {
                if ((float)$value <= 0 && $this->isLikelyPriceField($field)) {
                    // Collect field/value/sku for batch alert email
                    $this->zeroPriceAlerts[] = [
                        'sku' => $data['sku'] ?? 'N/A',
                        'field' => $field,
                        'value' => $value,
                    ];
                    continue;
                }
            }

            $fieldMap = $this->map->get($field);

            // devo inserire una riga per ogni website/prezzo
            if ((!isset($fieldMap['skip']) || !$fieldMap['skip']) && $fieldMap['type'] === 'price') {
                if (isset($fieldMap['website']) && is_array($fieldMap['website']) && count($fieldMap['website']) > 0) {
                    $websites = $fieldMap['website'];

                    foreach ($websites as $website) {
                        try {
                            $currency = $fieldMap['currency'];
                            $model->setId(null);
                            $model->setData('prezzo', floatval($value));
                            $model->setData('paese', $website);
                            $model->setData('valuta', $currency);
                            $model->setData('meta_processed', 0);
                            $model->setData('meta_insert_time', date('Y-m-d H:i:s'));
                            $model->save();
                        } catch (Exception $e) {
                            $this->_logger->info('Exception! ' . $e->getMessage() . PHP_EOL);
                        }
                    }
                } elseif (isset($fieldMap['website']) && $fieldMap['website'] !== '') {
                    try {
                        $currency = $fieldMap['currency'];
                        $website = $fieldMap['website'];
                        $model->setId(null);
                        $model->setData('prezzo', (float)$value);
                        $model->setData('paese', $website);
                        $model->setData('valuta', $currency);
                        $model->setData('meta_processed', 0);
                        $model->setData('meta_insert_time', date('Y-m-d H:i:s'));
                        $model->save();

                        // $this->_logger->info('Saved!! '. print_r($model->getData(), true) . PHP_EOL);
                    } catch (Exception $e) {
                        $this->_logger->info('Exception! ' . $e->getMessage() . PHP_EOL);
                    }
                } else {
                    $websites_list = explode(',', $data['paese']);

                    try {
                        if (empty($websites_list)) {
                            $this->_logger->info(' no website found for : ' . $data['sku'] . PHP_EOL);
                            return false;
                        }

                        foreach ($websites_list as $website) {
                            $metaProcessed = 0;
                            if (!$this->helperFlow->websiteExist($website)) {
                                $metaProcessed = 2;
                            }
                            $model->setId(null);
                            $model->setData('prezzo', (float)$value);
                            $model->setData('paese', $website);
                            $model->setData('valuta', $data['valuta']);
                            $model->setData('meta_processed', $metaProcessed);
                            $model->setData('meta_insert_time', date('Y-m-d H:i:s'));
                            $model->save();
                        }

                        // $this->_logger->info('Saved!! '. print_r($model->getData(), true) . PHP_EOL);
                    } catch (Exception $e) {
                        $this->_logger->info('Exception! ' . $e->getMessage() . PHP_EOL);
                    }
                }
            }
        }

        if (!empty($this->zeroPriceAlerts)) {
            $this->sendEmailToAlertForZeroPricesBatch($this->zeroPriceAlerts);
        }

        return true;
    }

    /**
     * @param $data
     * @param $model
     */
    private function directInsert($data, $model)
    {
        try {
            foreach ($data as $field => $value) {
                $model->setData($field, $value);
            }
            $model->setData('meta_processed', 0);
            $model->setData('meta_insert_time', date('Y-m-d H:i:s'));
            $model->save();
        } catch (Exception $e) {
            $this->_logger->info('Exception! ' . $e->getMessage() . PHP_EOL);
        }
    }

    /**
     * Sends a batch email with all fields that had zero price in the processed file
     *
     * @param array $zeroPriceAlerts
     */
    public function sendEmailToAlertForZeroPricesBatch(array $zeroPriceAlerts)
    {
        if (!$this->getChannelConfig()->shouldWarningOnZeroPrice()) {
            return;
        }

        $emails = $this->getChannelConfig()->getEmailToAlertForZeroPrice();

        if (empty($emails)) {
            $this->_logger->info('No email configured to alert for zero price.');
            return;
        }

        $filename = $this->getFile()->getName() ?? 'Unknown filename';

        $tableRowsHtml = '';
        foreach ($zeroPriceAlerts as $alert) {
            $sku = $alert['sku'] ?? '';
            $field = $alert['field'] ?? '';
            $value = isset($alert['value']) ? (string)$alert['value'] : '0';

            $tableRowsHtml .= sprintf(
                '<tr><td>%s</td><td>%s</td><td>%s</td></tr>',
                $sku,
                $field,
                $value
            );
        }

        try {
            $this->inlineTranslation->suspend();

            $transportBuilder = $this->transportBuilder
                ->setTemplateIdentifier('alert_zero_price_email_template')
                ->setTemplateOptions([
                    'area' => 'adminhtml',
                    'store' => 0,
                ])
                ->setTemplateVars([
                    'table_rows' => $tableRowsHtml,
                    'filename' => $filename
                ])
                ->setFromByScope(
                    [ 'email' => $this->helperFlow->getCustomEmail2(), 'name' => 'Zero Price Notifier'],
                    0
                );

            foreach ($emails as $recipient) {
                $transportBuilder->addTo($recipient);
            }

            $transport = $transportBuilder->getTransport();
            $transport->sendMessage();
        } catch (Exception $e) {
            $this->_logger->error('Failed to send zero price alert email: ' . $e->getMessage());
        } finally {
            $this->inlineTranslation->resume();
        }
    }

    /**
     * Determines if the given field name is likely to represent a price field.
     *
     * @param string $field The field name or key to check.
     * @return bool True if the field name matches common price-related patterns, false otherwise.
     */
    public function isLikelyPriceField(string $field): bool
    {
        return preg_match('/price|prezzo|listino/i', $field);
    }
}
