<?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\Module\Campaigns\Service\Email\Log;

use App\Data\Entity\Record;
use App\Data\LegacyHandler\PreparedStatementHandler;
use App\Data\Service\RecordProviderInterface;
use App\DateTime\LegacyHandler\DateTimeHandlerInterface;
use Doctrine\DBAL\Exception;
use Psr\Log\LoggerInterface;

class DefaultEmailCampaignLogManager implements EmailCampaignLogManagerInterface
{
    public function __construct(
        protected RecordProviderInterface $recordProvider,
        protected LoggerInterface $logger,
        protected DateTimeHandlerInterface $dateTimeHandler,
        protected PreparedStatementHandler $preparedStatementHandler,
    ) {
    }

    public function createCampaignLogEntry(
        string $campaignId,
        string $marketingId,
        string $email,
        string $activityType,
        string $prospectListId,
        string $targetId,
        string $targetType,
        string $trackerId = '',
        string $relatedId = '',
        string $relatedType = '',
        bool $isTest = false
    ): void {

        $timedate = $this->dateTimeHandler->getDateTime();

        $record = new Record();
        $record->setModule('campaign-log');
        $attributes = [
            'module_name' => 'CampaignLog',
            'campaign_id' => $campaignId,
            'marketing_id' => $marketingId,
            'more_information' => $email,
            'activity_type' => $activityType,
            'activity_date' => $timedate->nowDb(),
            'list_id' => $prospectListId ?? null,
            'related_id' => $relatedId,
            'related_type' => $relatedType,
            'target_id' => $targetId,
            'target_type' => $targetType,
            'resend_type' => null,
            'is_test_entry' => $isTest,
        ];

        if ($trackerId !== '') {
            $attributes['target_tracker_key'] = $trackerId;
        }

        $record->setAttributes(
            $attributes
        );

        $savedRecord = $this->recordProvider->saveRecord($record);
        $this->logger->debug(
            'Campaigns:DefaultEmailCampaignLogManager::createCampaignLogEntry - Campaign log entry created - id: ' . $savedRecord->getId(), [
                'campaignLogId' => $savedRecord->getId(),
                'campaignId' => $campaignId,
                'marketingId' => $marketingId,
                'activityType' => $activityType,
                'prospectListId' => $prospectListId,
                'targetId' => $targetId,
                'targetType' => $targetType,
                'relatedId' => $relatedId,
                'relatedType' => $relatedType,
                '$trackerId' => $trackerId,
                'is_test_entry' => $isTest,
            ]
        );
    }

    public function countEntries(string $marketingId): int
    {
        $queryBuilder = $this->preparedStatementHandler->createQueryBuilder();
        $queryBuilder->select('COUNT(*) as total')
                     ->from('campaign_log')
                     ->where('marketing_id = :mkt_id')
                     ->andWhere('activity_type IN (:activity_types)')
                     ->andWhere('is_test_entry = 0')
                     ->andWhere('deleted = 0')
                     ->setParameter('mkt_id', $marketingId)
                     ->setParameter('activity_types', ['targeted', 'send error'], \Doctrine\DBAL\ArrayParameterType::STRING);

        try {
            $result = $queryBuilder->fetchAssociative();
            return (int)($result['total'] ?? 0);
        } catch (Exception $e) {
            $this->logger->error(
                'Campaigns:DefaultEmailCampaignLogManager::countEntries | Exception - ' . $e->getMessage(),
                ['trace' => $e->getTrace()]
            );
            return 0;
        }
    }
}
