<?php
declare(strict_types=1);

class RecipientAutomationService
{
    private PDO $db;
    private ?AutomationRuleEngine $ruleEngine = null;

    public function __construct(PDO $db)
    {
        $this->db = $db;
    }

    public function setRuleEngine(AutomationRuleEngine $ruleEngine): void
    {
        $this->ruleEngine = $ruleEngine;
    }

    public function assignTagToRecipient(int $recipientId, int $tagId, array $context = []): bool
    {
        if ($recipientId <= 0 || $tagId <= 0) {
            return false;
        }

        try {
            $sql = 'INSERT IGNORE INTO recipient_tags (recipient_id, tag_id, assigned_at) VALUES (?, ?, NOW())';
            $stmt = $this->db->prepare($sql);
            $stmt->execute([$recipientId, $tagId]);
            ErrorLogger::logSqlSuccess('recipient_automation: assign tag | SQL: ' . $sql . ' | params: ' . json_encode([$recipientId, $tagId], JSON_UNESCAPED_UNICODE));

            $inserted = $stmt->rowCount() > 0;
            if ($inserted && empty($context['suppress_rule_events']) && $this->ruleEngine !== null) {
                $this->ruleEngine->handleEvent('tag_assigned', $recipientId, $tagId, $context);
            }

            return $inserted;
        } catch (Throwable $e) {
            ErrorLogger::logSqlError('recipient_automation: assign tag failed | context: ' . json_encode(['recipient_id' => $recipientId, 'tag_id' => $tagId], JSON_UNESCAPED_UNICODE) . ' | error: ' . $e->getMessage());
            return false;
        }
    }

    public function removeTagFromRecipient(int $recipientId, int $tagId, array $context = []): bool
    {
        if ($recipientId <= 0 || $tagId <= 0) {
            return false;
        }

        try {
            $sql = 'DELETE FROM recipient_tags WHERE recipient_id = ? AND tag_id = ?';
            $stmt = $this->db->prepare($sql);
            $stmt->execute([$recipientId, $tagId]);
            ErrorLogger::logSqlSuccess('recipient_automation: remove tag | SQL: ' . $sql . ' | params: ' . json_encode([$recipientId, $tagId], JSON_UNESCAPED_UNICODE));

            $removed = $stmt->rowCount() > 0;
            if ($removed && empty($context['suppress_rule_events']) && $this->ruleEngine !== null) {
                $this->ruleEngine->handleEvent('tag_removed', $recipientId, $tagId, $context);
            }

            return $removed;
        } catch (Throwable $e) {
            ErrorLogger::logSqlError('recipient_automation: remove tag failed | context: ' . json_encode(['recipient_id' => $recipientId, 'tag_id' => $tagId], JSON_UNESCAPED_UNICODE) . ' | error: ' . $e->getMessage());
            return false;
        }
    }

    public function subscribeRecipientToList(int $recipientId, int $listId): bool
    {
        if ($recipientId <= 0 || $listId <= 0) {
            return false;
        }

        try {
            $pauseToken = bin2hex(random_bytes(16));
            $sql = 'INSERT IGNORE INTO recipient_lists (recipient_id, list_id, subscribed_at, pause_token) VALUES (?, ?, NOW(), ?)';
            $stmt = $this->db->prepare($sql);
            $stmt->execute([$recipientId, $listId, $pauseToken]);
            ErrorLogger::logSqlSuccess('recipient_automation: subscribe list | SQL: ' . $sql . ' | params: ' . json_encode([$recipientId, $listId, $pauseToken], JSON_UNESCAPED_UNICODE));

            return $stmt->rowCount() > 0;
        } catch (Throwable $e) {
            ErrorLogger::logSqlError('recipient_automation: subscribe list failed | context: ' . json_encode(['recipient_id' => $recipientId, 'list_id' => $listId], JSON_UNESCAPED_UNICODE) . ' | error: ' . $e->getMessage());
            return false;
        }
    }

    public function unsubscribeRecipientFromList(int $recipientId, int $listId): bool
    {
        if ($recipientId <= 0 || $listId <= 0) {
            return false;
        }

        try {
            $sql = 'DELETE FROM recipient_lists WHERE recipient_id = ? AND list_id = ?';
            $stmt = $this->db->prepare($sql);
            $stmt->execute([$recipientId, $listId]);
            ErrorLogger::logSqlSuccess('recipient_automation: unsubscribe list | SQL: ' . $sql . ' | params: ' . json_encode([$recipientId, $listId], JSON_UNESCAPED_UNICODE));

            return $stmt->rowCount() > 0;
        } catch (Throwable $e) {
            ErrorLogger::logSqlError('recipient_automation: unsubscribe list failed | context: ' . json_encode(['recipient_id' => $recipientId, 'list_id' => $listId], JSON_UNESCAPED_UNICODE) . ' | error: ' . $e->getMessage());
            return false;
        }
    }
}
