<?php

namespace FiloBlu\Flow\Model\Channel\In;

use Exception;
use Magento\Framework\DB\Adapter\AdapterInterface;
use function in_array;

/**
 * Class Customer
 * @package FiloBlu\Flow\Model\Channel\In
 */
class Customer extends Anagrafica
{

    /**
     * @param $row
     * @return void
     * @throws Exception
     */
    public function insertData($row)
    {
        $binds = [];

        /** @var AdapterInterface $connection */
        $connection = $this->resourceConnection->getConnection();
        $tableName = $connection->getTableName('flow_from_customer');
        $meta_file = $this->getFile()->getId();

        if ($this->getChannelConfig()->usesMap()) {
            $binds_raw = $this->getSimpleFields($row, $meta_file);
            $actions_raw = $this->getActionFields($row, $binds_raw['actions'], $meta_file);
            $binds = array_merge($binds_raw['simple'], $actions_raw);
        } else {
            $metas = $this->getMetaRefIdAndExecutedOn($row, 'customer');

            $bind = [
                'e'                => $row['e'] ?? $row['email'],
                'a'                => $row['a'],
                'v'                => $row['v'],
                'params'           => $row['params'] ?? '',
                's'                => $row['s'],
                'executed_on'      => $metas['executed_on'],
                'meta_file'        => $meta_file,
                'meta_ref_id'      => $metas['meta_ref_id'],
                'meta_processed'   => 0,
                'meta_insert_time' => date('Y-m-d H:i:s')
            ];

            if (!empty($row['l'])) {
                // Missing storeview with this language!
                if (!isset($this->_storeByLocale[$row['l']])) {
                    $this->_logger->info("There is no storeview with language {$row['l']} (meta_file $meta_file)");
                    return;
                }

                /* Expand languages per store view */

                $storeViews = $this->_storeByLocale[$row['l']];

                foreach ($storeViews as $store) {
                    $dataPerStore = $bind;
                    $dataPerStore['s'] = $store;
                    $binds[] = $dataPerStore;
                }
            } else {
                $binds = $bind;
            }
        }

        $connection->insertOnDuplicate($tableName, $binds);
    }

    /**
     * @param $data
     * @param $meta_file
     * @return array
     * @throws Exception
     */
    public function getSimpleFields($data, $meta_file)
    {
        $binds = ['simple' => [], 'actions' => []];

        foreach ($data as $field => $value) {
            $fieldMap = $this->map->get($field);

            if ((!isset($fieldMap['skip']) || !$fieldMap['skip'])
                && (trim($value ?? '') !== '' || isset($fieldMap['allowNull']))
            ) {
                $to_field = '';
                if (isset($fieldMap['to']) && $fieldMap['to']) {
                    $to_field = $fieldMap['to'];
                    $metas = $this->getMetaRefIdAndExecutedOn(['a' => $to_field], 'customer');

                    if (!isset($fieldMap['actions']) || !in_array(
                        '_translate_attribute',
                        $fieldMap['actions'],
                        false
                    )) {
                        //devo inserire una riga per ogni attributo
                        $template_bind = [
                            'e'                => $data['email'],
                            'a'                => $to_field,
                            'v'                => trim($value),
                            'params'           => $data['params'] ?? '',
                            's'                => '',
                            'executed_on'      => $metas['executed_on'],
                            'meta_file'        => $meta_file,
                            'meta_ref_id'      => 0,
                            'meta_processed'   => 0,
                            'meta_insert_time' => date('Y-m-d H:i:s')
                        ];

                        $storeViews = ['s' => ''];

                        if ($fieldMap['stores'] && isset($fieldMap['stores']) && count($fieldMap['stores']) > 0) {
                            $storeViews = $fieldMap['stores'];
                        } else {
                            if ($fieldMap['locale'] && isset($fieldMap['locale']) && !empty($fieldMap['locale'])) {
                                //if there are no hashes it process the value normally
                                if (strpos($fieldMap['locale'], '#') === false) {
                                    $storeViews = $this->_storeByLocale[$fieldMap['locale']];
                                } //Otherwise it gets the value in the column of array
                                else {
                                    $localeField = strtolower($data[str_replace('#', '', $fieldMap['locale'])]);
                                    $storeViews = $this->_storeByLocale[$localeField];
                                }
                            } else {
                                // TODO : Unreachable statement ??
                            }
                        }

                        foreach ($storeViews as $store) {
                            $template_bind['s'] = $store;
                            $binds['simple'][] = $template_bind;
                        }
                    }
                }
            }
            // Le azioni le conservo per inserirle alla fine
            if (isset($fieldMap['actions'])) {
                foreach ($fieldMap['actions'] as $action) {
                    $a = ['value' => $value, 'stores' => []];
                    if (empty($a['value'])) {
                        continue;
                    }

                    if (isset($to_field) && ($action === '_translate_attribute' || $action === '_set_default_locale')) {
                        $a['e'] = $to_field;
                    }
                    if ($fieldMap['stores'] && isset($fieldMap['stores']) && count($fieldMap['stores']) > 0) {
                        $a['stores'] = $fieldMap['stores'];
                    } else {
                        if ($fieldMap['locale'] && isset($fieldMap['locale']) && !empty($fieldMap['locale'])) {
                            //$storeViews = $this->_storeByLocale[$fieldMap['locale']];
                            //if there are no hashes it process the value normally
                            if (strpos($fieldMap['locale'], '#') === false) {
                                $storeViews = $this->_storeByLocale[$fieldMap['locale']];
                            } //Otherwise it gets the value in the column of array
                            else {
                                $localeField = strtolower($data[str_replace('#', '', $fieldMap['locale'])]);
                                $storeViews = $this->_storeByLocale[$localeField];
                            }
                            foreach ($storeViews as $store) {
                                $a['stores'][] = $store;
                            }
                        } else {
                            // TODO : unreachable statement ??
                        }
                    }

                    if (isset($fieldMap['params']) && !empty($fieldMap['params'])) {
                        $a['params'] = json_encode($fieldMap['params']);
                    }
                    $binds['actions'][$action][] = $a;
                }
            }
        }

        return $binds;
    }

    /**
     * @param $data
     * @param $actions
     * @param $metaFile
     * @return array
     */
    public function getActionFields($data, $actions, $metaFile)
    {
        $actionsParsed = [];

        foreach ($actions as $a => $values) {
            $metas = $this->getMetaRefIdAndExecutedOn(['a' => $a], 'customer');

            foreach ($values as $v) {
                $bind = [
                    'e'                => $v['e'] ?? $data['email'],
                    'a'                => $a,
                    'v'                => $v['value'],
                    'params'           => $v['params'] ?? '',
                    's'                => '',
                    'executed_on'      => $metas['executed_on'],
                    'meta_file'        => $metaFile,
                    'meta_ref_id'      => $metas['meta_ref_id'],
                    'meta_processed'   => 0,
                    'meta_insert_time' => date('Y-m-d H:i:s')
                ];

                if (count($v['stores']) > 0) {
                    $storeViews = $v['stores'];
                    foreach ($storeViews as $store) {
                        $bind['s'] = $store;
                        $actionsParsed[] = $bind;
                    }
                } else {
                    $actionsParsed[] = $bind;
                }
            }
        }

        return $actionsParsed;
    }

    /**
     * @return bool
     */
    public function commitData()
    {
        return true;
    }
}
