<?php

if (!defined('ABSPATH')) {
    exit;
}

function chbk_register_rest_routes()
{
    add_action('rest_api_init', 'chbk_rest_routes_init');
}

function chbk_rest_routes_init()
{
    register_rest_route('chbk/v1', '/trips', [
        'methods' => WP_REST_Server::READABLE,
        'callback' => 'chbk_rest_get_trips',
        'permission_callback' => '__return_true',
    ]);

    register_rest_route('chbk/v1', '/trips/(?P<id>\d+)/availability', [
        'methods' => WP_REST_Server::READABLE,
        'callback' => 'chbk_rest_get_trip_availability',
        'permission_callback' => 'chbk_rest_can_view_trip_availability',
        'args' => [
            'datetime' => [
                'required' => true,
                'sanitize_callback' => 'sanitize_text_field',
                'validate_callback' => 'chbk_rest_validate_availability_datetime',
            ],
            'party_size' => [
                'required' => false,
                'default' => 1,
                'sanitize_callback' => 'absint',
                'validate_callback' => 'chbk_rest_validate_party_size',
            ],
        ],
    ]);

    register_rest_route('chbk/v1', '/bookings/(?P<id>\d+)', [
        'methods' => WP_REST_Server::READABLE,
        'callback' => 'chbk_rest_get_booking',
        'permission_callback' => function () {
            return current_user_can('manage_options');
        },
    ]);
}

function chbk_rest_can_view_trip_availability($request)
{
    $trip_id = isset($request['id']) ? absint($request['id']) : 0;
    if ($trip_id < 1) {
        return new WP_Error('trip_not_found', 'Trip not found', ['status' => 404]);
    }

    $trip = get_post($trip_id);
    if (!$trip || $trip->post_type !== 'chbk_trip') {
        return new WP_Error('trip_not_found', 'Trip not found', ['status' => 404]);
    }

    if ($trip->post_status === 'publish') {
        return true;
    }

    if (current_user_can('edit_post', $trip_id) || current_user_can('manage_options')) {
        return true;
    }

    return new WP_Error('trip_not_found', 'Trip not found', ['status' => 404]);
}

function chbk_rest_validate_availability_datetime($value, $request, $param)
{
    $datetime = sanitize_text_field((string) $value);
    if ($datetime === '') {
        return false;
    }

    $trip_id = isset($request['id']) ? absint($request['id']) : 0;
    $tz = $trip_id > 0 && function_exists('chbk_get_trip_timezone') ? chbk_get_trip_timezone($trip_id) : chbk_get_default_site_timezone();
    $utc = chbk_to_utc_datetime($datetime, $tz);
    return $utc !== '';
}

function chbk_rest_validate_party_size($value, $request, $param)
{
    return absint($value) > 0;
}

function chbk_rest_get_trips($request)
{
    $posts = get_posts([
        'post_type' => 'chbk_trip',
        'post_status' => 'publish',
        'numberposts' => 100,
    ]);

    $data = [];
    foreach ($posts as $post) {
        $data[] = [
            'id' => $post->ID,
            'title' => $post->post_title,
            'trip_type' => get_post_meta($post->ID, 'chbk_trip_type', true),
            'duration' => get_post_meta($post->ID, 'chbk_duration', true),
            'base_price' => (float) get_post_meta($post->ID, 'chbk_base_price', true),
            'active_status' => get_post_meta($post->ID, 'chbk_active_status', true),
        ];
    }

    return rest_ensure_response($data);
}

function chbk_rest_get_trip_availability($request)
{
    $trip_id = (int) $request['id'];
    $datetime = (string) $request->get_param('datetime');
    $party_size = max(1, (int) $request->get_param('party_size'));

    $trip = get_post($trip_id);
    if (!$trip || $trip->post_type !== 'chbk_trip') {
        return new WP_Error('trip_not_found', 'Trip not found', ['status' => 404]);
    }
    if ($trip->post_status !== 'publish' && !current_user_can('edit_post', $trip_id) && !current_user_can('manage_options')) {
        return new WP_Error('trip_not_found', 'Trip not found', ['status' => 404]);
    }

    $tz = function_exists('chbk_get_trip_timezone') ? chbk_get_trip_timezone($trip_id) : chbk_get_default_site_timezone();
    $utc = chbk_to_utc_datetime($datetime, $tz);
    if ($utc === '') {
        return new WP_Error('invalid_datetime', 'Invalid datetime value.', ['status' => 400]);
    }

    $available = chbk_is_trip_available($trip_id, $party_size, $utc);
    $price = chbk_calculate_price($trip_id, $party_size, $utc);

    return rest_ensure_response([
        'trip_id' => $trip_id,
        'datetime_local' => $datetime,
        'datetime_utc' => $utc,
        'party_size' => $party_size,
        'available' => (bool) $available,
        'price' => (float) $price,
    ]);
}

function chbk_rest_get_booking($request)
{
    $booking_id = (int) $request['id'];
    $post = get_post($booking_id);

    if (!$post || $post->post_type !== 'chbk_booking') {
        return new WP_Error('booking_not_found', 'Booking not found', ['status' => 404]);
    }

    $keys = [
        'trip_id', 'boat_id', 'captain_id', 'user_id', 'party_size', 'booking_status',
        'payment_status', 'order_id', 'checkin_status', 'trip_datetime_utc', 'total_price',
        'deposit_due', 'customer_name', 'customer_email',
    ];

    $data = [
        'id' => $post->ID,
        'title' => $post->post_title,
    ];

    foreach ($keys as $key) {
        $data[$key] = get_post_meta($post->ID, 'chbk_' . $key, true);
    }

    return rest_ensure_response($data);
}
