<?php
declare(strict_types=1);

// ------- Config -------
const DATA_FILE   = __DIR__ . '/erp_data.json';
const BACKUP_DIR  = __DIR__ . '/backups';
const FORCE_SAVE_HEADER = 'X-ERP-Force-Save';   // optional belt & suspenders
const API_KEY_HEADER    = 'X-ERP-Key';
const EXPECTED_API_KEY  = 'bellwether-local';   // keep in sync with index.html

// ------- CORS / Preflight (same-origin is OK; CORS kept permissive for safety) -------
$origin = $_SERVER['HTTP_ORIGIN'] ?? '';
header('Vary: Origin');
header('Access-Control-Allow-Origin: ' . ($origin ?: '*'));
header('Access-Control-Allow-Credentials: true');
header('Access-Control-Allow-Headers: Content-Type, ' . API_KEY_HEADER . ', ' . FORCE_SAVE_HEADER);
header('Access-Control-Allow-Methods: GET, POST, OPTIONS');
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
  http_response_code(204);
  exit;
}
header('Content-Type: application/json; charset=utf-8');

// ------- Helpers -------
function read_json_file(string $path): array {
  if (!file_exists($path)) return ['tasks'=>[], 'clients'=>[], 'users'=>[]];
  $raw = @file_get_contents($path);
  if ($raw === false) return ['tasks'=>[], 'clients'=>[], 'users'=>[]];
  $data = json_decode($raw, true);
  return is_array($data) ? $data : ['tasks'=>[], 'clients'=>[], 'users'=>[]];
}
function write_json_atomic(string $path, array $data): bool {
  $tmp = $path . '.tmp';
  $json = json_encode($data, JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES);
  if ($json === false) return false;

  $fp = @fopen($tmp, 'wb');
  if (!$fp) return false;
  if (!flock($fp, LOCK_EX)) { fclose($fp); @unlink($tmp); return false; }
  fwrite($fp, $json);
  fflush($fp);
  flock($fp, LOCK_UN);
  fclose($fp);
  return @rename($tmp, $path);
}
function backup_snapshot(string $path): void {
  if (!file_exists($path)) return;
  if (!is_dir(BACKUP_DIR)) @mkdir(BACKUP_DIR, 0755, true);
  $ts = date('Ymd_His');
  @copy($path, BACKUP_DIR . "/erp_data_{$ts}.json");
}
function get_header_value(string $name): ?string {
  $key = 'HTTP_' . strtoupper(str_replace('-', '_', $name));
  return $_SERVER[$key] ?? null;
}

// ------- Auth (soft) -------
$providedKey = get_header_value(API_KEY_HEADER);
if ($providedKey !== null && $providedKey !== EXPECTED_API_KEY) {
  http_response_code(401);
  echo json_encode(['error'=>'invalid_api_key']);
  exit;
}

// ------- Routing -------
$method = $_SERVER['REQUEST_METHOD'] ?? 'GET';
$op = $_GET['op'] ?? $_POST['op'] ?? '';

if ($op === 'load') {
  // allow GET or POST -> never 405
  $data = read_json_file(DATA_FILE);
  http_response_code(200);
  echo json_encode($data, JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES);
  exit;
}

if ($op === 'save' && $method === 'POST') {
  $raw = file_get_contents('php://input') ?: '';
  $payload = json_decode($raw, true);
  if (!is_array($payload)) {
    http_response_code(400);
    echo json_encode(['error'=>'invalid_json']);
    exit;
  }

  // Hard guard: ignore accidental wipes unless forced
  $tasks   = isset($payload['tasks'])   && is_array($payload['tasks'])   ? $payload['tasks']   : [];
  $clients = isset($payload['clients']) && is_array($payload['clients']) ? $payload['clients'] : [];
  $users   = isset($payload['users'])   && is_array($payload['users'])   ? $payload['users']   : [];

  $nonEmpty = (count($tasks) + count($clients)) > 0;
  $force = get_header_value(FORCE_SAVE_HEADER);

  if (!$nonEmpty && !$force) {
    // ignore empty save
    $current = read_json_file(DATA_FILE);
    http_response_code(200);
    echo json_encode(['status'=>'ignored_empty_save','data'=>$current]);
    exit;
  }

  // make backup then write
  backup_snapshot(DATA_FILE);
  $ok = write_json_atomic(DATA_FILE, ['tasks'=>$tasks,'clients'=>$clients,'users'=>$users]);
  if (!$ok) {
    http_response_code(500);
    echo json_encode(['error'=>'write_failed']);
    exit;
  }
  http_response_code(200);
  echo json_encode(['status'=>'ok','counts'=>['tasks'=>count($tasks),'clients'=>count($clients),'users'=>count($users)]]);
  exit;
}

// Unknown route / wrong method
http_response_code(400);
echo json_encode(['error'=>'bad_request','hint'=>'use ?op=load (GET/POST) or ?op=save (POST)']);
