<?php

function config($key = null)
{
    static $config = null;

    if ($config === null) {
        $config = require __DIR__ . '/config.php';
    }

    if ($key === null)
        return $config;

    $keys = explode('.', $key);
    $value = $config;

    foreach ($keys as $k) {
        if (!isset($value[$k]))
            return null;
        $value = $value[$k];
    }

    return $value;
}

function getRequestData()
{
    $raw = file_get_contents('php://input');
    $json = json_decode($raw, true);

    if (!empty($json))
        return $json;
    if (!empty($_POST))
        return $_POST;
    if (!empty($_GET))
        return $_GET;

    return [];
}

function getParam($key, $default = null)
{
    static $jsonData = null;

    // cache biar gak decode berkali-kali
    if ($jsonData === null) {
        $raw = file_get_contents('php://input');
        $jsonData = json_decode($raw, true) ?? [];
    }

    // prioritas: JSON → POST → GET
    if (isset($jsonData[$key]))
        return $jsonData[$key];
    if (isset($_POST[$key]))
        return $_POST[$key];
    if (isset($_GET[$key]))
        return $_GET[$key];

    return $default;
}

function getCommonParams()
{
    return [
        "gpsAddress" => getParam('gpsAddress'),
        "gpsLat" => getParam('gpsLat'),
        "gpsLong" => getParam('gpsLong'),
        "device" => getParam('device'),
        "ipAddress" => getParam('ipAddress') ?? ($_SERVER['REMOTE_ADDR'] ?? null),
        "IDUserLogin" => getParam('IDUserLogin'),
        "lang" => getParam('lang', 'id'),
        "IDPerusahaan" => getParam('IDPerusahaan'),
    ];
}

function bindParams($stmt, $params)
{
    foreach ($params as $i => $val) {
        $idx = $i + 1;

        if (is_int($val)) {
            $stmt->bindValue($idx, $val, PDO::PARAM_INT);
        } elseif (is_bool($val)) {
            $stmt->bindValue($idx, $val, PDO::PARAM_BOOL);
        } elseif (is_null($val)) {
            $stmt->bindValue($idx, $val, PDO::PARAM_NULL);
        } else {
            $stmt->bindValue($idx, $val, PDO::PARAM_STR);
        }
    }
}
function jsonResponse($data, $code = 200)
{
    http_response_code($code);
    header('Content-Type: application/json');
    echo json_encode($data);
    exit;
}


function writeLog($data)
{
    $logFile = __DIR__ . '/../logs/midtrans.log';
    $line = "[" . date('Y-m-d H:i:s') . "] " . json_encode($data) . PHP_EOL;
    file_put_contents($logFile, $line, FILE_APPEND);
}

function getServerKey($mode = 'sandbox')
{
    return config("midtrans.$mode");
}

function verifySignature($data, $serverKey)
{
    if (!isset($data['signature_key']))
        return false;

    $signature = hash(
        'sha512',
        $data['order_id'] .
        $data['status_code'] .
        $data['gross_amount'] .
        $serverKey
    );

    return $signature === $data['signature_key'];
}



function generateToken($length = 32)
{
    return bin2hex(random_bytes($length));
}

function hashToken($token)
{
    return hash('sha256', $token);
}

