<?php
function ht_array_is_list_compat(array $arr): bool {
  if (function_exists('array_is_list')) return array_is_list($arr);
  $i = 0;
  foreach ($arr as $k => $_) { if ($k !== $i++) return false; }
  return true;
}

function ht_asset_url(string $path, string $fallbackDir = 'img/content'): string {
  $path = trim(str_replace('\\', '/', $path));
  if ($path === '') return '';
  if (preg_match('#^(https?:)?//#i', $path) || str_starts_with($path, 'data:')) return $path;
  if (str_starts_with($path, '/')) return $path;
  if (preg_match('#^(img|uploads|assets|api|data)/#i', $path)) return '/' . ltrim($path, '/');
  $fallbackDir = trim(str_replace('\\', '/', $fallbackDir), '/');
  return '/' . ($fallbackDir !== '' ? $fallbackDir . '/' : '') . ltrim($path, '/');
}

function ht_news_defaults(): array {
  return [
    'title' => '',
    'author' => 'Admin',
    'date' => '',
    'tag' => '',
    'content' => '',
    'body' => '',
    'image' => '',
    'published' => 1,
    'featured_home' => 0,
    'source_file' => '',
    '_mtime' => 0,
  ];
}

function ht_event_defaults(): array {
  return [
    'title' => '',
    'start' => '',
    'end' => '',
    'description' => '',
    'image' => '',
    'published' => 1,
    'featured_home' => 0,
    'show_entry_form' => 1,
    'show_external_link' => 0,
    'external_url' => '',
    'external_label' => 'Open External Events Site',
    'prizes' => [],
    'source_file' => '',
    '_mtime' => 0,
  ];
}

function ht_normalize_news_item(array $item, string $sourceFile = '', int $mtime = 0): array {
  $n = array_merge(ht_news_defaults(), $item);
  $n['title'] = trim((string)($item['title'] ?? $n['title']));
  $n['author'] = trim((string)($item['author'] ?? $n['author']));
  $n['date'] = trim((string)($item['date'] ?? $item['timestamp'] ?? $n['date']));
  $n['tag'] = trim((string)($item['tag'] ?? ''));
  $n['content'] = trim((string)($item['content'] ?? $item['body'] ?? ''));
  $n['body'] = $n['content'];
  $n['image'] = trim((string)($item['image'] ?? $item['image_url'] ?? ''));
  $n['published'] = array_key_exists('published', $item) ? (!empty($item['published']) ? 1 : 0) : 1;
  $n['featured_home'] = array_key_exists('featured_home', $item) ? (!empty($item['featured_home']) ? 1 : 0) : (!empty($item['featured']) ? 1 : 0);
  $n['source_file'] = $sourceFile !== '' ? $sourceFile : (string)($item['source_file'] ?? '');
  $n['_mtime'] = $mtime;
  return $n;
}

function ht_normalize_event_item(array $item, string $sourceFile = '', int $mtime = 0): array {
  $e = array_merge(ht_event_defaults(), $item);
  $e['title'] = trim((string)($item['title'] ?? $e['title']));
  $e['start'] = trim((string)($item['start'] ?? ''));
  $e['end'] = trim((string)($item['end'] ?? ''));
  $e['description'] = trim((string)($item['description'] ?? $item['body'] ?? ''));
  $e['image'] = trim((string)($item['image'] ?? $item['image_url'] ?? ''));
  $e['published'] = array_key_exists('published', $item) ? (!empty($item['published']) ? 1 : 0) : (!empty($item['enabled']) ? 1 : 0);
  $e['featured_home'] = array_key_exists('featured_home', $item) ? (!empty($item['featured_home']) ? 1 : 0) : (!empty($item['pinned']) ? 1 : 0);
  $e['show_entry_form'] = array_key_exists('show_entry_form', $item) ? (!empty($item['show_entry_form']) ? 1 : 0) : 1;
  $e['show_external_link'] = array_key_exists('show_external_link', $item) ? (!empty($item['show_external_link']) ? 1 : 0) : 0;
  $e['external_url'] = trim((string)($item['external_url'] ?? ''));
  $e['external_label'] = trim((string)($item['external_label'] ?? 'Open External Events Site'));
  $e['prizes'] = array_values(array_filter(array_map('trim', (array)($item['prizes'] ?? []))));
  $e['source_file'] = $sourceFile !== '' ? $sourceFile : (string)($item['source_file'] ?? '');
  $e['_mtime'] = $mtime;
  return $e;
}

function ht_sort_items(array &$items, string $dateKey = 'date'): void {
  usort($items, function($a, $b) use ($dateKey) {
    $at = 0; $bt = 0;
    if (!empty($a[$dateKey])) $at = strtotime((string)$a[$dateKey]) ?: 0;
    if (!empty($b[$dateKey])) $bt = strtotime((string)$b[$dateKey]) ?: 0;
    if ($at !== $bt) return $bt <=> $at;
    return ((int)($b['_mtime'] ?? 0)) <=> ((int)($a['_mtime'] ?? 0));
  });
}

