<?php
declare(strict_types=1);

/**
 * api.php
 *
 * GET  ?file=main.json          → returns JSON data for that section
 * POST {"action":"save","file":"main.json","data":{...}} → saves and returns updated data
 *
 * All data files are stored in ./data/
 */

header('Content-Type: application/json; charset=utf-8');

$root    = __DIR__;
$dataDir = $root . DIRECTORY_SEPARATOR . 'data';

$allowed = [
  'main.json'     => 'Main',
  'general.json'  => 'General',
  'security.json' => 'Security',
  'parking.json'  => 'Parking',
  'admin.json'    => 'Admin',
  'personal.json' => 'Personal',
  'tools.json'    => 'Quick Tools',
];

/* ---- helpers ---- */

function respond(bool $ok, array $payload = [], int $code = 200): void {
  http_response_code($code);
  echo json_encode(array_merge(['ok' => $ok], $payload), JSON_UNESCAPED_SLASHES);
  exit;
}

function safe_file(string $file, array $allowed): string {
  $file = basename($file);
  if (!isset($allowed[$file])) respond(false, ['error' => 'File not allowed'], 403);
  return $file;
}

function backup_file(string $path): void {
  if (is_file($path)) {
    @copy($path, $path . '.bak-' . date('Ymd-His'));
  }
}

function normalize_payload(array $data): array {
  // grid
  if (!isset($data['grid']) || !is_array($data['grid'])) $data['grid'] = [];
  $rows = (int)($data['grid']['rows'] ?? 0);
  $cols = (int)($data['grid']['cols'] ?? 0);
  $rows = max(1, min(20, $rows ?: 1));
  $cols = max(1, min(20, $cols ?: 4));
  $data['grid'] = ['rows' => $rows, 'cols' => $cols];

  // apps
  if (!isset($data['apps']) || !is_array($data['apps'])) $data['apps'] = [];
  $apps = [];
  foreach ($data['apps'] as $a) {
    if (!is_array($a)) continue;
    $target = in_array(($a['target'] ?? '_blank'), ['_blank', '_self', '_top', '_parent'], true)
      ? $a['target']
      : '_blank';
    $apps[] = [
      'id'      => trim((string)($a['id']      ?? '')),
      'name'    => trim((string)($a['name']    ?? '')),
      'url'     => trim((string)($a['url']     ?? '')),
      'icon'    => trim((string)($a['icon']    ?? '')),
      'tint'    => trim((string)($a['tint']    ?? '')),
      'hint'    => trim((string)($a['hint']    ?? '')),
      'target'  => $target,
      'overlay' => (bool)($a['overlay'] ?? false),
    ];
  }
  $data['apps'] = $apps;
  return $data;
}

/* ---- ensure data dir ---- */
if (!is_dir($dataDir)) {
  @mkdir($dataDir, 0755, true);
}

/* ---- route ---- */
$method = $_SERVER['REQUEST_METHOD'] ?? 'GET';

/* GET — read file */
if ($method === 'GET') {
  $file = safe_file((string)($_GET['file'] ?? 'main.json'), $allowed);
  $path = $dataDir . DIRECTORY_SEPARATOR . $file;

  if (!is_file($path)) {
    respond(true, ['file' => $file, 'data' => ['grid' => ['rows' => 1, 'cols' => 4], 'apps' => []]]);
  }

  $raw = file_get_contents($path);
  if ($raw === false) respond(false, ['error' => 'Failed to read file'], 500);

  $data = json_decode($raw, true);
  if (!is_array($data)) $data = ['grid' => ['rows' => 1, 'cols' => 4], 'apps' => []];
  $data = normalize_payload($data);
  respond(true, ['file' => $file, 'data' => $data]);
}

/* POST — save file */
if ($method === 'POST') {
  $raw  = file_get_contents('php://input');
  $body = json_decode($raw ?: '', true);
  if (!is_array($body)) $body = $_POST;

  $action = (string)($body['action'] ?? '');
  if ($action !== 'save') respond(false, ['error' => 'Invalid action'], 400);

  $file = safe_file((string)($body['file'] ?? ''), $allowed);
  $path = $dataDir . DIRECTORY_SEPARATOR . $file;

  $data = $body['data'] ?? null;
  if (!is_array($data)) respond(false, ['error' => 'Invalid data'], 400);

  $data = normalize_payload($data);
  backup_file($path);

  $json = json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
  if ($json === false) respond(false, ['error' => 'JSON encode failed'], 500);

  if (file_put_contents($path, $json . "\n", LOCK_EX) === false) {
    respond(false, ['error' => 'Write failed — check folder permissions'], 500);
  }

  respond(true, ['file' => $file, 'data' => $data]);
}

respond(false, ['error' => 'Method not allowed'], 405);
