<?php
require_once __DIR__ . '/../Core.php';

class Suppression extends Model
{
    public function all(): array
    {
        return $this->db->query('SELECT * FROM suppression_list ORDER BY updated_at DESC, id DESC')->fetchAll();
    }

    public function summary(int $days = 30): array
    {
        $days = max(1, (int)$days);
        $sql = "SELECT
            COUNT(*) AS total,
            SUM(channel = 'email') AS email_total,
            SUM(channel = 'sms') AS sms_total,
            SUM(reason LIKE 'bounce%') AS bounce_total,
            SUM(reason LIKE 'complaint%') AS complaint_total,
            SUM(reason LIKE 'blocked%') AS blocked_total,
            SUM(created_at >= DATE_SUB(NOW(), INTERVAL {$days} DAY)) AS recent_total
            FROM suppression_list";
        return $this->db->query($sql)->fetch() ?: [];
    }

    public function recent(int $limit = 12): array
    {
        $stmt = $this->db->prepare('SELECT * FROM suppression_list ORDER BY updated_at DESC, id DESC LIMIT ?');
        $stmt->bindValue(1, $limit, PDO::PARAM_INT);
        $stmt->execute();
        return $stmt->fetchAll();
    }

    public function forContact(int $contactId): array
    {
        $sql = "SELECT s.*
            FROM suppression_list s
            LEFT JOIN contacts c ON c.id = ?
            WHERE s.contact_id = ?
               OR (s.channel = 'email' AND s.normalized_address = LOWER(TRIM(COALESCE(c.email, ''))))
               OR (s.channel = 'sms' AND s.normalized_address = REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(TRIM(COALESCE(c.phone, '')), ' ', ''), '-', ''), '(', ''), ')', ''), '+', ''), '.', ''), '/', ''))
            ORDER BY s.updated_at DESC, s.id DESC";
        $stmt = $this->db->prepare($sql);
        $stmt->execute([$contactId, $contactId]);
        return $stmt->fetchAll();
    }

    public function findByAddress(string $channel, string $address): ?array
    {
        $normalized = normalize_channel_address($channel, $address);
        if ($normalized === '') {
            return null;
        }
        $stmt = $this->db->prepare('SELECT * FROM suppression_list WHERE channel = ? AND normalized_address = ? LIMIT 1');
        $stmt->execute([$channel, $normalized]);
        return $stmt->fetch() ?: null;
    }

    public function isSuppressed(string $channel, string $address): bool
    {
        return $this->findByAddress($channel, $address) !== null;
    }

    public function add(string $channel, string $address, string $reason = 'manual', ?int $contactId = null, ?int $messageId = null): int
    {
        $normalized = normalize_channel_address($channel, $address);
        if ($normalized === '') {
            throw new RuntimeException('A valid address is required for suppression.');
        }
        $stmt = $this->db->prepare('INSERT INTO suppression_list (contact_id, message_id, channel, address, normalized_address, reason) VALUES (?, ?, ?, ?, ?, ?) ON DUPLICATE KEY UPDATE reason = VALUES(reason), address = VALUES(address), contact_id = COALESCE(VALUES(contact_id), contact_id), message_id = COALESCE(VALUES(message_id), message_id), updated_at = NOW()');
        $stmt->execute([$contactId, $messageId, $channel, $address, $normalized, $reason]);
        return (int)$this->db->lastInsertId();
    }

    public function removeByAddress(string $channel, string $address): void
    {
        $normalized = normalize_channel_address($channel, $address);
        if ($normalized === '') {
            return;
        }
        $stmt = $this->db->prepare('DELETE FROM suppression_list WHERE channel = ? AND normalized_address = ?');
        $stmt->execute([$channel, $normalized]);
    }

    public function delete(int $id): void
    {
        $stmt = $this->db->prepare('DELETE FROM suppression_list WHERE id = ?');
        $stmt->execute([$id]);
    }
}
