<?php
/**
 * send-message.php
 * - CORS + preflight support
 * - Safe JSON responses
 * - Works with either FormData ($_POST) OR JSON body (application/json)
 * - Avoids fatal errors when $conn is not available
 */

declare(strict_types=1);

// ===== CORS HEADERS =====
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Methods: POST, OPTIONS");
header("Access-Control-Allow-Headers: Content-Type, Authorization");
header("Content-Type: application/json; charset=UTF-8");

// ===== Handle preflight OPTIONS =====
if (isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] === "OPTIONS") {
    http_response_code(200);
    echo json_encode([
        'code' => 200,
        'status' => 'success',
        'message' => 'Preflight OK',
        'data' => null
    ]);
    exit();
}

// ===== Helper: send response safely =====
function sendResponse(int $httpCode, string $status, string $message, $data = null): void {
    // close db connection if available
    if (isset($GLOBALS['conn']) && $GLOBALS['conn'] instanceof mysqli) {
        @$GLOBALS['conn']->close();
    }

    http_response_code($httpCode);
    echo json_encode([
        'code'    => $httpCode,
        'status'  => $status,
        'message' => $message,
        'data'    => $data,
    ]);
    exit();
}

// ===== Only allow POST =====
if (!isset($_SERVER['REQUEST_METHOD']) || $_SERVER['REQUEST_METHOD'] !== 'POST') {
    sendResponse(400, "error", "Use POST method only.");
}

// ===== Load DB connection early (before any function that might respond) =====
require "../../../../database/conn.php";
if (!isset($conn) || !($conn instanceof mysqli)) {
    sendResponse(500, "error", "Database connection not initialized.");
}
$GLOBALS['conn'] = $conn;

// ===== Helper: get input from POST or JSON body =====
function getInput(): array {
    // If request is JSON, PHP won't populate $_POST
    $contentType = $_SERVER['CONTENT_TYPE'] ?? $_SERVER['HTTP_CONTENT_TYPE'] ?? '';
    if (stripos($contentType, 'application/json') !== false) {
        $raw = file_get_contents("php://input");
        $decoded = json_decode($raw, true);
        return is_array($decoded) ? $decoded : [];
    }
    return $_POST ?? [];
}

// ===== Helper: validate required fields =====
function requireFields(array $data, array $requiredFields): void {
    foreach ($requiredFields as $field) {
        if (!isset($data[$field]) || trim((string)$data[$field]) === '') {
            sendResponse(400, "error", "'$field' is missing or empty.");
        }
    }
}

// ===== Read inputs =====
$input = getInput();

// student_id is expected in query string (?student_id=...)
requireFields($_GET, ['student_id']);

// ticket_id + message expected in body (FormData or JSON)
requireFields($input, ['ticket_id', 'message']);

$email        = (string) $_GET['student_id'];
$ticketId     = (int) $input['ticket_id'];
$message      = (string) $input['message'];
$chatIdFromUI = isset($input['chat_id']) ? (string)$input['chat_id'] : "";
$userType     = 2;
$responseType = 2;

// ===== Save message =====
function save_message(int $ticketId, string $chatIdFromUI, int $userType, string $message, int $responseType, string $email): ?int {
    $conn = $GLOBALS['conn'];

    $query = "INSERT INTO `ticket_chat`
              (`ticket_id`, `chat_id`, `user_type`, `response`, `response_type`, `user`)
              VALUES (?,?,?,?,?,?)";

    $stmt = mysqli_prepare($conn, $query);
    if (!$stmt) {
        error_log("Query preparation failed: " . mysqli_error($conn));
        return null;
    }

    // ticket_id(i), chat_id(s), user_type(i), response(s), response_type(i), user(s)
    if (!mysqli_stmt_bind_param($stmt, 'isisis', $ticketId, $chatIdFromUI, $userType, $message, $responseType, $email)) {
        error_log("Parameter binding failed: " . mysqli_error($conn));
        mysqli_stmt_close($stmt);
        return null;
    }

    if (!mysqli_stmt_execute($stmt)) {
        error_log("Query execution failed: " . mysqli_error($conn));
        mysqli_stmt_close($stmt);
        return null;
    }

    $lastInsertedId = mysqli_insert_id($conn);
    mysqli_stmt_close($stmt);

    if ($lastInsertedId <= 0) {
        error_log("Failed to retrieve last inserted ID: " . mysqli_error($conn));
        return null;
    }

    return (int)$lastInsertedId;
}

