<?php
declare(strict_types=1);

header('Content-Type: application/json; charset=utf-8');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type, Accept');

ob_start();

function respond(int $status_code, array $payload): void
{
    while (ob_get_level() > 0) {
        ob_end_clean();
    }

    http_response_code($status_code);
    echo json_encode($payload);
    exit;
}

if (($_SERVER['REQUEST_METHOD'] ?? '') === 'OPTIONS') {
    respond(204, []);
}

if (($_SERVER['REQUEST_METHOD'] ?? '') !== 'POST') {
    respond(405, ['success' => false, 'message' => 'Method tidak dibenarkan.']);
}

require_once __DIR__ . '/../db.php';

$payload = json_decode(file_get_contents('php://input') ?: '', true);
if (!is_array($payload)) {
    $payload = $_POST;
}

$user_id = (int) ($payload['user_id'] ?? 0);
if ($user_id <= 0) {
    respond(422, ['success' => false, 'message' => 'Pengguna tidak sah.']);
}

$action = trim((string) ($payload['action'] ?? 'fetch'));

if ($action === 'update_profile') {
    $fullname = trim((string) ($payload['fullname'] ?? ''));
    $short_name = trim((string) ($payload['short_name'] ?? $payload['shortName'] ?? ''));
    $email = trim((string) ($payload['email'] ?? ''));

    if ($fullname === '' || $short_name === '' || $email === '') {
        respond(422, ['success' => false, 'message' => 'Maklumat profil tidak lengkap.']);
    }

    if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
        respond(422, ['success' => false, 'message' => 'Format emel tidak sah.']);
    }

    $duplicate = mysqli_prepare(
        $conn,
        'SELECT id FROM users WHERE email = ? AND id <> ? LIMIT 1'
    );
    if (!$duplicate) {
        respond(500, ['success' => false, 'message' => 'Profil tidak dapat dikemaskini.']);
    }
    mysqli_stmt_bind_param($duplicate, 'si', $email, $user_id);
    mysqli_stmt_execute($duplicate);
    $duplicate_result = mysqli_stmt_get_result($duplicate);
    if ($duplicate_result && mysqli_fetch_assoc($duplicate_result)) {
        respond(409, ['success' => false, 'message' => 'Emel telah digunakan oleh pengguna lain.']);
    }

    $update = mysqli_prepare(
        $conn,
        'UPDATE users SET fullname = ?, short_name = ?, email = ? WHERE id = ? AND status = "approved"'
    );
    if (!$update) {
        respond(500, ['success' => false, 'message' => 'Profil tidak dapat dikemaskini.']);
    }
    mysqli_stmt_bind_param($update, 'sssi', $fullname, $short_name, $email, $user_id);
    if (!mysqli_stmt_execute($update)) {
        respond(500, ['success' => false, 'message' => 'Profil tidak dapat dikemaskini.']);
    }
}

