<?php

/**
 * Хелпер для роботи з сесіями
 * Централізовані методи для роботи з сесіями та аутентифікацією
 *
 * @package Flowaxy\Support\Helpers
 * @version 1.0.0 Alpha prerelease
 */

declare(strict_types=1);

namespace Flowaxy\Support\Helpers;

use Flowaxy\Support\Managers\SessionManager;

final class SessionHelper
{
    /**
     * Отримання менеджера сесії
     * Уніфікований спосіб отримання менеджера сесії з fallback механізмами
     *
     * @return SessionManager|null
     */
    public static function getManager(): ?SessionManager
    {
        // Спочатку пробуємо через глобальну функцію sessionManager()
        if (function_exists('sessionManager')) {
            $session = sessionManager();
            if ($session instanceof SessionManager) {
                return $session;
            }
        }

        // Потім пробуємо через фасад Session
        if (class_exists(\Flowaxy\Support\Facades\Session::class)) {
            try {
                $session = \Flowaxy\Support\Facades\Session::manager();
                if ($session instanceof SessionManager) {
                    return $session;
                }
            } catch (\Throwable $e) {
                // Фасад не доступний, продовжуємо до fallback
            }
        }

        // Fallback: використовуємо getInstance() напрямую
        if (class_exists(SessionManager::class)) {
            try {
                $session = SessionManager::getInstance();
                if ($session instanceof SessionManager) {
                    return $session;
                }
            } catch (\Throwable $e) {
                // getInstance() не спрацював
            }
        }

        return null;
    }

    /**
     * Отримання ID користувача з сесії
     *
     * @return int ID користувача або 0, якщо не знайдено
     */
    public static function getUserId(): int
    {
        $session = self::getManager();
        if ($session === null) {
            return 0;
        }

        $userId = $session->get('admin_user_id', 0);
        return (int)$userId;
    }

    /**
     * Перевірка, чи користувач аутентифікований
     *
     * @return bool
     */
    public static function isAuthenticated(): bool
    {
        $userId = self::getUserId();
        return $userId > 0;
    }

    /**
     * Отримання flash повідомлення з сесії
     * Flash повідомлення автоматично видаляється після читання
     *
     * @param string $key Ключ повідомлення
     * @param mixed $default Значення за замовчуванням
     * @return mixed
     */
    public static function getFlash(string $key, $default = null)
    {
        $session = self::getManager();
        if ($session === null) {
            return $default;
        }

        if (method_exists($session, 'flash')) {
            return $session->flash($key, $default);
        }

        // Fallback: якщо метод flash не доступний, використовуємо get
        $value = $session->get($key, $default);
        if ($value !== $default) {
            $session->remove($key);
        }

        return $value;
    }

    /**
     * Встановлення flash повідомлення в сесію
     * Flash повідомлення зберігається для одного запиту
     *
     * @param string $key Ключ повідомлення
     * @param mixed $value Значення
     * @return void
     */
    public static function setFlash(string $key, $value): void
    {
        $session = self::getManager();
        if ($session === null) {
            return;
        }

        if (method_exists($session, 'setFlash')) {
            $session->setFlash($key, $value);
        } else {
            // Fallback: використовуємо set
            $session->set($key, $value);
        }
    }

    /**
     * Отримання значення з сесії
     *
     * @param string $key Ключ
     * @param mixed $default Значення за замовчуванням
     * @return mixed
     */
    public static function get(string $key, $default = null)
    {
        $session = self::getManager();
        if ($session === null) {
            return $default;
        }

        return $session->get($key, $default);
    }

    /**
     * Встановлення значення в сесію
     *
     * @param string $key Ключ
     * @param mixed $value Значення
     * @return void
     */
    public static function set(string $key, $value): void
    {
        $session = self::getManager();
        if ($session === null) {
            return;
        }

        $session->set($key, $value);
    }

    /**
     * Видалення значення з сесії
     *
     * @param string $key Ключ
     * @return void
     */
    public static function delete(string $key): void
    {
        $session = self::getManager();
        if ($session === null) {
            return;
        }

        if (method_exists($session, 'remove')) {
            $session->remove($key);
        } elseif (method_exists($session, 'delete')) {
            $session->delete($key);
        }
    }

    /**
     * Отримання username користувача з сесії
     *
     * @return string|null
     */
    public static function getUsername(): ?string
    {
        $session = self::getManager();
        if ($session === null) {
            return null;
        }

        $username = $session->get('admin_username', null);
        return $username !== null ? (string)$username : null;
    }
}