// ===== Save attachments (FormData only) =====
function save_attachment(int $chatId): array {
    $conn = $GLOBALS['conn'];

    $uploadPath = rtrim((string)$_SERVER['DOCUMENT_ROOT'], "/") . "/login/member/dashboard/imgs/tickets/";
    $uploadedFiles = [];
    $failedUploads = [];

    if (!is_dir($uploadPath)) {
        if (!mkdir($uploadPath, 0777, true)) {
            error_log("Failed to create upload directory: " . $uploadPath);
            return ["uploaded_files" => [], "failed_uploads" => ["UPLOAD_DIR_CREATE_FAILED"]];
        }
    }

    // Ensure attachments structure exists
    if (!isset($_FILES['attachments']) || !isset($_FILES['attachments']['name']) || !is_array($_FILES['attachments']['name'])) {
        return ["uploaded_files" => [], "failed_uploads" => []];
    }

    foreach ($_FILES['attachments']['name'] as $index => $fileName) {
        $fileName    = (string)$fileName;
        $fileTmpName = $_FILES['attachments']['tmp_name'][$index] ?? null;
        $fileError   = $_FILES['attachments']['error'][$index] ?? UPLOAD_ERR_NO_FILE;

        if ($fileError !== UPLOAD_ERR_OK) {
            error_log("File upload error for file $fileName: Error code $fileError");
            $failedUploads[] = $fileName;
            continue;
        }

        if (!$fileTmpName || !is_uploaded_file($fileTmpName)) {
            error_log("Temporary upload missing/invalid for file $fileName");
            $failedUploads[] = $fileName;
            continue;
        }

        // Generate unique file name
        $fileExt = pathinfo($fileName, PATHINFO_EXTENSION);
        $uniqueFileName = $chatId . "_" . str_replace('.', '', uniqid('', true)) . ($fileExt ? "." . $fileExt : "");

        $fileDestination = $uploadPath . $uniqueFileName;

        if (move_uploaded_file($fileTmpName, $fileDestination)) {
            $uploadedFiles[] = $uniqueFileName;

            // caption
            $caption = "";
            if (isset($_POST['captions']) && is_array($_POST['captions'])) {
                $caption = (string)($_POST['captions'][$index] ?? "");
            }

            // Insert into DB
            $query = "INSERT INTO `ticket_attachement` (`description`, `caption`, `ticket_res_id`) VALUES (?, ?, ?)";
            $stmt = mysqli_prepare($conn, $query);

            if (!$stmt) {
                error_log("Query preparation failed: " . mysqli_error($conn));
                $failedUploads[] = $fileName;
                continue;
            }

            if (!mysqli_stmt_bind_param($stmt, 'ssi', $uniqueFileName, $caption, $chatId)) {
                error_log("Parameter binding failed: " . mysqli_error($conn));
                mysqli_stmt_close($stmt);
                $failedUploads[] = $fileName;
                continue;
            }

            if (!mysqli_stmt_execute($stmt)) {
                error_log("Query execution failed: " . mysqli_error($conn));
                mysqli_stmt_close($stmt);
                $failedUploads[] = $fileName;
                continue;
            }

            mysqli_stmt_close($stmt);
        } else {
            error_log("Failed to move file $fileName to $fileDestination");
            $failedUploads[] = $fileName;
        }
    }

    return ["uploaded_files" => $uploadedFiles, "failed_uploads" => $failedUploads];
}

// ===== Run =====
$chatId = save_message($ticketId, $chatIdFromUI, $userType, $message, $responseType, $email);

if ($chatId === null) {
    sendResponse(500, "error", "Unexpected error occurred while saving your message");
}

// Attachments only come via multipart/form-data
if (!empty($_FILES)) {
    $response = save_attachment($chatId);
    sendResponse(200, "success", "message sent", $response);
}

sendResponse(200, "success", "message sent");