if ($action === 'upload_photo') {
    $file = $_FILES['profile_photo'] ?? null;
    if (!is_array($file) || (int) ($file['error'] ?? UPLOAD_ERR_NO_FILE) !== UPLOAD_ERR_OK) {
        respond(422, ['success' => false, 'message' => 'Sila pilih gambar profil yang sah.']);
    }

    $size = (int) ($file['size'] ?? 0);
    if ($size <= 0 || $size > 5 * 1024 * 1024) {
        respond(422, ['success' => false, 'message' => 'Saiz gambar mestilah tidak melebihi 5MB.']);
    }

    $image_info = @getimagesize((string) $file['tmp_name']);
    $mime = is_array($image_info) ? (string) ($image_info['mime'] ?? '') : '';
    $extensions = [
        'image/jpeg' => 'jpg',
        'image/png' => 'png',
        'image/webp' => 'webp',
    ];
    if (!isset($extensions[$mime])) {
        respond(422, ['success' => false, 'message' => 'Hanya gambar JPG, PNG atau WEBP dibenarkan.']);
    }

    $upload_dir = dirname(__DIR__) . DIRECTORY_SEPARATOR . 'uploads';
    if (!is_dir($upload_dir) && !mkdir($upload_dir, 0755, true) && !is_dir($upload_dir)) {
        respond(500, ['success' => false, 'message' => 'Folder gambar profil tidak dapat disediakan.']);
    }

    try {
        $token = bin2hex(random_bytes(6));
    } catch (Throwable $error) {
        $token = (string) time();
    }
    $filename = 'profile_' . $user_id . '_' . $token . '.' . $extensions[$mime];
    $destination = $upload_dir . DIRECTORY_SEPARATOR . $filename;
    $relative_path = 'uploads/' . $filename;

    if (!move_uploaded_file((string) $file['tmp_name'], $destination)) {
        respond(500, ['success' => false, 'message' => 'Gambar profil gagal dimuat naik.']);
    }

    $old_photo = '';
    $old_stmt = mysqli_prepare($conn, 'SELECT profile_photo FROM users WHERE id = ? LIMIT 1');
    if ($old_stmt) {
        mysqli_stmt_bind_param($old_stmt, 'i', $user_id);
        mysqli_stmt_execute($old_stmt);
        $old_result = mysqli_stmt_get_result($old_stmt);
        $old_row = $old_result ? mysqli_fetch_assoc($old_result) : null;
        $old_photo = trim((string) ($old_row['profile_photo'] ?? ''));
    }

    $update = mysqli_prepare(
        $conn,
        'UPDATE users SET profile_photo = ? WHERE id = ? AND status = "approved"'
    );
    if (!$update) {
        @unlink($destination);
        respond(500, ['success' => false, 'message' => 'Gambar profil tidak dapat disimpan.']);
    }
    mysqli_stmt_bind_param($update, 'si', $relative_path, $user_id);
    if (!mysqli_stmt_execute($update)) {
        @unlink($destination);
        respond(500, ['success' => false, 'message' => 'Gambar profil tidak dapat disimpan.']);
    }

    if ($old_photo !== '' && str_starts_with(str_replace('\\', '/', $old_photo), 'uploads/')) {
        $old_file = dirname(__DIR__) . DIRECTORY_SEPARATOR . str_replace(
            '/',
            DIRECTORY_SEPARATOR,
            $old_photo
        );
        if (is_file($old_file) && realpath($old_file) !== realpath($destination)) {
            @unlink($old_file);
        }
    }
}

