<?php

/*
ET-Chat Copyright by SEDesign | ET-Chat v3.x.x Lizenz: CCPL | Autor: Evgeni Tcherkasski (info@s-e-d.de)
ET-Chat_T-FISH-MOD Weiterentwicklungen, Optimierungen und Ergänzungen am Code sind das geistige Eigentum von Tommy (Thomas Kuhn) und Harlekin (Bernd Witte).

Die darauf folgende Optimierungen und Ergänzungen am Code sind das Geistige Eigentum von Powermen (Christian K.) 
PHP 8/9 Ready, XML Parser, PDO Prepared Statements Get Set sicherheit usw.
*/

class Broadcast extends DbConectionMaker
{
    private string $broadcast_file = __DIR__ . '/../cache/broadcast_current.txt';

    public function __construct()
    {
        parent::__construct();

        if (session_status() === PHP_SESSION_NONE) {
            session_start();
        }

        header('Content-Type: application/json; charset=utf-8');

        $function = $_GET['function'] ?? '';

        switch ($function) {

            case 'sendBroadcast':
                $this->sendBroadcast();
                break;

            case 'checkBroadcast':
                $this->checkBroadcast();
                break;

            case 'clearBroadcast':
                $this->clearBroadcast();
                break;

            case 'getBroadcastStatus':
                $this->getBroadcastStatus();
                break;

            default:
                echo json_encode(['error' => 'Unbekannte Funktion']);
        }

        if (isset($this->dbObj)) {
            $this->dbObj->close();
        }

        exit;
    }

    /* -------------------------------------------------- */
    /* ONLINE USER ERMITTELN */
    /* -------------------------------------------------- */

    private function getRealOnlineUsers(): array
    {
        $time_limit = time() - 300;

        $sqlRegistered = "
        SELECT 
            u.etchat_user_id
        FROM {$this->_prefix}etchat_useronline o
        JOIN {$this->_prefix}etchat_user u 
            ON o.etchat_user_online_user_name = u.etchat_username
        WHERE o.etchat_onlinetimestamp > ?
        AND (
            o.etchat_user_online_user_status_img IS NULL
            OR o.etchat_user_online_user_status_img NOT IN ('status_invisible','status_off')
        )
        AND u.etchat_userprivilegien != 'admin'
        ";

        $sqlGuests = "
        SELECT 
            etchat_onlineuser_fid
        FROM {$this->_prefix}etchat_useronline
        WHERE etchat_onlinetimestamp > ?
        AND (
            etchat_user_online_user_name LIKE 'Gast%'
            OR etchat_user_online_user_priv = 'gast'
        )
        AND (
            etchat_user_online_user_status_img IS NULL
            OR etchat_user_online_user_status_img NOT IN ('status_invisible','status_off')
        )
        GROUP BY LOWER(TRIM(etchat_user_online_user_name))
        ";

        $sql = "($sqlRegistered) UNION ALL ($sqlGuests)";

        $result = $this->dbObj->sqlGet($sql, [$time_limit, $time_limit]);

        $users = [];

        if ($result) {
            foreach ($result as $row) {
                if (isset($row[0])) {
                    $users[] = (int)$row[0];
                }
            }
        }

        return array_unique($users);
    }

    /* -------------------------------------------------- */

    private function isUserOnline(int $user_id): bool
    {
        $time_limit = time() - 300;

        $sql = "
        SELECT COUNT(*)
        FROM {$this->_prefix}etchat_useronline
        WHERE etchat_onlineuser_fid = ?
        AND etchat_onlinetimestamp > ?
        AND (
            etchat_user_online_user_status_img IS NULL
            OR etchat_user_online_user_status_img NOT IN ('status_invisible','status_off')
        )
        ";

        $result = $this->dbObj->sqlGet($sql, [$user_id, $time_limit]);

        return ($result && isset($result[0][0]) && $result[0][0] > 0);
    }

    /* -------------------------------------------------- */
    /* BROADCAST SENDEN */
    /* -------------------------------------------------- */

    private function sendBroadcast(): void
    {
        $priv = $_SESSION['etchat_' . $this->_prefix . 'user_priv'] ?? '';
		$allowedRoles = ['admin', 'co_admin'];

		if (!in_array($priv, $allowedRoles)) {
			echo json_encode(['success' => false, 'error' => 'Keine Admin- oder Co-Admin-Rechte']);
			return;
		}

        $message = trim($_POST['message'] ?? '');

        if ($message === '') {
            echo json_encode(['success' => false, 'error' => 'Leere Nachricht']);
            return;
        }

        $timestamp = time();

        $target_users = $this->getRealOnlineUsers();

        $data = [
            'timestamp' => $timestamp,
            'admin_id' => (int)($_POST['admin_id'] ?? 0),
            'message' => $message,
            'no_reload' => (int)($_POST['no_reload'] ?? 0),
            'message_type' => $_POST['message_type'] ?? 'standard',
            'target_users' => $target_users,
            'original_online_count' => count($target_users),
            'seen_by' => []
        ];

        file_put_contents(
            $this->broadcast_file,
            json_encode($data, JSON_UNESCAPED_UNICODE),
            LOCK_EX
        );

        $_SESSION['last_broadcast_seen'] = $timestamp;

        echo json_encode([
            'success' => true,
            'target_count' => count($target_users),
            'message_type' => $data['message_type']
        ]);
    }

