<?php
/**
 * REST API endpoint for Birth Chart generation
 *
 * @package EZHoroscope
 */

defined('ABSPATH') || exit;

add_action('rest_api_init', function () {
    register_rest_route('ezhp/v1', '/birth-chart', [
        'methods'             => 'POST',
        'callback'            => 'ezhp_rest_birth_chart',
        'permission_callback' => '__return_true',
    ]);
});

// Add no-cache headers to birth chart responses
add_filter('rest_post_dispatch', function ($response, $server, $request) {
    if ($request->get_route() === '/ezhp/v1/birth-chart') {
        $response->header('Cache-Control', 'no-store, no-cache, must-revalidate, max-age=0');
        $response->header('Pragma', 'no-cache');
        $response->header('Expires', '0');
    }
    return $response;
}, 10, 3);

/**
 * Handle birth chart API request
 *
 * @param WP_REST_Request $ezhp_request The REST request object.
 * @return array Response with image data or error.
 */
function ezhp_rest_birth_chart( WP_REST_Request $ezhp_request ) {

    $ezhp_body = $ezhp_request->get_json_params();

    $ezhp_location = isset($ezhp_body['location']) ? sanitize_text_field($ezhp_body['location']) : '';
    $ezhp_datetime = isset($ezhp_body['birthDateTimeLocal']) ? sanitize_text_field($ezhp_body['birthDateTimeLocal']) : '';
    $ezhp_language = isset($ezhp_body['language']) ? sanitize_text_field($ezhp_body['language']) : 'en';
    $ezhp_house_system = isset($ezhp_body['houseSystem']) ? sanitize_text_field($ezhp_body['houseSystem']) : 'placidus';
    $ezhp_include_transits = isset($ezhp_body['includeTransits']) ? (bool) $ezhp_body['includeTransits'] : true;
    $ezhp_transit_datetime = isset($ezhp_body['transitDateTime']) ? sanitize_text_field($ezhp_body['transitDateTime']) : '';
    $ezhp_style    = isset($ezhp_body['styleSettings']) ? $ezhp_body['styleSettings'] : [];

    if (empty($ezhp_location)) {
        return [
            'error' => 'Location is required.',
        ];
    }

    if (empty($ezhp_datetime)) {
        return [
            'error' => 'Birth date and time is required.',
        ];
    }

    // Format datetime for API - DO NOT append 'Z' as this is LOCAL time
    // The API will convert to UTC based on the location's timezone
    // Input: 2025-11-26T16:52 -> Output: 2025-11-26T16:52:00
    $ezhp_datetime_formatted = $ezhp_datetime;
    if (strlen($ezhp_datetime) === 16) {
        // datetime-local format without seconds - just add seconds
        $ezhp_datetime_formatted = $ezhp_datetime . ':00';
    } elseif (strlen($ezhp_datetime) === 19) {
        // Has seconds already, use as-is
        $ezhp_datetime_formatted = $ezhp_datetime;
    } elseif (substr($ezhp_datetime, -1) === 'Z') {
        // Strip the Z suffix if present - we want local time, not UTC
        $ezhp_datetime_formatted = substr($ezhp_datetime, 0, -1);
        // Also strip milliseconds if present (e.g., .000Z -> remove .000)
        if (preg_match('/\.\d{3}$/', $ezhp_datetime_formatted)) {
            $ezhp_datetime_formatted = substr($ezhp_datetime_formatted, 0, -4);
        }
    }
    // Do NOT append 'Z' - the time is local to the birth location

    // Build the payload for the external API
    $ezhp_payload = [
        'location'           => $ezhp_location,
        'birthDateTimeLocal' => $ezhp_datetime_formatted,
        'language'           => $ezhp_language,
        'houseSystem'        => $ezhp_house_system,
        'includeTransits'    => $ezhp_include_transits,
        'styleSettings'      => ezhp_sanitize_style_settings($ezhp_style),
    ];

    // Only include transitDateTime if provided
    if (!empty($ezhp_transit_datetime)) {
        $ezhp_payload['transitDateTime'] = $ezhp_transit_datetime;
    }

    $ezhp_api_key = sanitize_text_field(get_option('ezhp_horoscope_activation_guid', ''));

    $ezhp_api_url = 'https://api.ezhoroscope.com/astrology/birth-chart-image/by-location-styled?apikey=' . rawurlencode($ezhp_api_key);

    // Debug logging (enable WP_DEBUG and WP_DEBUG_LOG in wp-config.php to see)
    if (defined('WP_DEBUG') && WP_DEBUG) {
        // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
        error_log('EZHP Birth Chart - Payload: ' . wp_json_encode($ezhp_payload));
    }

    $ezhp_response = wp_remote_post($ezhp_api_url, [
        'timeout' => 30,
        'headers' => [
            'Content-Type' => 'application/json',
            'Accept'       => 'image/png',
        ],
        'body'    => wp_json_encode($ezhp_payload),
    ]);

    if (is_wp_error($ezhp_response)) {
        return [
            'error' => 'Error contacting API: ' . $ezhp_response->get_error_message(),
        ];
    }

    $ezhp_status_code = wp_remote_retrieve_response_code($ezhp_response);

    if (400 === $ezhp_status_code) {
        $ezhp_error_body = wp_remote_retrieve_body($ezhp_response);
        $ezhp_error_data = json_decode($ezhp_error_body, true);
        
        // Debug logging
        if (defined('WP_DEBUG') && WP_DEBUG) {
            // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
            error_log('EZHP Birth Chart - 400 Error Response: ' . $ezhp_error_body);
        }
        
        $ezhp_error_msg  = isset($ezhp_error_data['error']) ? $ezhp_error_data['error'] : 'Invalid request.';
        return [
            'error' => $ezhp_error_msg,
        ];
    }

    if ($ezhp_status_code < 200 || $ezhp_status_code >= 300) {
        return [
            'error' => 'API returned status code: ' . $ezhp_status_code,
        ];
    }

    $ezhp_image_data = wp_remote_retrieve_body($ezhp_response);
    $ezhp_content_type = wp_remote_retrieve_header($ezhp_response, 'content-type');

    // Check if we got an image
    if (strpos($ezhp_content_type, 'image/png') !== false) {
        // Return as base64 data URL
        // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode
        $ezhp_base64 = base64_encode($ezhp_image_data);
        return [
            'image' => 'data:image/png;base64,' . $ezhp_base64,
        ];
    }

    // Maybe it's JSON with an error
    $ezhp_json_data = json_decode($ezhp_image_data, true);
    if (json_last_error() === JSON_ERROR_NONE && isset($ezhp_json_data['error'])) {
        return [
            'error' => $ezhp_json_data['error'],
        ];
    }

    return [
        'error' => 'Unexpected response from API.',
    ];
}