if ($action === 'upload_signature' || $action === 'save_signature') {
    $upload_dir = dirname(__DIR__) . DIRECTORY_SEPARATOR . 'uploads' . DIRECTORY_SEPARATOR . 'signatures';
    if (!is_dir($upload_dir) && !mkdir($upload_dir, 0755, true) && !is_dir($upload_dir)) {
        respond(500, ['success' => false, 'message' => 'Folder tandatangan tidak dapat disediakan.']);
    }

    $raw_bytes = null;
    $ext = 'png';

    // 1. Check if multipart file uploaded
    $file = $_FILES['signature_file'] ?? $_FILES['signature_image'] ?? $_FILES['signature'] ?? null;
    if (is_array($file) && (int) ($file['error'] ?? UPLOAD_ERR_NO_FILE) === UPLOAD_ERR_OK) {
        $size = (int) ($file['size'] ?? 0);
        if ($size <= 0 || $size > 5 * 1024 * 1024) {
            respond(422, ['success' => false, 'message' => 'Saiz fail tandatangan mestilah tidak melebihi 5MB.']);
        }
        $image_info = @getimagesize((string) $file['tmp_name']);
        $mime = is_array($image_info) ? (string) ($image_info['mime'] ?? '') : '';
        $extensions = [
            'image/jpeg' => 'jpg',
            'image/png' => 'png',
            'image/webp' => 'webp',
        ];
        if (!isset($extensions[$mime])) {
            respond(422, ['success' => false, 'message' => 'Hanya gambar JPG, PNG atau WEBP dibenarkan untuk tandatangan.']);
        }
        $ext = $extensions[$mime];
        $raw_bytes = file_get_contents((string) $file['tmp_name']);
    }

    // 2. Check if base64 string provided in JSON payload
    if ($raw_bytes === null) {
        $base64_str = trim((string) ($payload['signature_base64'] ?? $payload['signature_data'] ?? $payload['signature_image'] ?? ''));
        if ($base64_str !== '') {
            // Remove data URI prefix if present (e.g. data:image/png;base64,)
            if (preg_match('/^data:image\/(\w+);base64,/', $base64_str, $matches)) {
                $ext = strtolower($matches[1]);
                if ($ext === 'jpeg') $ext = 'jpg';
                $base64_str = substr($base64_str, strpos($base64_str, ',') + 1);
            }
            $decoded = base64_decode($base64_str, true);
            if ($decoded !== false && strlen($decoded) > 50) {
                $raw_bytes = $decoded;
            }
        }
    }

    if ($raw_bytes === null || strlen($raw_bytes) < 50) {
        respond(422, ['success' => false, 'message' => 'Data tandatangan tidak sah atau kosong. Sila lukis atau pilih gambar.']);
    }

    try {
        $token = bin2hex(random_bytes(6));
    } catch (Throwable $error) {
        $token = (string) time();
    }
    $filename = 'signature_' . $user_id . '_' . $token . '.' . $ext;
    $destination = $upload_dir . DIRECTORY_SEPARATOR . $filename;
    $relative_path = 'uploads/signatures/' . $filename;

    if (file_put_contents($destination, $raw_bytes) === false) {
        respond(500, ['success' => false, 'message' => 'Gagal menyimpan fail tandatangan ke storan server.']);
    }

    $old_sig = '';
    $old_stmt = mysqli_prepare($conn, 'SELECT signature_path FROM users WHERE id = ? LIMIT 1');
    if ($old_stmt) {
        mysqli_stmt_bind_param($old_stmt, 'i', $user_id);
        mysqli_stmt_execute($old_stmt);
        $old_result = mysqli_stmt_get_result($old_stmt);
        $old_row = $old_result ? mysqli_fetch_assoc($old_result) : null;
        $old_sig = trim((string) ($old_row['signature_path'] ?? ''));
    }

    $update = mysqli_prepare(
        $conn,
        'UPDATE users SET signature_path = ? WHERE id = ? AND status = "approved"'
    );
    if (!$update) {
        @unlink($destination);
        respond(500, ['success' => false, 'message' => 'Tandatangan tidak dapat dikemaskini dalam pangkalan data.']);
    }
    mysqli_stmt_bind_param($update, 'si', $relative_path, $user_id);
    if (!mysqli_stmt_execute($update)) {
        @unlink($destination);
        respond(500, ['success' => false, 'message' => 'Tandatangan tidak dapat dikemaskini dalam pangkalan data.']);
    }



    if (function_exists('logActivity')) {
        @logActivity(
            $conn,
            $user_id,
            'update_signature',
            'Kemaskini tandatangan digital melalui aplikasi mobile'
        );
    }
}

$stmt = mysqli_prepare(
    $conn,
    'SELECT id, fullname, short_name, ic_number, email, department, status, role, position, signature_path, profile_photo
     FROM users
     WHERE id = ? AND status = "approved"
     LIMIT 1'
);

if (!$stmt) {
    respond(500, ['success' => false, 'message' => 'Profil tidak dapat dimuatkan.']);
}

mysqli_stmt_bind_param($stmt, 'i', $user_id);
mysqli_stmt_execute($stmt);
$result = mysqli_stmt_get_result($stmt);
$user = $result ? mysqli_fetch_assoc($result) : null;

if (!$user) {
    respond(404, ['success' => false, 'message' => 'Profil pengguna tidak ditemui.']);
}

respond(200, [
    'success' => true,
    'user' => [
        'id' => (int) $user['id'],
        'fullname' => (string) ($user['fullname'] ?? ''),
        'shortName' => (string) ($user['short_name'] ?? ''),
        'identityCard' => (string) ($user['ic_number'] ?? ''),
        'email' => (string) ($user['email'] ?? ''),
        'department' => (string) ($user['department'] ?? ''),
        'role' => (string) ($user['role'] ?? 'user'),
        'position' => (string) ($user['position'] ?? ''),
        'signaturePath' => (string) ($user['signature_path'] ?? ''),
        'profileImage' => (string) ($user['profile_photo'] ?? ''),
    ],
]);
