<?php

/**
 * Copyright 2024-2025 Simply.IN Sp. z o.o.
 *
 * NOTICE OF LICENSE
 *
 * Licensed under the EUPL-1.2 or later.
 * You may not use this work except in compliance with the Licence.
 *
 * Copy of the Licence is available at:
 * https://joinup.ec.europa.eu/software/page/eupl
 * It is bundled with this package in the file LICENSE.txt
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the Licence is distributed on an as is basis,
 * without warranties or conditions of any kind, either express or implied.
 * Check the Licence for the specific language governing permissions
 * and limitations under the License.
 *
 * @author   Simply.IN Sp. z o.o.
 * @copyright 2024-2025 Simply.IN Sp. z o.o.
 * @license   https://joinup.ec.europa.eu/software/page/eupl
 */

if (!defined('_PS_VERSION_')) {
    exit;
}

class SimplyInEmailCache extends ObjectModel
{
    use SimplyInInstallSqlTrait;

    public $id;

    public $email;

    public $customer_exist = false;

    public $date_check = '';

    public static $token = '';

    public static $definition = [
        'table' => 'simplyin_email_cache',
        'primary' => 'id_simplyin_email_cache',
        'multilang' => false,
        'multilang_shop' => false,
        'fields' => [
            'email' => [
                'type' => self::TYPE_STRING,
                'size' => 100,
                'index' => true,
            ],
            'customer_exist' => [
                'type' => self::TYPE_BOOL,
            ],
            'date_check' => [
                'type' => self::TYPE_DATE,
            ],
        ],
    ];

    public static function getByEmail($email)
    {
        $sql = '
            SELECT *    FROM `' . _DB_PREFIX_ . self::$definition['table'] . '`
            WHERE       email = "' . pSQL($email) . '"
            AND         date_check > DATE_SUB(NOW(), INTERVAL 15 MINUTE)
        ';
        $row = Db::getInstance()->getRow($sql);
        if ($row) {
            $cache = new SimplyInEmailCache($row['id_simplyin_email_cache']);

            return $cache;
        }
        $cache = new SimplyInEmailCache();
        $cache->email = $email;

        return $cache;

    }

    public static function checkUserExist($user_email)
    {
        $sql = '
            SELECT *    FROM `' . _DB_PREFIX_ . self::$definition['table'] . '`
            WHERE       email = "' . pSQL($user_email) . '"
            AND         date_check > DATE_SUB(NOW(), INTERVAL 60 MINUTE)
        ';
        $row = Db::getInstance()->getRow($sql);
        if ($row) {
            return (bool) $row['customer_exist'];
        }
        if (trim($user_email) == '') {
            return false;
        }

        $hash = hash('sha256', strtolower($user_email));
        $body_data = [
            'data' => [
                $hash,
            ],
        ];

        $response = self::callVerifyHashedEmails($body_data);

        if (!isset($response['ok']) || !isset($response['data']) || empty($response['data'])) {
            $result = false;
        } else {
            $result = true;
        }
        self::addEmailToCache($user_email, $result);

        return $result;
    }

    public static function addEmailToCache($user_email, $result)
    {
        $cache = SimplyInEmailCache::getByEmail($user_email);
        $cache->email = $user_email;
        $cache->customer_exist = $result;
        $cache->date_check = date('Y-m-d H:i:s');
        $cache->save();

        return (bool) $cache->customer_exist;
    }

    public static function clearCacheByEmail($user_email)
    {
        $sql = '
            DELETE FROM `' . _DB_PREFIX_ . self::$definition['table'] . '`
            WHERE email = "' . pSQL($user_email) . '"
        ';

        return Db::getInstance()->execute($sql);
    }

    public static function checkUserListExist($list)
    {
        $result = [];
        $data = [];
        $hash_by_email = [];

        $list = array_slice($list, 0, 100);
        foreach ($list as $email) {
            $hash = hash('sha256', strtolower($email));
            $data[] = $hash;
            $hash_by_email[$hash] = $email;
        }

        $body_data = [
            'data' => $data,
        ];

        $response = self::callVerifyHashedEmails($body_data);

        if (!empty($response['data']) && is_array($response['data'])) {
            foreach ($response['data'] as $email_data) {
                $emailHash = is_array($email_data) ? ($email_data['email'] ?? null) : null;
                if ($emailHash === null || !isset($hash_by_email[$emailHash])) {
                    continue;
                }
                $email = $hash_by_email[$emailHash];
                $status = $email_data['status'] ?? null;
                $result[$email] = $status === 'Active';
                self::addEmailToCache($email, $result[$email]);
            }
        }

        return $result;
    }

    /**
     * @param array<string, mixed> $body_data
     *
     * @return array<string, mixed>
     */
    private static function callVerifyHashedEmails(array $body_data): array
    {
        $module = Module::getInstanceByName('simplyin');
        if (!$module instanceof Simplyin) {
            return [];
        }
        $client = \SimplyIn\Api\SimplyInApiClientFactory::fromPrestaShop($module, Context::getContext());
        $response = $client->apiCall($body_data, 'POST', 'users/verifyHashedEmailsExist');

        return is_array($response) ? $response : [];
    }
}