    /* -------------------------------------------------- */
    /* BROADCAST CHECKEN */
    /* -------------------------------------------------- */

    private function checkBroadcast(): void
    {
        $current_user_priv = $_SESSION['etchat_' . $this->_prefix . 'user_priv'] ?? 'user';
		$current_user_id = (int)($_SESSION['etchat_' . $this->_prefix . 'user_id'] ?? 0);

		$excludedRoles = ['admin', 'co_admin'];
    
		if (in_array($current_user_priv, $excludedRoles, true)) {
			echo json_encode(['hasBroadcast' => false]);
			return;
		}

        if (!file_exists($this->broadcast_file)) {
            echo json_encode(['hasBroadcast' => false]);
            return;
        }

        $broadcast = $this->readBroadcast();

        if (!$broadcast) {
            echo json_encode(['hasBroadcast' => false]);
            return;
        }

        $seen_by = $broadcast['seen_by'] ?? [];

        if (in_array($current_user_id, $seen_by, true)) {
            echo json_encode(['hasBroadcast' => false]);
            return;
        }

        $is_online = $this->isUserOnline($current_user_id);

        switch ($broadcast['message_type']) {

            case 'standard':

                if (!$is_online) {
                    echo json_encode(['hasBroadcast' => false]);
                    return;
                }

                if (!in_array($current_user_id, $broadcast['target_users'], true)) {
                    echo json_encode(['hasBroadcast' => false]);
                    return;
                }

                break;

            case 'general':
                break;

            case 'welcome':

				if (in_array($current_user_id, $broadcast['target_users'], true)) {
                    echo json_encode(['hasBroadcast' => false]);
                    return;
                }

                if (!$is_online) {
                    echo json_encode(['hasBroadcast' => false]);
                    return;
                }

                break;
        }

        $seen_by[] = $current_user_id;

        $broadcast['seen_by'] = $seen_by;

        file_put_contents(
            $this->broadcast_file,
            json_encode($broadcast, JSON_UNESCAPED_UNICODE),
            LOCK_EX
        );

        echo json_encode([
            'hasBroadcast' => true,
            'message' => $broadcast['message'],
            'no_reload' => $broadcast['no_reload']
        ]);
    }

    /* -------------------------------------------------- */
    /* STATUS */
    /* -------------------------------------------------- */

    private function getBroadcastStatus(): void
	{
		if (!file_exists($this->broadcast_file)) {
			echo json_encode(['hasBroadcast' => false]);
			return;
		}

		$broadcast = $this->readBroadcast();

		if (!$broadcast) {
			echo json_encode(['hasBroadcast' => false]);
			return;
		}

		$current_online = count($this->getRealOnlineUsers());

		echo json_encode([
			'hasBroadcast' => true,
			'message' => $broadcast['message'],
			'timestamp' => $broadcast['timestamp'],
			'time_ago' => $this->getTimeAgo($broadcast['timestamp']),

			// 🔥 DIESE FEHLTEN
			'no_reload' => $broadcast['no_reload'] ?? 0,
			'message_type' => $broadcast['message_type'] ?? 'standard',
			'original_online_count' => $broadcast['original_online_count'] ?? count($broadcast['target_users']),

			// bestehend
			'target_count' => count($broadcast['target_users']),
			'seen_count' => count($broadcast['seen_by'] ?? []),
			'current_online_count' => $current_online
		]);
	}

    /* -------------------------------------------------- */
    /* CLEAR */
    /* -------------------------------------------------- */

    private function clearBroadcast(): void
    {
        $priv = $_SESSION['etchat_' . $this->_prefix . 'user_priv'] ?? '';
		$allowedRoles = ['admin', 'co_admin'];

		if (!in_array($priv, $allowedRoles)) {
			echo json_encode(['success' => false, 'error' => 'Keine Admin- oder Co-Admin-Rechte']);
			return;
		}

        if (file_exists($this->broadcast_file)) {
            unlink($this->broadcast_file);
        }

        echo json_encode(['success' => true]);
    }

    /* -------------------------------------------------- */
    /* HELPER */
    /* -------------------------------------------------- */

    private function readBroadcast(): ?array
    {
        if (!file_exists($this->broadcast_file)) {
            return null;
        }

        $data = file_get_contents($this->broadcast_file);

        if (!$data) {
            return null;
        }

        $json = json_decode($data, true);

			if (!is_array($json) || json_last_error() !== JSON_ERROR_NONE) {
				return null;
			}

		return $json;
    }

    /* -------------------------------------------------- */

    private function getTimeAgo(int $timestamp): string
    {
        $diff = time() - $timestamp;

        if ($diff < 60) {
            return 'Gerade eben';
        }

        if ($diff < 3600) {
            $m = floor($diff / 60);
            return "Vor {$m} Minute" . ($m > 1 ? 'n' : '');
        }

        if ($diff < 86400) {
            $h = floor($diff / 3600);
            return "Vor {$h} Stunde" . ($h > 1 ? 'n' : '');
        }

        $d = floor($diff / 86400);
        return "Vor {$d} Tag" . ($d > 1 ? 'en' : '');
    }
}