<?php
if (!function_exists('ah_station_slug')) { function ah_station_slug(): string { return 'almostheaven'; } }
if (!function_exists('ah_auth_config_path')) { function ah_auth_config_path(): string { return 'C:/inetpub/Authentication/' . ah_station_slug() . '/auth_config.php'; } }
if (!function_exists('ah_api_config_path')) { function ah_api_config_path(): string { return 'C:/inetpub/Authentication/api/' . ah_station_slug() . '.php'; } }
if (!function_exists('ah_local_users_file')) { function ah_local_users_file(): string { return __DIR__ . '/../admin/users.txt'; } }
if (!function_exists('ah_load_auth_config')) {
  function ah_load_auth_config(): array {
    $path = ah_auth_config_path();
    if (!is_file($path)) return [];
    $cfg = @include $path;
    return is_array($cfg) ? $cfg : [];
  }
}
if (!function_exists('ah_resolve_users_file')) {
  function ah_resolve_users_file(): string {
    $cfg = ah_load_auth_config();
    $candidates = [];
    foreach (['users_file','users_path','auth_users_file'] as $key) {
      if (!empty($cfg[$key]) && is_string($cfg[$key])) $candidates[] = $cfg[$key];
    }
    $candidates[] = 'C:/inetpub/Authentication/' . ah_station_slug() . '/users.json';
    foreach ($candidates as $candidate) {
      $candidate = str_replace('\\', '/', (string)$candidate);
      if ($candidate !== '') return $candidate;
    }
    return 'C:/inetpub/Authentication/' . ah_station_slug() . '/users.json';
  }
}
if (!function_exists('ah_verify_password')) {
  function ah_verify_password(string $inputPassword, $storedPassword): bool {
    if (!is_string($storedPassword) || $storedPassword === '') return false;
    $info = password_get_info($storedPassword);
    if (($info['algo'] ?? null) !== null && ($info['algo'] ?? 0) !== 0) return password_verify($inputPassword, $storedPassword);
    return hash_equals((string)$storedPassword, $inputPassword);
  }
}
if (!function_exists('ah_permission_map')) {
  function ah_permission_map(): array {
    return [
      'pages' => 'Page Builder','users' => 'User Manager','events' => 'Events','fans' => 'Fans','contact' => 'Contact Inbox',
      'applications' => 'Applications','chat' => 'Live Chat','requests' => 'Song Requests','about' => 'About Content',
      'schedule' => 'Schedule','media' => 'Media','news' => 'Newsreel','navigation' => 'Navigation','top50' => 'Top 50',
      'player' => 'Popout Player','poll' => 'Poll Manager','comments' => 'Comments','friends' => 'Friends','djs' => 'DJs',
      'backup' => 'Backup / Restore','radiostats' => 'Radio Stats','westats' => 'Web Stats',
    ];
  }
}
if (!function_exists('ah_page_permission_aliases')) {
  function ah_page_permission_aliases(): array {
    return ['manage_users'=>'users','users'=>'users','admin_about'=>'about','about'=>'about','Schedule_update'=>'schedule','schedule'=>'schedule','newsreel_admin'=>'news','news'=>'news','player'=>'player','top50'=>'top50','manage_poll'=>'poll','poll'=>'poll','manage_comments'=>'comments','comments'=>'comments','manage_djs'=>'djs','djs'=>'djs','manage_friends'=>'friends','friends'=>'friends','hosting_tools'=>'westats','westats'=>'westats','radiostats'=>'radiostats','icecast_backup'=>'backup','backup'=>'backup','navigation'=>'navigation','pages'=>'pages','events'=>'events','fans'=>'fans','contact'=>'contact','applications'=>'applications','chat'=>'chat','requests'=>'requests','media'=>'media','file-finder'=>'backup','file_finder'=>'backup'];
  }
}
if (!function_exists('ah_normalize_permission_key')) {
  function ah_normalize_permission_key(string $pageOrPerm): string { $pageOrPerm = trim($pageOrPerm); $aliases = ah_page_permission_aliases(); return $aliases[$pageOrPerm] ?? $pageOrPerm; }
}
if (!function_exists('ah_permission_keys')) { function ah_permission_keys(): array { return array_keys(ah_permission_map()); } }
if (!function_exists('ah_normalize_user_record')) {
  function ah_normalize_user_record(array $user): array {
    $role = strtolower(trim((string)($user['role'] ?? 'viewer')));
    if ($role === 'dj') $role = 'viewer';
    if (!in_array($role, ['master','admin','viewer'], true)) $role = 'viewer';
    $rawPerms = $user['permissions'] ?? [];
    $normalized = [];
    if (is_array($rawPerms)) {
      foreach ($rawPerms as $perm => $level) {
        $key = ah_normalize_permission_key((string)$perm);
        if (!in_array($key, ah_permission_keys(), true)) continue;
        if (is_string($level) && $level !== '') $normalized[$key] = strtolower($level) === 'full' ? 'full' : 'view';
        elseif ($level) $normalized[$key] = 'view';
      }
    } elseif (is_string($rawPerms) && trim($rawPerms) !== '') {
      foreach (array_map('trim', explode(',', $rawPerms)) as $perm) {
        $key = ah_normalize_permission_key($perm);
        if (in_array($key, ah_permission_keys(), true)) $normalized[$key] = 'view';
      }
    }
    $user['role'] = $role; $user['permissions'] = $normalized; return $user;
  }
}
if (!function_exists('ah_load_local_users')) {
  function ah_load_local_users(): array {
    $file = ah_local_users_file();
    if (!is_file($file)) return [];
    $rows = [];
    foreach ((array)@file($file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES) as $line) {
      $parts = array_map('trim', explode('|', (string)$line));
      if (count($parts) < 3) continue;
      [$username, $password, $role] = $parts;
      $perms = $parts[3] ?? '';
      $rows[] = ah_normalize_user_record(['username'=>$username,'password'=>$password,'role'=>$role,'permissions'=>$perms]);
    }
    return $rows;
  }
}
if (!function_exists('ah_load_users')) {
  function ah_load_users(): array {
    $usersFile = ah_resolve_users_file();
    if (is_file($usersFile)) {
      $decoded = json_decode((string)@file_get_contents($usersFile), true);
      if (is_array($decoded)) {
        $rows = $decoded['users'] ?? $decoded;
        if (is_array($rows) && $rows) return array_values(array_map('ah_normalize_user_record', array_filter($rows, 'is_array')));
      }
    }
    return ah_load_local_users();
  }
}
if (!function_exists('ah_save_users')) {
  function ah_save_users(array $users): bool {
    $usersFile = ah_resolve_users_file();
    $dir = dirname($usersFile);
    if (!is_dir($dir)) @mkdir($dir, 0775, true);
    $payload = ['users' => array_values($users)];
    if (@file_put_contents($usersFile, json_encode($payload, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES)) !== false) return true;
    return false;
  }
}
if (!function_exists('ah_user_can_access_page')) { function ah_user_can_access_page(string $role, array $permissions, string $page): bool { if (in_array($role, ['master','admin'], true)) return true; $key = ah_normalize_permission_key($page); return isset($permissions[$key]); } }
if (!function_exists('ah_user_can_edit_page')) { function ah_user_can_edit_page(string $role, array $permissions, string $page): bool { if (in_array($role, ['master','admin'], true)) return true; $key = ah_normalize_permission_key($page); return isset($permissions[$key]); } }
if (!function_exists('ah_is_private_ip')) { function ah_is_private_ip(string $ip): bool { if ($ip === '' || $ip === '::1') return true; if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) { $long = ip2long($ip); $ranges = [['10.0.0.0','10.255.255.255'],['127.0.0.0','127.255.255.255'],['172.16.0.0','172.31.255.255'],['192.168.0.0','192.168.255.255']]; foreach ($ranges as [$start,$end]) { if ($long >= ip2long($start) && $long <= ip2long($end)) return true; } } return false; } }
if (!function_exists('ah_is_local_env')) { function ah_is_local_env(): bool { $serverName = strtolower((string)($_SERVER['SERVER_NAME'] ?? '')); $httpHostRaw = (string)($_SERVER['HTTP_HOST'] ?? ''); $httpHost = strtolower(preg_replace('/:\d+$/', '', $httpHostRaw)); $remoteAddr = (string)($_SERVER['REMOTE_ADDR'] ?? ''); if (in_array($serverName, ['localhost','127.0.0.1','::1'], true)) return true; if (in_array($httpHost, ['localhost','127.0.0.1','::1'], true)) return true; if ($serverName !== '' && (str_contains($serverName, '.local') || !str_contains($serverName, '.'))) return true; if ($httpHost !== '' && (str_contains($httpHost, '.local') || !str_contains($httpHost, '.'))) return true; if (ah_is_private_ip($remoteAddr)) return true; if (filter_var($serverName, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) && ah_is_private_ip($serverName)) return true; if (filter_var($httpHost, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) && ah_is_private_ip($httpHost)) return true; return false; } }
