<?php

function sanitize($input)
{
    if (is_array($input)) {
        return array_map('sanitize', $input);
    }
    return htmlspecialchars(trim($input), ENT_QUOTES, 'UTF-8');
}

function redirect($url)
{
    if (strpos($url, 'http://') === 0 || strpos($url, 'https://') === 0) {
        header('Location: ' . $url);
    } else {
        header('Location: ' . APP_URL . '/' . ltrim($url, '/'));
    }
    exit;
}

function jsonResponse($success, $message, $data = [], $statusCode = 200)
{
    http_response_code($statusCode);
    header('Content-Type: application/json; charset=utf-8');
    echo json_encode(array_merge([
        'success' => $success,
        'message' => $message,
    ], $data));
    exit;
}

function formatCurrency($amount, $currency = 'LKR')
{
    $symbols = [
        'LKR' => 'Rs.',
        'USD' => '$',
        'EUR' => "\xE2\x82\xAC",
        'GBP' => "\xC2\xA3",
        'INR' => "\xE2\x82\xB9",
    ];
    $symbol = $symbols[$currency] ?? $currency . ' ';
    return $symbol . number_format((float) $amount, 2, '.', ',');
}

function timeAgo($datetime)
{
    $now = new DateTime();
    $ago = new DateTime($datetime);
    $diff = $now->diff($ago);

    if ($diff->y > 0) {
        return $diff->y . ' year' . ($diff->y > 1 ? 's' : '') . ' ago';
    }
    if ($diff->m > 0) {
        return $diff->m . ' month' . ($diff->m > 1 ? 's' : '') . ' ago';
    }
    if ($diff->d > 0) {
        return $diff->d . ' day' . ($diff->d > 1 ? 's' : '') . ' ago';
    }
    if ($diff->h > 0) {
        return $diff->h . ' hour' . ($diff->h > 1 ? 's' : '') . ' ago';
    }
    if ($diff->i > 0) {
        return $diff->i . ' minute' . ($diff->i > 1 ? 's' : '') . ' ago';
    }
    return 'just now';
}

function slugify($text)
{
    $text = preg_replace('~[^\pL\d]+~u', '-', $text);
    $text = preg_replace('~[^-\w]+~', '', $text);
    $text = trim($text, '-');
    $text = preg_replace('~-+~', '-', $text);
    $text = strtolower($text);
    return $text ?: 'n-a';
}

function generateCode($length = 6)
{
    $characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
    $code = '';
    $max = strlen($characters) - 1;
    for ($i = 0; $i < $length; $i++) {
        $code .= $characters[random_int(0, $max)];
    }
    return $code;
}

function isInstalled()
{
    return file_exists(BASE_PATH . DIRECTORY_SEPARATOR . 'install' . DIRECTORY_SEPARATOR . 'installed.lock');
}

function getBaseUrl()
{
    if (defined('APP_URL')) {
        return APP_URL;
    }
    $protocol = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on') ? 'https' : 'http';
    $host = $_SERVER['HTTP_HOST'] ?? 'localhost';
    return $protocol . '://' . $host;
}

function formatDate($date, $format = 'Y-m-d')
{
    if (empty($date)) {
        return '';
    }
    try {
        $dt = new DateTime($date);
        return $dt->format($format);
    } catch (Exception $e) {
        return $date;
    }
}

function formatDateTime($datetime)
{
    return formatDate($datetime, 'Y-m-d H:i:s');
}

function getDeviceType()
{
    $userAgent = $_SERVER['HTTP_USER_AGENT'] ?? '';
    if (preg_match('/tablet|ipad/i', $userAgent)) {
        return 'tablet';
    }
    if (preg_match('/mobile|android|iphone|ipod|blackberry|opera mini|iemobile/i', $userAgent)) {
        return 'mobile';
    }
    return 'desktop';
}

function getOperatingHours($settings)
{
    $dayOfWeek = (int) date('w');
    $days = ['sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday'];
    $today = $days[$dayOfWeek];

    $openKey = $today . '_open';
    $closeKey = $today . '_close';

    $openTime = $settings[$openKey] ?? null;
    $closeTime = $settings[$closeKey] ?? null;

    if (empty($openTime) || empty($closeTime)) {
        return ['is_open' => false, 'message' => 'Operating hours not set for today.'];
    }

    $now = new DateTime('now');
    $open = DateTime::createFromFormat('H:i:s', $openTime);
    $close = DateTime::createFromFormat('H:i:s', $closeTime);

    if (!$open || !$close) {
        return ['is_open' => false, 'message' => 'Invalid operating hours.'];
    }

    if ($now >= $open && $now <= $close) {
        return [
            'is_open'   => true,
            'message'   => 'Open now',
            'open_time' => $open->format('g:i A'),
            'close_time' => $close->format('g:i A'),
        ];
    }

    return [
        'is_open'   => false,
        'message'   => 'Currently closed',
        'open_time' => $open->format('g:i A'),
        'close_time' => $close->format('g:i A'),
    ];
}

function truncate($text, $length = 100)
{
    if (strlen($text) <= $length) {
        return $text;
    }
    return substr($text, 0, $length) . '...';
}

function getOrdinalSuffix($number)
{
    $number = (int) $number;
    if (($number % 100) >= 11 && ($number % 100) <= 13) {
        return $number . 'th';
    }
    switch ($number % 10) {
        case 1:
            return $number . 'st';
        case 2:
            return $number . 'nd';
        case 3:
            return $number . 'rd';
        default:
            return $number . 'th';
    }
}