function uploadImage($file, $folder, $maxSizeMB = 5, $maxDim = 1024)
{
    if (!$file || $file['error'] !== UPLOAD_ERR_OK) {
        return null;
    }

    // ================= SIZE CHECK =================
    $maxSize = $maxSizeMB * 1024 * 1024;
    if ($file['size'] > $maxSize) {
        throw new Exception("Ukuran file maksimal {$maxSizeMB}MB");
    }

    // ================= MIME CHECK =================
    $allowedMime = [
        'image/jpeg',
        'image/png',
        'image/webp'
    ];

    if (!in_array($file['type'], $allowedMime)) {
        throw new Exception("Format gambar tidak valid");
    }

    // ================= CREATE IMAGE =================
    $image = match ($file['type']) {
        'image/jpeg' => imagecreatefromjpeg($file['tmp_name']),
        'image/png' => imagecreatefrompng($file['tmp_name']),
        'image/webp' => imagecreatefromwebp($file['tmp_name']),
    };

    if (!$image) {
        throw new Exception("Gagal membaca image");
    }

    $width = imagesx($image);
    $height = imagesy($image);

    // ================= RESIZE LOGIC =================
    $ratio = 1;

    if ($width > $maxDim || $height > $maxDim) {
        $ratio = min($maxDim / $width, $maxDim / $height);
    }

    if ($ratio < 1) {

        $newWidth = (int) round($width * $ratio);
        $newHeight = (int) round($height * $ratio);

        $newImage = imagecreatetruecolor($newWidth, $newHeight);

        // preserve PNG transparency
        imagealphablending($newImage, false);
        imagesavealpha($newImage, true);

        imagecopyresampled(
            $newImage,
            $image,
            0,
            0,
            0,
            0,
            $newWidth,
            $newHeight,
            $width,
            $height
        );

        $image = $newImage;
    }

    // ================= CREATE FOLDER =================
    if (!is_dir($folder)) {
        mkdir($folder, 0777, true);
    }

    // ================= FILENAME =================
    $ext = match ($file['type']) {
        'image/jpeg' => 'jpg',
        'image/png' => 'png',
        'image/webp' => 'webp',
    };

    $filename = uniqid('img_') . '.' . $ext;
    $path = rtrim($folder, '/') . '/' . $filename;

    // ================= SAVE FILE =================
    match ($ext) {
        'jpg' => imagejpeg($image, $path, 90),
        'png' => imagepng($image, $path),
        'webp' => imagewebp($image, $path),
    };

    // ❌ no imagedestroy needed (GC will handle safely)
    $image = null;

    return $filename;
}

function deleteFile($folder, $filename)
{
    if (!$filename) return;

    $path = rtrim($folder, '/') . '/' . $filename;

    if (file_exists($path)) {
        unlink($path);
    }
}

function deleteFolderIfEmpty($folder)
{
    if (!is_dir($folder)) return;

    $files = scandir($folder);

    if (count($files) <= 2) { // . dan ..
        rmdir($folder);
    }
}

function updateColumnById($table, $idColumn, $idValue, $column, $value)
{
    $stmt = db()->prepare("
        UPDATE {$table}
        SET {$column} = ?
        WHERE {$idColumn} = ?
    ");

    $stmt->execute([$value, $idValue]);
}

function appendFilters(&$data, $newFilters, $overwrite = true)
{
    if (!isset($data['filter']) || !is_array($data['filter'])) {
        $data['filter'] = [];
    }

    foreach ($newFilters as $key => $val) {
        if ($overwrite || !isset($data['filter'][$key])) {
            $data['filter'][$key] = $val;
        }
    }
}
function buildHistoryFilter($req, $table, $id)
{
    $req['rowsPerPage'] = 250;
    $req['sortColumn'] = "IDActivity";
    $req['sortDirection'] = "DESC";

    appendFilters($req, [
        "EntityName" => [
            "value" => $table,
            "condition" => 1
        ],
        "EntityID" => [
            "value" => $id,
            "condition" => 1
        ],
        "Activity" => [
            "value" => "Login",
            "condition" => 5
        ]
    ], false);

    return $req;
}

function getUserHistory($req, $ttbl, $id)
{
    require_once "../activity_history/common.php";
    
    $historyReq = buildHistoryFilter($req, $ttbl, $id);
    
    $configHistory = getListConfigActivityHistory();

    return DataFetcher::getListData($configHistory, $historyReq);
}

function getUserHistoryDetail($req, $ttbl, $id)
{
    require_once "../activity_history_detail/common.php";

    $historyReq = buildHistoryFilter($req, $ttbl, $id);
    $configHistoryDetail = getListConfigActivityHistoryDetail();

    return DataFetcher::getListData($configHistoryDetail, $historyReq);
}