<?php
header('Content-Type: application/json');
$response = ['success' => false, 'message' => 'Gagal membuat tiket.', 'ticket_id' => null];

require_once __DIR__ . '/../../config/config.php';
require_once __DIR__ . '/../../includes/session.php';
require_once __DIR__ . '/../../lib/Auth.php';
require_once __DIR__ . '/../../includes/functions.php';

define('TICKET_UPLOAD_DIR', PUBLIC_ROOT . '/uploads/tickets/');
define('TICKET_MAX_FILE_SIZE', 2 * 1024 * 1024); 
$ticketAllowedTypes = ['image/jpeg', 'image/png', 'image/gif', 'image/webp'];

if (!is_dir(TICKET_UPLOAD_DIR) && !mkdir(TICKET_UPLOAD_DIR, 0775, true)) {
    http_response_code(500);
    error_log("Failed to create ticket upload directory: " . TICKET_UPLOAD_DIR);
    $response['message'] = 'Kesalahan server: Gagal membuat direktori upload tiket.';
    echo json_encode($response);
    exit;
}
if (!is_writable(TICKET_UPLOAD_DIR)) {
    http_response_code(500);
    error_log("Ticket upload directory is not writable: " . TICKET_UPLOAD_DIR);
    $response['message'] = 'Kesalahan server: Direktori upload tiket tidak dapat ditulis.';
    echo json_encode($response);
    exit;
}


if (!Auth::isLoggedIn()) { http_response_code(401); $response['message'] = 'Sesi berakhir.'; echo json_encode($response); exit; }
if (!isset($pdo) || !$pdo instanceof PDO) { http_response_code(500); error_log("PDO object not available in create_ticket.php"); $response['message'] = 'Koneksi database gagal.'; echo json_encode($response); exit; }
if ($_SERVER['REQUEST_METHOD'] !== 'POST') { http_response_code(405); $response['message'] = 'Metode request tidak valid.'; echo json_encode($response); exit; }

$uploadedFilename = null;

