<?php
declare(strict_types=1);

require_once __DIR__ . '/../config/bootstrap.php';

require_permission($conn, 'services');

process_post_only_or_redirect('../pages/services.php');

$returnTo = safe_page_return((string) ($_POST['return_to'] ?? ''), 'service_categories.php');
$categoryId = filter_input(INPUT_POST, 'category_id', FILTER_VALIDATE_INT);
$returnServiceId = filter_input(INPUT_POST, 'return_service_id', FILTER_VALIDATE_INT);
$categoryName = trim((string) ($_POST['category_name'] ?? ''));
$redirectPath = '../pages/' . $returnTo;
$successPath = '../pages/' . $returnTo;

$oldInput = array(
    'category_name' => $categoryName,
);

if ($categoryName === '') {
    redirect_with_flash($redirectPath, 'error', localized_flash_message('กรุณาระบุชื่อหมวดหมู่', 'Category name is required.'), $oldInput);
}

$currentCategory = null;
if ($categoryId) {
    $categoryStmt = db_prepare($conn, "
        SELECT category_id, category_name
        FROM service_categories
        WHERE category_id = ?
        LIMIT 1
    ");
    $categoryStmt->bind_param('i', $categoryId);
    $categoryStmt->execute();
    $currentCategory = $categoryStmt->get_result()->fetch_assoc();
    $categoryStmt->close();

    if (!$currentCategory) {
        redirect_with_flash($successPath, 'error', localized_flash_message('ไม่พบหมวดหมู่', 'Category was not found.'));
    }
}

$conn->begin_transaction();

try {
    if ($categoryId) {
        $oldCategoryName = (string) ($currentCategory['category_name'] ?? '');

        $updateCategoryStmt = db_prepare($conn, "
            UPDATE service_categories
            SET category_name = ?
            WHERE category_id = ?
        ");
        $updateCategoryStmt->bind_param('si', $categoryName, $categoryId);
        $updateCategoryStmt->execute();
        $updateCategoryStmt->close();

        if ($oldCategoryName !== '' && $oldCategoryName !== $categoryName) {
            $updateServiceStmt = db_prepare($conn, "
                UPDATE services
                SET category = ?
                WHERE category_id = ?
            ");
            $updateServiceStmt->bind_param('si', $categoryName, $categoryId);
            $updateServiceStmt->execute();
            $updateServiceStmt->close();
        }

        $categoryDiff = audit_diff_assoc(
            array('category_name' => $oldCategoryName),
            array('category_name' => $categoryName)
        );
        if (!empty($categoryDiff['after'])) {
            audit_log($conn, array(
                'module_key' => 'category',
                'action_key' => 'update',
                'entity_type' => 'service_category',
                'entity_id' => $categoryId,
                'message' => 'Service category updated.',
                'before' => $categoryDiff['before'],
                'after' => $categoryDiff['after'],
            ));
        }

        $conn->commit();
        redirect_with_flash($successPath, 'success', localized_flash_message('อัปเดตหมวดหมู่เรียบร้อยแล้ว', 'Category updated.'));
    }

    $insertStmt = db_prepare($conn, "
        INSERT INTO service_categories (category_name)
        VALUES (?)
    ");
    $insertStmt->bind_param('s', $categoryName);
    $insertStmt->execute();
    $categoryId = (int) $conn->insert_id;
    $insertStmt->close();

    audit_log($conn, array(
        'module_key' => 'category',
        'action_key' => 'create',
        'entity_type' => 'service_category',
        'entity_id' => $categoryId,
        'message' => 'Service category created.',
        'after' => array(
            'category_name' => $categoryName,
        ),
    ));

    $conn->commit();
    redirect_with_flash($successPath, 'success', localized_flash_message('เพิ่มหมวดหมู่เรียบร้อยแล้ว', 'Category added.'));
} catch (Throwable $exception) {
    process_handle_exception_and_redirect(
        $conn,
        $exception,
        'save_service_category',
        $redirectPath,
        localized_flash_message('บันทึกหมวดหมู่ไม่สำเร็จ ชื่อนี้อาจถูกใช้งานแล้ว', 'Category was not saved. The name may already be in use.'),
        array(
            'category_id' => (int) ($categoryId ?: 0),
            'return_to' => $returnTo,
            'return_service_id' => (int) ($returnServiceId ?: 0),
        ),
        $oldInput
    );
}
