<?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_login_url')) { function ah_login_url(): string { return '/login/index.php'; } }
if (!function_exists('ah_admin_dashboard_url')) { function ah_admin_dashboard_url(): string { return '/admin/dashboard.php'; } }
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';
    $candidates[] = __DIR__ . '/../data/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_record_value')) {
  function ah_record_value(array $row, array $keys, $default = null) {
    foreach ($keys as $key) {
      if (array_key_exists($key, $row) && $row[$key] !== null && $row[$key] !== '') return $row[$key];
    }
    return $default;
  }
}
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_discover_admin_pages')) {
  function ah_discover_admin_pages(): array {
    $skip = ['auth','login','logout','index','dashboard','delete_dj','delete_friend','save_djs','save_friends'];
    $pages = [];
    foreach ((array)glob(__DIR__ . '/../admin/*.php') as $file) {
      $slug = basename((string)$file, '.php');
      if (in_array($slug, $skip, true)) continue;
      $pages[$slug] = ucwords(str_replace(['-','_'], ' ', $slug));
    }
    ksort($pages);
    return $pages;
  }
}
if (!function_exists('ah_permission_map')) { function ah_permission_map(): array { return ah_discover_admin_pages(); } }
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 {
    $username = trim((string)ah_record_value($user, ['username','user','name','login'], ''));
    $password = (string)ah_record_value($user, ['password','password_hash','hash','pass','passwd'], '');
    $role = strtolower(trim((string)ah_record_value($user, ['role','group','access_role','access','type'], 'viewer')));
    if ($role === 'dj') $role = 'viewer';
    if (!in_array($role, ['master','admin','viewer'], true)) $role = 'viewer';
    $rawPerms = ah_record_value($user, ['permissions','permission','perms','pages'], []);
    $normalized = [];
    if (is_array($rawPerms)) {
      foreach ($rawPerms as $perm => $level) {
        $key = ah_normalize_permission_key(is_int($perm) ? (string)$level : (string)$perm);
        if (!in_array($key, ah_permission_keys(), true)) continue;
        if (is_int($perm)) {
          $normalized[$key] = 'view';
        } elseif (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', preg_split('/[,|]/', $rawPerms)) as $perm) {
        $key = ah_normalize_permission_key($perm);
        if (in_array($key, ah_permission_keys(), true)) $normalized[$key] = 'view';
      }
    }
    return [
      'username' => $username,
      'password' => $password,
      'role' => $role,
      'permissions' => $normalized,
      '_source' => $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['accounts'] ?? $decoded['staff'] ?? $decoded;
        if (is_array($rows) && $rows) {
          $out = [];
          foreach ($rows as $row) {
            if (is_array($row)) $out[] = ah_normalize_user_record($row);
          }
          if ($out) return array_values($out);
        }
      }
    }
    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(array_map(function($u){
      if (!is_array($u)) return [];
      return [
        'username' => $u['username'] ?? '',
        'password' => $u['password'] ?? '',
        'role' => $u['role'] ?? 'viewer',
        'permissions' => $u['permissions'] ?? [],
      ];
    }, $users))];
    return @file_put_contents($usersFile, json_encode($payload, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES)) !== false;
  }
}
if (!function_exists('ah_user_can_access_page')) { function ah_user_can_access_page(string $role, array $permissions, string $page): bool { return in_array($role, ['master','admin','viewer'], true); } }
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; } }
