<?php
declare(strict_types=1);

// Start session for admin pages
if (session_status() === PHP_SESSION_NONE) {
    session_start();
}

// Use Cairo timezone across PHP
date_default_timezone_set('Africa/Cairo');

// Database configuration - adjust as needed or set as environment variables
$DB_HOST = getenv('DB_HOST') ?: 'localhost';
$DB_PORT = getenv('DB_PORT') ?: '3306';
$DB_NAME = getenv('DB_NAME') ?: 'tempduzq_dallah';
$DB_USER = getenv('DB_USER') ?: 'tempduzq_dallah';
$DB_PASS = getenv('DB_PASS') ?: 'L?g[]Nx.8lmK';
$DB_CHARSET = 'utf8mb4';

/**
 * Get a shared PDO instance (singleton per request)
 */
function pdo(): PDO {
    static $pdo = null;
    if ($pdo instanceof PDO) {
        return $pdo;
    }

    $host = $GLOBALS['DB_HOST'];
    $port = $GLOBALS['DB_PORT'];
    $db   = $GLOBALS['DB_NAME'];
    $user = $GLOBALS['DB_USER'];
    $pass = $GLOBALS['DB_PASS'];
    $charset = $GLOBALS['DB_CHARSET'];

    $dsn = "mysql:host={$host};port={$port};dbname={$db};charset={$charset}";
    $options = [
        PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
        PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
        PDO::ATTR_EMULATE_PREPARES   => false,
    ];
    $pdo = new PDO($dsn, $user, $pass, $options);

    // Attempt to set MySQL session time_zone to Cairo; fallback to PHP offset if named timezone is unavailable
    try {
        $pdo->exec("SET time_zone = 'Africa/Cairo'");
    } catch (Throwable $e) {
        $offset = date('P'); // e.g. +02:00 or +03:00 depending on DST
        try { $pdo->exec("SET time_zone = '" . $offset . "'"); } catch (Throwable $e2) { /* ignore */ }
    }
    return $pdo;
}

/**
 * Send a JSON response and exit
 */
function json_response(array $data, int $statusCode = 200): void {
    // Clear any previous output (warnings/notices) captured in buffers to keep JSON clean
    try {
        while (function_exists('ob_get_level') && ob_get_level() > 0) {
            ob_end_clean();
        }
    } catch (Throwable $e) { /* ignore */ }
    http_response_code($statusCode);
    header('Content-Type: application/json; charset=utf-8');
    header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
    echo json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
    exit;
}

/**
 * Read input data from JSON body or form data; supports GET as well.
 */
function get_input(): array {
    $data = $_POST ?? [];
    $contentType = $_SERVER['CONTENT_TYPE'] ?? '';

    if (stripos($contentType, 'application/json') !== false) {
        $raw = file_get_contents('php://input');
        if ($raw !== false && $raw !== '') {
            $json = json_decode($raw, true);
            if (is_array($json)) {
                $data = array_merge($data, $json);
            }
        }
    }

    if (($_SERVER['REQUEST_METHOD'] ?? '') === 'GET' && !empty($_GET)) {
        $data = array_merge($data, $_GET);
    }

    return $data;
}

/** Ensure HTTP method matches */
function require_method(string $method): void {
    if (strcasecmp($_SERVER['REQUEST_METHOD'] ?? '', $method) !== 0) {
        json_response(['error' => 'Method Not Allowed', 'allowed' => $method], 405);
    }
}

/** Ensure required fields are present and not empty */
function require_fields(array $data, array $fields): void {
    $missing = [];
    foreach ($fields as $f) {
        if (!array_key_exists($f, $data)) {
            $missing[] = $f;
            continue;
        }

        $value = $data[$f];
        if (is_string($value)) {
            $value = trim($value);
        }

        if ($value === '' || $value === null) {
            $missing[] = $f;
        }
    }

    if ($missing) {
        json_response(['error' => 'Validation failed', 'missing' => $missing], 422);
    }
}

/** Basic phone number validation */
function validate_phone(string $phone): bool {
    return (bool)preg_match('/^\+?[0-9]{7,15}$/', $phone);
}

/** Ensure service date matches YYYY-MM-DD */
function validate_service_date(string $date): bool {
    $date = trim($date);
    if ($date === '') {
        return false;
    }
    $dt = DateTime::createFromFormat('Y-m-d', $date);
    return $dt instanceof DateTime && $dt->format('Y-m-d') === $date;
}

/** Convenience helper for trimming strings */
function clean_string(null|string $value): string {
    return trim((string)$value);
}

/** Current timestamp helper */
function now(): string {
    return date('Y-m-d H:i:s');
}

/** Require admin session for protected endpoints (returns 401 JSON) */
function require_admin(): void {
    if (empty($_SESSION['admin_id'])) {
        json_response(['error' => 'Unauthorized'], 401);
    }
}