function ht_load_news_items(string $baseDir): array {
  $items = [];
  $newsDir = rtrim($baseDir, '/\\') . '/data/news/';
  $newsIndexFile = rtrim($baseDir, '/\\') . '/data/news.json';
  if (is_dir($newsDir)) {
    $files = glob($newsDir . '*.json') ?: [];
    foreach ($files as $path) {
      $raw = json_decode((string)file_get_contents($path), true);
      if (!is_array($raw)) continue;
      $items[] = ht_normalize_news_item($raw, basename($path), (int)@filemtime($path));
    }
  }
  if (!$items && file_exists($newsIndexFile)) {
    $raw = json_decode((string)file_get_contents($newsIndexFile), true);
    if (is_array($raw)) {
      if (ht_array_is_list_compat($raw)) {
        foreach ($raw as $entry) {
          if (is_array($entry)) $items[] = ht_normalize_news_item($entry, (string)($entry['source_file'] ?? ''), 0);
        }
      } else {
        $items[] = ht_normalize_news_item($raw, (string)($raw['source_file'] ?? ''), 0);
      }
    }
  }
  ht_sort_items($items, 'date');
  return $items;
}

function ht_load_event_items(string $baseDir): array {
  $items = [];
  $eventsDir = rtrim($baseDir, '/\\') . '/data/events/';
  $eventsIndexFile = rtrim($baseDir, '/\\') . '/data/events.json';
  $promoFile = rtrim($baseDir, '/\\') . '/data/promo.json';
  if (is_dir($eventsDir)) {
    $files = glob($eventsDir . '*.json') ?: [];
    foreach ($files as $path) {
      $raw = json_decode((string)file_get_contents($path), true);
      if (!is_array($raw)) continue;
      $items[] = ht_normalize_event_item($raw, basename($path), (int)@filemtime($path));
    }
  }
  if (!$items && file_exists($eventsIndexFile)) {
    $raw = json_decode((string)file_get_contents($eventsIndexFile), true);
    if (is_array($raw)) {
      if (ht_array_is_list_compat($raw)) {
        foreach ($raw as $entry) {
          if (is_array($entry)) $items[] = ht_normalize_event_item($entry, (string)($entry['source_file'] ?? ''), 0);
        }
      } else {
        $items[] = ht_normalize_event_item($raw, (string)($raw['source_file'] ?? ''), 0);
      }
    }
  }
  if (!$items && file_exists($promoFile)) {
    $promo = json_decode((string)file_get_contents($promoFile), true);
    if (is_array($promo) && (trim((string)($promo['title'] ?? '')) !== '' || !empty($promo['enabled']) || !empty($promo['description']) || !empty($promo['image']))) $items[] = ht_normalize_event_item($promo, 'promo.json', (int)@filemtime($promoFile));
  }
  ht_sort_items($items, 'start');
  return $items;
}

function ht_migrate_legacy_news_to_files(string $baseDir): void {
  $newsDir = rtrim($baseDir, '/\\') . '/data/news/';
  $newsIndexFile = rtrim($baseDir, '/\\') . '/data/news.json';
  if (!is_dir($newsDir)) @mkdir($newsDir, 0777, true);
  $existing = glob($newsDir . '*.json') ?: [];
  if ($existing || !file_exists($newsIndexFile)) return;
  $raw = json_decode((string)file_get_contents($newsIndexFile), true);
  if (!is_array($raw)) return;
  $items = ht_array_is_list_compat($raw) ? $raw : [$raw];
  $i = 1;
  foreach ($items as $entry) {
    if (!is_array($entry)) continue;
    $n = ht_normalize_news_item($entry);
    $slug = preg_replace('/[^a-z0-9]+/i', '-', strtolower((string)$n['title']));
    $slug = trim((string)$slug, '-') ?: ('post-' . $i);
    $name = sprintf('migrated_%03d_%s.json', $i++, $slug);
    file_put_contents($newsDir . $name, json_encode($n, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) . "\n");
  }
}

function ht_migrate_legacy_events_to_files(string $baseDir): void {
  $eventsDir = rtrim($baseDir, '/\\') . '/data/events/';
  $eventsIndexFile = rtrim($baseDir, '/\\') . '/data/events.json';
  $promoFile = rtrim($baseDir, '/\\') . '/data/promo.json';
  if (!is_dir($eventsDir)) @mkdir($eventsDir, 0777, true);
  $existing = glob($eventsDir . '*.json') ?: [];
  if ($existing) return;
  $items = [];
  if (file_exists($eventsIndexFile)) {
    $raw = json_decode((string)file_get_contents($eventsIndexFile), true);
    if (is_array($raw)) $items = ht_array_is_list_compat($raw) ? $raw : [$raw];
  }
  if (!$items && file_exists($promoFile)) {
    $raw = json_decode((string)file_get_contents($promoFile), true);
    if (is_array($raw) && (trim((string)($raw['title'] ?? '')) !== '' || !empty($raw['enabled']) || !empty($raw['description']) || !empty($raw['image']))) $items = [$raw];
  }
  if (!$items) return;
  $i = 1;
  foreach ($items as $entry) {
    if (!is_array($entry)) continue;
    $e = ht_normalize_event_item($entry);
    $slug = preg_replace('/[^a-z0-9]+/i', '-', strtolower((string)$e['title']));
    $slug = trim((string)$slug, '-') ?: ('event-' . $i);
    $name = sprintf('migrated_%03d_%s.json', $i++, $slug);
    file_put_contents($eventsDir . $name, json_encode($e, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) . "\n");
  }
}