try {
    $userId = $_SESSION['user_id'];
    $subject = sanitize_input($_POST['subject'] ?? '');
    $message = sanitize_input($_POST['message'] ?? '');
    $errors = [];

    if (empty($subject)) { $errors['subject'] = 'Subjek wajib diisi.'; }
    if (mb_strlen($subject) > 255) { $errors['subject'] = 'Subjek terlalu panjang (maks 255 karakter).'; }
    if (empty($message)) { $errors['message'] = 'Pesan wajib diisi.'; }

    if (isset($_FILES['attachment']) && $_FILES['attachment']['error'] == UPLOAD_ERR_OK) {
        $fileTmpPath = $_FILES['attachment']['tmp_name'];
        $fileName = $_FILES['attachment']['name'];
        $fileSize = $_FILES['attachment']['size'];
        $fileType = $_FILES['attachment']['type'];
        $fileNameCmps = explode(".", $fileName);
        $fileExtension = strtolower(end($fileNameCmps));

        if ($fileSize > TICKET_MAX_FILE_SIZE) {
            $errors['attachment'] = 'Ukuran file terlalu besar (Maks 2MB).';
        } elseif (!in_array($fileType, $ticketAllowedTypes)) {
            $errors['attachment'] = 'Format file tidak diizinkan (Hanya JPG, PNG, GIF, WEBP).';
        } else {
            $newFileName = md5(time() . $fileName . $userId) . '.' . $fileExtension;
            $dest_path = TICKET_UPLOAD_DIR . $newFileName;

            if (move_uploaded_file($fileTmpPath, $dest_path)) {
                $uploadedFilename = $newFileName; 
            } else {
                $errors['attachment'] = 'Gagal memindahkan file lampiran.';
                error_log("Failed to move ticket attachment to: " . $dest_path);
            }
        }
    } elseif (isset($_FILES['attachment']) && $_FILES['attachment']['error'] != UPLOAD_ERR_NO_FILE) {
        $uploadErrors = [ UPLOAD_ERR_INI_SIZE => 'Ukuran file melebihi batas server.', UPLOAD_ERR_FORM_SIZE => 'Ukuran file melebihi batas form.', UPLOAD_ERR_PARTIAL => 'File hanya terunggah sebagian.', UPLOAD_ERR_CANT_WRITE => 'Gagal menulis file ke disk.', UPLOAD_ERR_EXTENSION => 'Ekstensi PHP menghentikan unggahan file.', ];
        $errorCode = $_FILES['attachment']['error'];
        $errors['attachment'] = $uploadErrors[$errorCode] ?? 'Terjadi kesalahan saat mengunggah lampiran.';
        error_log("Ticket attachment upload error code: " . $errorCode);
    }


    if (!empty($errors)) {
        http_response_code(400);
        $response['errors'] = $errors;
        $response['message'] = 'Harap perbaiki input yang ditandai.';
        if ($uploadedFilename && file_exists(TICKET_UPLOAD_DIR . $uploadedFilename)) {
            unlink(TICKET_UPLOAD_DIR . $uploadedFilename);
        }
        echo json_encode($response);
        exit;
    }

    $pdo->beginTransaction();

    $ticketId = 'TKT-' . strtoupper(substr(md5(uniqid(rand(), true)), 0, 10));

    $sqlInsertTicket = "INSERT INTO tickets (ticket_id, user_id, subject, message, status, priority, last_reply_by, is_read_user, is_read_admin, created_at, updated_at)
                        VALUES (:ticket_id, :user_id, :subject, :message, 'open', 'medium', 'user', 1, 0, NOW(), NOW())";
    $stmtInsertTicket = $pdo->prepare($sqlInsertTicket);
    $stmtInsertTicket->bindParam(':ticket_id', $ticketId);
    $stmtInsertTicket->bindParam(':user_id', $userId, PDO::PARAM_INT);
    $stmtInsertTicket->bindParam(':subject', $subject);
    $stmtInsertTicket->bindParam(':message', $message); 

    if (!$stmtInsertTicket->execute()) {
        throw new RuntimeException("Gagal menyimpan data tiket utama.");
    }
    $newTicketInternalId = $pdo->lastInsertId(); 

    $sqlInsertReply = "INSERT INTO ticket_replies (ticket_id, user_id, message, attachment_filename, created_at)
                       VALUES (:ticket_id, :user_id, :message, :attachment, NOW())";
    $stmtInsertReply = $pdo->prepare($sqlInsertReply);
    $stmtInsertReply->bindParam(':ticket_id', $newTicketInternalId, PDO::PARAM_INT);
    $stmtInsertReply->bindParam(':user_id', $userId, PDO::PARAM_INT);
    $stmtInsertReply->bindParam(':message', $message);
    $stmtInsertReply->bindParam(':attachment', $uploadedFilename); 

    if (!$stmtInsertReply->execute()) {
        if ($uploadedFilename && file_exists(TICKET_UPLOAD_DIR . $uploadedFilename)) {
            unlink(TICKET_UPLOAD_DIR . $uploadedFilename);
        }
        throw new RuntimeException("Gagal menyimpan pesan awal tiket.");
    }

    $pdo->commit();

    $response['success'] = true;
    $response['message'] = 'Tiket berhasil dibuat.';
    $response['ticket_id'] = $ticketId;

} catch (InvalidArgumentException $e) {
    if ($pdo->inTransaction()) { $pdo->rollBack(); }
    if (isset($uploadedFilename) && $uploadedFilename && file_exists(TICKET_UPLOAD_DIR . $uploadedFilename)) { unlink(TICKET_UPLOAD_DIR . $uploadedFilename); }
    http_response_code(400);
    $response['message'] = $e->getMessage();
} catch (RuntimeException $e) {
    if ($pdo->inTransaction()) { $pdo->rollBack(); }
    if (isset($uploadedFilename) && $uploadedFilename && file_exists(TICKET_UPLOAD_DIR . $uploadedFilename)) { unlink(TICKET_UPLOAD_DIR . $uploadedFilename); }
    error_log("Create Ticket Runtime Error: " . $e->getMessage());
    $response['message'] = "Gagal menyimpan tiket: " . $e->getMessage();
    http_response_code(500);
} catch (\PDOException $e) {
    if ($pdo->inTransaction()) { $pdo->rollBack(); }
    if (isset($uploadedFilename) && $uploadedFilename && file_exists(TICKET_UPLOAD_DIR . $uploadedFilename)) { unlink(TICKET_UPLOAD_DIR . $uploadedFilename); }
    error_log("Create Ticket DB Error: " . $e->getMessage());
    $response['message'] = "Terjadi kesalahan database saat membuat tiket.";
    http_response_code(500);
} catch (\Throwable $e) {
    if ($pdo->inTransaction()) { $pdo->rollBack(); }
    if (isset($uploadedFilename) && $uploadedFilename && file_exists(TICKET_UPLOAD_DIR . $uploadedFilename)) { unlink(TICKET_UPLOAD_DIR . $uploadedFilename); }
    error_log("Create Ticket General Error: " . $e->getMessage());
    $response['message'] = "Terjadi kesalahan internal server.";
    if (defined('DEBUG_MODE') && DEBUG_MODE === true) { $response['debug_php'] = $e->getMessage(); }
    http_response_code(500);
}

echo json_encode($response);
exit;
?>