/**
 * Sanitize style settings array
 *
 * @param array $ezhp_style The style settings array.
 * @return array Sanitized style settings.
 */
function ezhp_sanitize_style_settings( $ezhp_style ) {

    $ezhp_sanitized = [];

    // Handle backgroundColor specially to allow 'transparent'
    if (isset($ezhp_style['backgroundColor'])) {
        if ($ezhp_style['backgroundColor'] === 'transparent') {
            $ezhp_sanitized['backgroundColor'] = 'transparent';
        } else {
            $ezhp_sanitized['backgroundColor'] = sanitize_hex_color($ezhp_style['backgroundColor']);
        }
    }

    // String color fields (excluding backgroundColor which is handled above)
    $ezhp_color_fields = [
        'circleColor',
        'pointsColor',
        'signsColor',
        'cuspsColor',
        'lineColor',
        'axisFontColor',
        'legendFontColor',
        'legendBorderColor',
        'colorAries',
        'colorTaurus',
        'colorGemini',
        'colorCancer',
        'colorLeo',
        'colorVirgo',
        'colorLibra',
        'colorScorpio',
        'colorSagittarius',
        'colorCapricorn',
        'colorAquarius',
        'colorPisces',
    ];

    foreach ($ezhp_color_fields as $ezhp_field) {
        if (isset($ezhp_style[$ezhp_field])) {
            $ezhp_sanitized[$ezhp_field] = sanitize_hex_color($ezhp_style[$ezhp_field]);
        }
    }

    // Float fields
    $ezhp_float_fields = [
        'symbolScale',
        'pointsStroke',
        'signsStroke',
        'circleStrong',
        'cuspsStroke',
        'axisStroke',
        'indoorCircleRadiusRatio',
        'innerCircleRadiusRatio',
        'rulerRadius',
    ];

    foreach ($ezhp_float_fields as $ezhp_field) {
        if (isset($ezhp_style[$ezhp_field])) {
            $ezhp_sanitized[$ezhp_field] = floatval($ezhp_style[$ezhp_field]);
        }
    }

    // Integer fields
    $ezhp_int_fields = [
        'pointsTextSize',
        'margin',
        'padding',
        'collisionRadius',
        'shiftInDegrees',
    ];

    foreach ($ezhp_int_fields as $ezhp_field) {
        if (isset($ezhp_style[$ezhp_field])) {
            $ezhp_sanitized[$ezhp_field] = intval($ezhp_style[$ezhp_field]);
        }
    }

    // Boolean fields
    $ezhp_bool_fields = [
        'transparentBackground',
        'strokeOnly',
        'addClickArea',
        'showDignitiesText',
        'debug',
    ];

    foreach ($ezhp_bool_fields as $ezhp_field) {
        if (isset($ezhp_style[$ezhp_field])) {
            $ezhp_sanitized[$ezhp_field] = (bool) $ezhp_style[$ezhp_field];
        }
    }

    // Sign colors array (alternative to individual color fields)
    // Build from individual colors if not provided as array
    if (isset($ezhp_style['signColors']) && is_array($ezhp_style['signColors'])) {
        $ezhp_sanitized['signColors'] = [];
        foreach ($ezhp_style['signColors'] as $ezhp_color) {
            $ezhp_sanitized['signColors'][] = sanitize_hex_color($ezhp_color);
        }
    } else {
        // Build signColors array from individual zodiac color fields in zodiac order
        $ezhp_zodiac_order = [
            'colorAries',
            'colorTaurus',
            'colorGemini',
            'colorCancer',
            'colorLeo',
            'colorVirgo',
            'colorLibra',
            'colorScorpio',
            'colorSagittarius',
            'colorCapricorn',
            'colorAquarius',
            'colorPisces',
        ];
        $ezhp_sanitized['signColors'] = [];
        foreach ($ezhp_zodiac_order as $ezhp_zodiac_field) {
            if (isset($ezhp_sanitized[$ezhp_zodiac_field])) {
                $ezhp_sanitized['signColors'][] = $ezhp_sanitized[$ezhp_zodiac_field];
            }
        }
    }

    // Aspect colors (object)
    if (isset($ezhp_style['aspectColors']) && is_array($ezhp_style['aspectColors'])) {
        $ezhp_sanitized['aspectColors'] = [];
        foreach ($ezhp_style['aspectColors'] as $ezhp_key => $ezhp_value) {
            $ezhp_sanitized['aspectColors'][sanitize_text_field($ezhp_key)] = sanitize_hex_color($ezhp_value);
        }
    }

    // Aspect configs (object with color and orbit)
    if (isset($ezhp_style['aspectConfigs']) && is_array($ezhp_style['aspectConfigs'])) {
        $ezhp_sanitized['aspectConfigs'] = [];
        foreach ($ezhp_style['aspectConfigs'] as $ezhp_key => $ezhp_config) {
            if (is_array($ezhp_config)) {
                $ezhp_sanitized['aspectConfigs'][sanitize_text_field($ezhp_key)] = [
                    'color' => isset($ezhp_config['color']) ? sanitize_hex_color($ezhp_config['color']) : '',
                    'orbit' => isset($ezhp_config['orbit']) ? floatval($ezhp_config['orbit']) : 10,
                ];
            }
        }
    }

    return $ezhp_sanitized;
}