<?php

namespace admin;

class Site
{
  // define APP_SECRET_KEY
  const APP_SECRET_KEY = 'c3cb2537d25c0efc9e573d059d79c3b8';

  public static function special_actions()
  {
    $sa = \S::get('s-action');
    $domain      = preg_replace('#^(http(s)?://)?w{3}\.#', '$1', $_SERVER['SERVER_NAME']);
    $cookie_name = str_replace('.', '-', $domain);

    switch ($sa)
    {
      case 'user-logon':
        {
          $login = \S::get('login');
          $pass  = \S::get('password');

          $result = \admin\factory\Users::logon($login, $pass);

          if ($result == 1)
          {
            $user = \admin\factory\Users::details($login);

            if ($user['twofa_enabled'] == 1)
            {
              \S::set_session('twofa_pending', [
                'uid'      => (int)$user['id'],
                'login'    => $login,
                'remember' => (bool)\S::get('remember'),
                'started'  => time(),
              ]);

              if (!\admin\factory\Users::send_twofa_code((int)$user['id']))
              {
                \S::alert('Nie udało się wysłać kodu 2FA. Spróbuj ponownie.');
                \S::delete_session('twofa_pending');
                header('Location: /admin/');
                exit;
              }

              header('Location: /admin/user/twofa/');
              exit;
            }
            else
            {
              $user = \admin\factory\Users::details($login);

              self::finalize_admin_login(
                $user,
                $domain,
                $cookie_name,
                (bool)\S::get('remember')
              );

              header('Location: /admin/articles/view_list/');
              exit;
            }
          }
          else
          {
            if ($result == -1)
            {
              \S::alert('Z powodu 5 nieudanych prób Twoje konto zostało zablokowane.');
            }
            else
            {
              \S::alert('Podane hasło jest nieprawidłowe lub użytkownik nie istnieje.');
            }
            header('Location: /admin/');
            exit;
          }
        }
        break;

      case 'user-2fa-verify':
        {
          $pending = \S::get_session('twofa_pending');
          if (!$pending || empty($pending['uid']))
          {
            \S::alert('Sesja 2FA wygasła. Zaloguj się ponownie.');
            header('Location: /admin/');
            exit;
          }

          $code = trim((string)\S::get('twofa'));
          if (!preg_match('/^\d{6}$/', $code))
          {
            \S::alert('Nieprawidłowy format kodu.');
            header('Location: /admin/user/twofa/');
            exit;
          }

          $ok = \admin\factory\Users::verify_twofa_code((int)$pending['uid'], $code);
          if (!$ok)
          {
            \S::alert('Błędny lub wygasły kod.');
            header('Location: /admin/user/twofa/');
            exit;
          }

          // 2FA OK — finalna sesja
          $user = \admin\factory\Users::details($pending['login']);
          \S::set_session('user', $user);
          \S::delete_session('twofa_pending');

          // Remember me – BEZPIECZNY podpis HMAC:
          if (!empty($pending['remember']))
          {
            $payloadArr = ['login' => $user['login'], 'ts' => time()];
            $json = json_encode($payloadArr, JSON_UNESCAPED_SLASHES);
            $sig  = hash_hmac('sha256', $json, APP_SECRET_KEY);
            $payload = base64_encode($json . '.' . $sig);

            setcookie($cookie_name, $payload, [
              'expires'  => time() + (86400 * 14),
              'path'     => '/',
              'domain'   => $domain,
              'secure'   => true,
              'httponly' => true,
              'samesite' => 'Lax',
            ]);
          }

          header('Location: /admin/articles/view_list/');
          exit;
        }
        break;

      case 'user-2fa-resend':
        {
          $pending = \S::get_session('twofa_pending');
          if (!$pending || empty($pending['uid']))
          {
            \S::alert('Sesja 2FA wygasła. Zaloguj się ponownie.');
            header('Location: /admin/');
            exit;
          }

          if (!\admin\factory\Users::send_twofa_code((int)$pending['uid'], true))
          {
            \S::alert('Kod można wysłać ponownie po krótkiej przerwie.');
          }
          else
          {
            \S::alert('Nowy kod został wysłany.');
          }
          header('Location: /admin/user/twofa/');
          exit;
        }
        break;

      case 'user-logout':
        {
          setcookie($cookie_name, "", time() - 86400, "/", $domain);
          \S::delete_session('twofa_pending');
          session_destroy();
          header('Location: /admin/');
          exit;
        }
        break;
    }
  }


  public static function route()
  {
    $_SESSION['admin'] = true;

    $class = '\admin\controls\\';

    $results = explode('_', \S::get('module'));
    if (is_array($results)) foreach ($results as $row)
      $class .= ucfirst($row);

    $action = \S::get('action');

    if (class_exists($class) and method_exists(new $class, $action))
      return call_user_func_array(array($class, $action), array());
    else
    {
      \S::alert('Nieprawidłowy adres url.');
      return false;
    }
  }

  static public function finalize_admin_login(array $user, string $domain, string $cookie_name, bool $remember = false) {
    \S::set_session('user', $user);
    \S::delete_session('twofa_pending');

    if ($remember)
    {
      $payloadArr = [
        'login' => $user['login'],
        'ts'    => time()
      ];

      $json = json_encode($payloadArr, JSON_UNESCAPED_SLASHES);
      $sig  = hash_hmac('sha256', $json, self::APP_SECRET_KEY);
      $payload = base64_encode($json . '.' . $sig);

      setcookie($cookie_name, $payload, [
        'expires'  => time() + (86400 * 14),
        'path'     => '/',
        'domain'   => $domain,
        'secure'   => true,
        'httponly' => true,
        'samesite' => 'Lax',
      ]);
    }
  }
}
