<?php

namespace App\Libraries;

use App\Entities\UserEntity;
use CodeIgniter\Session\Session;

/**
 * AuthContext
 * 인증 세션의 저장, 조회 및 파괴를 관리합니다.
 * AuthService의 세션 로직을 분리하여 SRP를 준수합니다.
 */
class AuthContext
{
  private Session $session;
  private string $urlStackName = "url_stack";

  // 환경 설정에서 정의된 상수라고 가정합니다.
  const SESSION_IS_LOGIN = 'ISLOGIN';
  const SESSION_AUTH_INFO = 'AUTH';

  public function __construct()
  {
    // 세션 서비스를 직접 사용합니다.
    $this->session = \Config\Services::session();
  }

  private function getAuthInfo(string $key = ""): array|int|string|null
  {
    $authInfo = $this->session->get(self::SESSION_AUTH_INFO);
    if ($key) {
      return $authInfo[$key] ?? null;
    }
    return $authInfo;
  }

  // ----------------------------------------------------
  // Public Accessors (AuthService에서 이동)
  // ----------------------------------------------------

  public function getUID(): int|null
  {
    return $this->getAuthInfo('uid');
  }

  public function getID(): string|null
  {
    return $this->getAuthInfo('id');
  }

  public function getName(): string|null
  {
    return $this->getAuthInfo('name');
  }

  public function getRole(): string|null
  {
    return $this->getAuthInfo('role');
  }

  public function getRoles(): array|null
  {
    return explode(DEFAULTS['DELIMITER_COMMA'], $this->getRole());
  }
  public function isLoggedIn(): bool
  {
    return $this->session->has(self::SESSION_IS_LOGIN);
  }

  public function isAccessRole(array $roles): bool
  {
    $userRoles = $this->getRoles();
    if (empty($userRoles) || !is_array($userRoles)) {
      return false;
    }
    return !empty(array_intersect($userRoles, $roles));
  }

  public function pushCurrentUrl(string $url): void
  {
    $this->session->set($this->urlStackName, $url);
  }

  public function popPreviousUrl(): string
  {
    $url = $this->session->get($this->urlStackName) ?? "";
    if (!empty($url)) {
      $this->session->set($this->urlStackName, ""); // 세션에서 제거
      return $url;
    }
    return '/';
  }

  // ----------------------------------------------------
  // Session Writers (Login/Logout Process)
  // ----------------------------------------------------

  /**
   * 인증 성공 후 세션에 사용자 정보를 기록합니다.
   */
  public function setAuthSession(UserEntity $entity): void
  {
    $this->session->set(self::SESSION_IS_LOGIN, true);
    $this->session->set(self::SESSION_AUTH_INFO, [
      'uid' => (int) $entity->getPK(),
      'id' => $entity->getID(),
      'name' => $entity->getTitle(),
      'role' => $entity->getRole()
    ]);
  }

  /**
   * 로그아웃 시 세션 및 쿠키를 파괴합니다.
   */
  public function destroyAuthSession(): void
  {
    // 세션 데이터 삭제
    $this->session->remove(self::SESSION_IS_LOGIN);
    $this->session->remove(self::SESSION_AUTH_INFO);

    // 모든 세션 데이터 삭제
    $this->session->destroy();

    // 세션 쿠키 삭제 (AuthService에서 가져온 로직)
    if (ini_get("session.use_cookies")) {
      $params = session_get_cookie_params();
      setcookie(
        session_name(),
        '',
        time() - 42000,
        $params["path"],
        $params["domain"],
        $params["secure"],
        $params["httponly"]
      );
    }
    // 세션 재생성
    session_start();
    $this->session->regenerate(true);
  }
}
