<?php
/**
 * SuiteCRM is a customer relationship management program developed by SuiteCRM Ltd.
 * Copyright (C) 2025 SuiteCRM Ltd.
 *
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the GNU Affero General Public License version 3 as published by the
 * Free Software Foundation with the addition of the following permission added
 * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
 * IN WHICH THE COPYRIGHT IS OWNED BY SUITECRM, SUITECRM DISCLAIMS THE
 * WARRANTY OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
 * details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * In accordance with Section 7(b) of the GNU Affero General Public License
 * version 3, these Appropriate Legal Notices must retain the display of the
 * "Supercharged by SuiteCRM" logo. If the display of the logos is not reasonably
 * feasible for technical reasons, the Appropriate Legal Notices must display
 * the words "Supercharged by SuiteCRM".
 */

namespace App\Data\LegacyHandler\PresetDataHandlers;


use App\Authentication\LegacyHandler\UserHandler;
use App\Data\LegacyHandler\BaseListDataHandler;
use App\Data\LegacyHandler\FilterMapper\LegacyFilterMapper;
use App\Data\LegacyHandler\ListData;
use App\Data\LegacyHandler\ListDataHandlerInterface;
use App\Data\LegacyHandler\PresetListDataHandlerInterface;
use App\Data\LegacyHandler\RecordMapper;

class OutboundEmailDataHandler extends BaseListDataHandler implements ListDataHandlerInterface, PresetListDataHandlerInterface
{
    public const HANDLER_KEY = 'outbound-email-data-handlers';

    public function __construct(
        LegacyFilterMapper $legacyFilterMapper,
        RecordMapper $recordMapper,
        protected UserHandler $userHandler
    )
    {
        parent::__construct($legacyFilterMapper, $recordMapper);
    }

    /**
     * @return string
     */
    public function getType(): string
    {
        return 'outbound-email';
    }

    /**
     * @inheritDoc
     */
    public function fetch(
        string $module,
        array  $criteria = [],
        int    $offset = -1,
        int    $limit = -1,
        array  $sort = [],
        string $type = 'advanced'
    ): ListData
    {
        $currentUser = $this->userHandler->getCurrentUser();

        $bean = $this->getBean($module);

        $legacyCriteria = $this->mapCriteria($criteria, $sort, $type);

        [$params, $where, $filter_fields] = $this->prepareQueryData($type, $bean, $legacyCriteria);

        $where = $this->getWhere($currentUser, $where);

        $resultData = $this->getListDataPort()->get($bean, $where, $offset, $limit, $filter_fields, $params);

        return $this->buildListData($resultData);
    }

    /**
     * @param array $resultData
     * @return ListData
     */
    protected function buildListData(array $resultData): ListData
    {
        $listData = new ListData();
        $records = $this->recordMapper->mapRecords($resultData['data'] ?? [], $resultData['pageData'] ?? []);
        $this->filterInvalidOutbounds($records, $resultData);
        $listData->setRecords($records);
        $listData->setOrdering($resultData['pageData']['ordering'] ?? []);
        if (isset($resultData['pageData']['offsets']['total']) && is_numeric($resultData['pageData']['offsets']['total'])) {
            $resultData['pageData']['offsets']['total'] = (int)$resultData['pageData']['offsets']['total'];
        }
        $listData->setOffsets($resultData['pageData']['offsets'] ?? []);

        return $listData;
    }

    protected function getWhere(?\SugarBean $currentUser, string $where): string
    {
        if (!is_admin($currentUser)){
            return $where;
        }

        $table = \BeanFactory::newBean('OutboundEmailAccounts')->getTableName();

        $showGroupRecords = "($table.type IS NULL) OR ($table.type != 'user' ) OR ";

        $query = "($showGroupRecords ($table.type = 'user' AND user_id = '".$currentUser?->db->quote($currentUser?->id)."'))";

        if (empty($where)) {
            return $query;
        }

        $where .= " AND $query";

        return $where;
    }

    protected function filterInvalidOutbounds(array &$records, array &$resultData): void
    {
        foreach ($records as $key => $record) {
            $attributes = $record->getAttributes();

            if (!empty($attributes['from_addr'])) {
                continue;
            }

            unset($records[$key]);
            $resultData['pageData']['offsets']['total']--;
        }
    }
}
