<?php
require_once __DIR__ . '/app_paths.php';
// admin/auth.php  (FINAL + ADMIN BYPASS)

require_once __DIR__ . '/security.php';
ua_session_start();

require_once __DIR__ . '/helpers.php';
require_once __DIR__ . '/db_bootstrap.php';
require_once __DIR__ . '/security_alerts_lib.php';
require_once __DIR__ . '/permissions_catalog.php';

/* =========================
   Auto-migrate: admin_users
========================= */
function ensure_auth_tables(mysqli $conn): void {
  try {
    // ✅ admin_roles
    if (!(function_exists('table_exists') && table_exists($conn, 'admin_roles'))) {
      @$conn->query("CREATE TABLE IF NOT EXISTS admin_roles (
        id INT AUTO_INCREMENT PRIMARY KEY,
        role_name VARCHAR(80) NOT NULL UNIQUE,
        permissions LONGTEXT NULL,
        created_at DATETIME NULL DEFAULT CURRENT_TIMESTAMP
      ) ENGINE=InnoDB DEFAULT CHARSET=utf8;");

      @$conn->query("INSERT IGNORE INTO admin_roles(id, role_name, permissions) VALUES (1,'مدير','{}')");
    } else {
      if (function_exists('col_exists') && !col_exists($conn,'admin_roles','role_name')) {
        if (col_exists($conn,'admin_roles','name')) {
          @$conn->query("ALTER TABLE admin_roles ADD COLUMN role_name VARCHAR(80) NULL");
          @$conn->query("UPDATE admin_roles SET role_name = COALESCE(role_name, name)");
          @$conn->query("ALTER TABLE admin_roles MODIFY role_name VARCHAR(80) NOT NULL");
          @$conn->query("ALTER TABLE admin_roles ADD UNIQUE(role_name)");
        } else {
          @$conn->query("ALTER TABLE admin_roles ADD COLUMN role_name VARCHAR(80) NOT NULL UNIQUE");
        }
      }
      if (function_exists('col_exists') && !col_exists($conn,'admin_roles','permissions')) {
        @$conn->query("ALTER TABLE admin_roles ADD COLUMN permissions LONGTEXT NULL");
      }
    }

    if (function_exists('table_exists') && table_exists($conn, 'admin_users')) {
      if (function_exists('col_exists') && !col_exists($conn,'admin_users','permissions')) {
        @$conn->query("ALTER TABLE admin_users ADD COLUMN permissions LONGTEXT NULL");
      }
      if (function_exists('col_exists') && !col_exists($conn,'admin_users','full_name')) {
        @$conn->query("ALTER TABLE admin_users ADD COLUMN full_name VARCHAR(100) NULL");
      }
      if (function_exists('col_exists') && !col_exists($conn,'admin_users','password_hash')) {
        @$conn->query("ALTER TABLE admin_users ADD COLUMN password_hash VARCHAR(255) NULL");
      }
      if (function_exists('col_exists') && !col_exists($conn,'admin_users','is_active')) {
        @$conn->query("ALTER TABLE admin_users ADD COLUMN is_active TINYINT(1) NOT NULL DEFAULT 1");
      }
      if (function_exists('col_exists') && !col_exists($conn,'admin_users','role_id')) {
        @$conn->query("ALTER TABLE admin_users ADD COLUMN role_id INT NULL");
      }
      $uaProfileCols = [
        'email' => "VARCHAR(120) NULL",
        'phone' => "VARCHAR(40) NULL",
        'phone2' => "VARCHAR(40) NULL",
        'address' => "VARCHAR(255) NULL",
        'job_title' => "VARCHAR(120) NULL",
        'identity_no' => "VARCHAR(80) NULL",
        'avatar_path' => "VARCHAR(255) NULL",
        'identity_image_path' => "VARCHAR(255) NULL",
        'profile_notes' => "TEXT NULL",
        'updated_at' => "DATETIME NULL",
      ];
      foreach ($uaProfileCols as $uaCol => $uaDef) {
        if (function_exists('col_exists') && !col_exists($conn, 'admin_users', $uaCol)) {
          @$conn->query("ALTER TABLE admin_users ADD COLUMN `$uaCol` $uaDef");
        }
      }
      return;
    }

    $conn->query("CREATE TABLE IF NOT EXISTS admin_users (
      id INT AUTO_INCREMENT PRIMARY KEY,
      username VARCHAR(50) NOT NULL UNIQUE,
      password VARCHAR(255) NULL,
      password_hash VARCHAR(255) NULL,
      full_name VARCHAR(100) NULL,
      role_id INT NULL,
      permissions LONGTEXT NULL,
      is_active TINYINT(1) NOT NULL DEFAULT 1,
      email VARCHAR(120) NULL,
      phone VARCHAR(40) NULL,
      phone2 VARCHAR(40) NULL,
      address VARCHAR(255) NULL,
      job_title VARCHAR(120) NULL,
      identity_no VARCHAR(80) NULL,
      avatar_path VARCHAR(255) NULL,
      identity_image_path VARCHAR(255) NULL,
      profile_notes TEXT NULL,
      updated_at DATETIME NULL,
      created_at DATETIME NULL DEFAULT CURRENT_TIMESTAMP
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;");
  } catch (Throwable $e) {
    // ignore
  }
}

/* =========================
   إعدادات BYPASS
========================= */
$GLOBALS['BYPASS_ADMINS'] = ['admin','super','superadmin','Super Admin'];

/* =========================
   أدوات
========================= */
function auth_redirect(string $url): void {
  header("Location: $url");
  exit;
}

function auth_is_api_request(): bool {
  $path = (string)($_SERVER['PHP_SELF'] ?? '');
  if (strpos($path, '/api/') !== false) return true;
  $xrw = strtolower((string)($_SERVER['HTTP_X_REQUESTED_WITH'] ?? ''));
  if ($xrw === 'xmlhttprequest') return true;
  $accept = strtolower((string)($_SERVER['HTTP_ACCEPT'] ?? ''));
  if (strpos($accept, 'application/json') !== false) return true;
  return false;
}

function auth_current_file(): string {
  return basename($_SERVER['PHP_SELF'] ?? '');
}

function auth_close_readonly_api_session(): void {
  if (($_SERVER['REQUEST_METHOD'] ?? 'GET') !== 'GET') return;
  if (!auth_is_api_request()) return;
  if (session_status() === PHP_SESSION_ACTIVE) @session_write_close();
}

function auth_record_unauthorized_access(): void {
  static $recorded = false;
  if ($recorded) return;
  $recorded = true;
  try {
    // Background GET requests lose their session naturally when a tab expires or
    // closes. They are not authentication attempts and must never become security
    // incidents. Real failed logins are recorded separately by the login handler.
    if (auth_is_api_request() && (string)($_SERVER['REQUEST_METHOD'] ?? 'GET') === 'GET') return;
    $conn = $GLOBALS['conn'] ?? null;
    if (!($conn instanceof mysqli) && function_exists('ensure_db')) {
      $conn = ensure_db(false);
    }
    if (!($conn instanceof mysqli) || !function_exists('ua_security_record_event')) return;
    $method = (string)($_SERVER['REQUEST_METHOD'] ?? 'GET');
    $uri = (string)($_SERVER['REQUEST_URI'] ?? '');
    $path = (string)($_SERVER['PHP_SELF'] ?? '');
    $ip = function_exists('ua_security_client_ip') ? ua_security_client_ip() : (string)($_SERVER['REMOTE_ADDR'] ?? '');
    $requestPath = (string)(parse_url($uri, PHP_URL_PATH) ?: $path);
    $key = hash('sha256', 'admin-unauthorized-access|' . $ip . '|' . $method . '|' . $requestPath . '|' . date('Y-m-d'));
    ua_security_record_event(
      $conn,
      $key,
      'admin_unauthorized_access',
      'warn',
      'محاولة دخول مباشرة بدون جلسة',
      'تم رصد محاولة فتح صفحة إدارية مباشرة بدون تسجيل دخول: ' . $uri,
      [
        'username' => '',
        'ip_address' => $ip,
        'request_uri' => $uri,
        'meta' => [
          'source' => 'require_login',
          'method' => $method,
          'php_self' => $path,
          'is_api_request' => auth_is_api_request(),
          'referer' => (string)($_SERVER['HTTP_REFERER'] ?? ''),
        ],
      ]
    );
  } catch (Throwable $e) {
    return;
  }
}

/* =========================
   تسجيل الدخول الإجباري (بدون loop)
========================= */
function require_login(string $redirect_to = 'login.php'): void {
  $cur = auth_current_file();
  if ($cur === 'login.php' || $cur === 'logout.php') return;

  $logged = !empty($_SESSION['admin_id']) || !empty($_SESSION['admin_user_id']) || !empty($_SESSION['admin_user']);
  if (!$logged) {
    auth_record_unauthorized_access();
    if (auth_is_api_request()) {
      http_response_code(401);
      header('Content-Type: application/json; charset=utf-8');
      echo json_encode([
        'ok' => false,
        'error' => 'AUTH_REQUIRED',
        'message' => 'انتهت الجلسة أو لم يتم تسجيل الدخول'
      ], JSON_UNESCAPED_UNICODE);
      exit;
    }
    auth_redirect($redirect_to);
  }

  if (empty($_SESSION['admin_id']) && !empty($_SESSION['admin_user_id'])) {
    $_SESSION['admin_id'] = (int)$_SESSION['admin_user_id'];
  }
  if (empty($_SESSION['admin_username']) && !empty($_SESSION['admin_user'])) {
    $_SESSION['admin_username'] = (string)$_SESSION['admin_user'];
  }
  auth_close_readonly_api_session();
}

/* =========================
   صلاحيات
========================= */
function super_admin_perms(): array {
  $permissions = array_fill_keys(array_keys(function_exists('ua_permission_catalog') ? ua_permission_catalog() : []), true);
  return ['all' => true] + $permissions + [

    // ✅ مهم: زر فصل/استعادة PPPoE
    'can_pppoe_cut_restore' => true,

    'can_manage_roles'     => true,
    'can_manage_admins'    => true,

    'can_maintenance'      => true,
    'can_manage_messages'  => true,
    'can_manage_sales'     => true,
    'can_manage_purchases' => true,
    'can_manage_agents'    => true,
    'can_view_agents'      => true,
    'can_edit_agents'      => true,
    'can_view_agent_log'   => true,
    'can_manage_agent_balances' => true,
    'can_cleanup_files'    => true,
    'can_reset_operational'=> true,
    'can_factory_reset'    => true,

    'can_view_invoices'    => true,
    'can_add_invoices'     => true,
    'can_pay_invoices'     => true,
    'can_delete_invoices'  => true,

    'can_view_subscribers' => true,
    'can_add_subscriber'   => true,
    'can_edit_subscriber'  => true,
    'can_delete_subscriber'=> true,
    'can_suspend_subscriber'=> true,
    'can_activate_subscriber'=> true,

    'can_mikrotik_sync'    => true,
    'can_manage_speed'     => true,
    'can_view_reports'     => true,
  ];
}

function is_bypass_admin(?string $username): bool {
  if (!empty($_SESSION['admin_id']) && (int)$_SESSION['admin_id'] === 1) return true;

  $username = trim((string)$username);
  if ($username === '') return false;
  $list = $GLOBALS['BYPASS_ADMINS'] ?? ['admin'];
  foreach ($list as $u) {
    if (strcasecmp(trim((string)$u), $username) === 0) return true;
  }
  return false;
}

function has_perm(string $key): bool {
  if (is_bypass_admin($_SESSION['admin_user'] ?? ($_SESSION['admin_username'] ?? ''))) {
    return true;
  }
  $permissions = is_array($_SESSION['perms'] ?? null) ? $_SESSION['perms'] : [];
  if (function_exists('ua_permission_array_has')) {
    return ua_permission_array_has($permissions, $key);
  }
  return !empty($permissions['all']) || !empty($permissions['ALL']) || !empty($permissions[$key]);
}

/** ✅ معدلة: للـ API رجّع JSON بدل die نصي */
function require_perm(string $key): void {
  if (!has_perm($key)) {
    http_response_code(403);

    if (auth_is_api_request()) {
      header('Content-Type: application/json; charset=utf-8');
      echo json_encode([
        'ok' => false,
        'error' => 'PERMISSION_DENIED',
        'perm' => $key,
        'message' => 'لا تملك صلاحية الوصول'
      ], JSON_UNESCAPED_UNICODE);
      exit;
    }

    die("403 - لا تملك صلاحية الوصول");
  }
}

if (!function_exists('require_any_perm')) {
  function require_any_perm(array $keys): void {
    foreach ($keys as $k) {
      if (has_perm($k)) return;
    }
    http_response_code(403);

    if (auth_is_api_request()) {
      header('Content-Type: application/json; charset=utf-8');
      echo json_encode([
        'ok' => false,
        'error' => 'PERMISSION_DENIED',
        'perms' => array_values($keys),
        'message' => 'لا تملك صلاحية الوصول'
      ], JSON_UNESCAPED_UNICODE);
      exit;
    }

    die("403 - لا تملك صلاحية الوصول");
  }
}

/* =========================
   تحميل صلاحيات الدور
========================= */
function load_admin_perms(mysqli $conn, int $admin_id): array {
  $admin_id = (int)$admin_id;

  try {
    $col = $conn->query("SHOW COLUMNS FROM admin_users LIKE 'permissions'");
    if ($col && $col->num_rows) {
      $q = $conn->query("SELECT permissions FROM admin_users WHERE id=$admin_id LIMIT 1");
      if ($q && $q->num_rows) {
        $p = (string)($q->fetch_assoc()['permissions'] ?? '');
        $arr = json_decode($p, true);
        return is_array($arr) ? $arr : [];
      }
      return [];
    }
  } catch (Throwable $e) {}

  $sql = "
    SELECT r.permissions
    FROM admin_users u
    LEFT JOIN admin_roles r ON u.role_id = r.id
    WHERE u.id = $admin_id
    LIMIT 1
  ";
  $q = $conn->query($sql);
  if(!$q || !$q->num_rows) return [];

  $p = $q->fetch_assoc()['permissions'] ?? '';
  $arr = json_decode($p, true);
  return is_array($arr) ? $arr : [];
}

function auth_refresh_session_perms(mysqli $conn): void {
  $aid = (int)($_SESSION['admin_id'] ?? 0);
  $_SESSION['perms'] = ($aid > 0) ? load_admin_perms($conn, $aid) : [];
}

/* =========================
   تحقق كلمة المرور
========================= */
function verify_any_password(string $input, string $stored): bool {
  if ($stored === '') return false;

  if (strpos($stored, '$2y$') === 0 || strpos($stored, '$argon2') === 0) {
    return function_exists('password_verify') ? password_verify($input, $stored) : false;
  }

  if ($stored === $input) return true;
  if ($stored === md5($input)) return true;
  if ($stored === sha1($input)) return true;
  if ($stored === hash('sha256', $input)) return true;

  return false;
}

/* =========================
   تسجيل الدخول
========================= */
function login_admin(mysqli $conn, string $username, string $password): bool {
  ensure_auth_tables($conn);

  $u = trim($username);
  $p = (string)$password;
  if ($u === '' || $p === '') return false;

  $u_esc = $conn->real_escape_string($u);
  $sql = "SELECT * FROM admin_users WHERE username='$u_esc' LIMIT 1";
  $q = $conn->query($sql);
  if(!$q || !$q->num_rows) return false;

  $row = $q->fetch_assoc();

  $active = (int)($row['is_active'] ?? 1);
  if ($active !== 1) return false;

  $plain = (string)($row['password'] ?? '');
  $hash  = (string)($row['password_hash'] ?? '');

  $ok = false;
  if ($hash !== '') $ok = verify_any_password($p, $hash);
  if (!$ok && $plain !== '') $ok = verify_any_password($p, $plain);
  if (!$ok) return false;

  if (function_exists('session_regenerate_id')) { @session_regenerate_id(true); }
  $_SESSION['ua_last_regen'] = time();

  $id = (int)($row['id'] ?? 0);
  $display = (string)($row['full_name'] ?? $row['username'] ?? 'admin');

  $_SESSION['admin_id'] = $id;
  $_SESSION['admin_username'] = $display;

  $_SESSION['admin_user'] = (string)($row['username'] ?? 'admin');
  $_SESSION['admin_user_id'] = $id;
  if (!empty($row['avatar_path'])) {
    $_SESSION['admin_avatar'] = (string)$row['avatar_path'];
  } else {
    unset($_SESSION['admin_avatar']);
  }

  if (is_bypass_admin($_SESSION['admin_user'])) {
    $_SESSION['perms'] = super_admin_perms();
  } else {
    $_SESSION['perms'] = load_admin_perms($conn, $id);
  }

  return true;
}

/* =========================
   تسجيل الخروج
========================= */

function auth_force_logout_response(bool $api = false, string $redirect = "login.php"): void {
  logout_admin();
  if ($api) {
    if (!headers_sent()) {
      http_response_code(401);
      header('Content-Type: application/json; charset=utf-8');
    }
    echo json_encode([
      'ok' => false,
      'error' => 'SUPER_ADMIN_LOCKED',
      'force_logout' => true,
      'redirect' => $redirect,
      'message' => 'تم تجاوز عدد المحاولات المسموح. تم تسجيل الخروج.'
    ], JSON_UNESCAPED_UNICODE);
    exit;
  }
  header('Location: ' . $redirect);
  exit;
}

function logout_admin(): void {
  $_SESSION = [];
  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_destroy();
}
