<?php

namespace Core\App\Models;

use PDO;

class AdminNotificationModel
{
    protected PDO $db;

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

    private function ensureSchema(): void
    {
        try {
            $this->db->exec("
                ALTER TABLE admin_notifications
                ADD COLUMN IF NOT EXISTS recipient_admin_id INT NULL AFTER reference_id,
                ADD COLUMN IF NOT EXISTS meta LONGTEXT NULL AFTER title
            ");
        } catch (\Throwable $e) {
        }
    }

    private function visibilitySql(bool $isManager): string
    {
        return $isManager
            ? '(recipient_admin_id = :admin_id OR recipient_admin_id IS NULL)'
            : '(recipient_admin_id = :admin_id)';
    }

    public function create(string $type, int $referenceId, string $title, ?int $recipientAdminId = null, array $meta = []): void
    {
        try {
            $stmt = $this->db->prepare("
                INSERT INTO admin_notifications
                    (type, reference_id, recipient_admin_id, title, meta, is_read, archived, created_at)
                VALUES
                    (:type, :reference_id, :recipient_admin_id, :title, :meta, 0, 0, UTC_TIMESTAMP())
            ");
            $stmt->execute([
                ':type' => $type,
                ':reference_id' => $referenceId,
                ':recipient_admin_id' => $recipientAdminId,
                ':title' => $title,
                ':meta' => !empty($meta) ? json_encode($meta, JSON_UNESCAPED_UNICODE | JSON_INVALID_UTF8_SUBSTITUTE) : null,
            ]);
        } catch (\Throwable $e) {
        }
    }

    public function createForAdmins(array $adminIds, string $type, int $referenceId, string $title, array $meta = []): void
    {
        $adminIds = array_values(array_unique(array_filter(array_map('intval', $adminIds), static fn(int $id): bool => $id > 0)));
        if (empty($adminIds)) {
            return;
        }

        foreach ($adminIds as $adminId) {
            $this->create($type, $referenceId, $title, $adminId, $meta);
        }
    }

    /**
     * عدد الإشعارات غير المقروءة
     */
    public function countUnread(?int $adminId = null, bool $isManager = true): int
    {
        if ($adminId === null || $adminId <= 0) {
            return 0;
        }

        $stmt = $this->db->prepare("
            SELECT COUNT(*) 
            FROM admin_notifications
            WHERE is_read = 0
              AND archived = 0
              AND {$this->visibilitySql($isManager)}
        ");
        $stmt->execute([':admin_id' => $adminId]);

        return (int)$stmt->fetchColumn();
    }

    public function getLatestForAdmin(int $adminId, bool $isManager = true, int $limit = 5): array
    {
        try {
            $stmt = $this->db->prepare(
                "SELECT id, type, reference_id, title, is_read, created_at
                 FROM admin_notifications
                 WHERE archived = 0
                   AND {$this->visibilitySql($isManager)}
                 ORDER BY created_at DESC
                 LIMIT :limit"
            );
            $stmt->bindValue(':admin_id', $adminId, \PDO::PARAM_INT);
            $stmt->bindValue(':limit', $limit, \PDO::PARAM_INT);
            $stmt->execute();
            return $stmt->fetchAll(\PDO::FETCH_ASSOC);
        } catch (\Throwable $e) {
            return [];
        }
    }

    public function getLatest(int $limit = 5): array
    {
        $adminId = (int)($_SESSION['admin_id'] ?? 0);
        $role = (string)($_SESSION['admin_role'] ?? '');
        return $this->getLatestForAdmin($adminId, in_array($role, ['owner', 'manager'], true), $limit);
    }
}
