<?php
// DESCRIPTION: REST API endpoint for sending test data to Google Sheets. Runs synchronously
// (not via Action Scheduler) so the user gets instant feedback on success/failure.

namespace SheetWise\Api;

use SheetWise\Admin\GoogleSheet;
use SheetWise\Sync\RetryHandler;
use SheetWise\Sync\SyncLogger;
use SheetWise\Sync\TestDataGenerator;
use SheetWise\Vendor\Google\Service\Sheets\ValueRange;
use WP_REST_Server;

class TestSync extends Swise_REST_Controller {

	/**
	 * Route name
	 *
	 * @since 2.0.0
	 *
	 * @var string
	 */
	protected $base = 'test-sync';

	/**
	 * Register routes
	 *
	 * @since 2.0.0
	 *
	 * @return void
	 */
	public function register_routes() {
		register_rest_route(
			$this->namespace,
			'/' . $this->base . '/(?P<id>[\d]+)',
			[
				[
					'methods'             => WP_REST_Server::CREATABLE,
					'callback'            => [ $this, 'send_test' ],
					'permission_callback' => [ $this, 'permission_check' ],
				],
			]
		);

		register_rest_route(
			$this->namespace,
			'/' . $this->base,
			[
				[
					'methods'             => WP_REST_Server::CREATABLE,
					'callback'            => [ $this, 'send_test_from_config' ],
					'permission_callback' => [ $this, 'permission_check' ],
				],
			]
		);
	}

	/**
	 * Send test data to Google Sheets using inline form config
	 *
	 * Used on the create form where no integration ID exists yet. Accepts
	 * source, sheet, and event_codes directly from the request body.
	 *
	 * @since 2.0.0
	 *
	 * @param \WP_REST_Request $request
	 *
	 * @return \WP_REST_Response
	 */
	public function send_test_from_config( $request ) {
		$body = json_decode( $request->get_body(), true );

		$source      = isset( $body['source'] ) ? sanitize_text_field( $body['source'] ) : '';
		$sheet_id    = isset( $body['sheet'] ) ? sanitize_text_field( $body['sheet'] ) : '';
		$event_codes = isset( $body['event_codes'] ) ? array_map( 'sanitize_text_field', $body['event_codes'] ) : [];

		$generator = new TestDataGenerator();
		$test_data = $generator->generate_from_config( $source, $sheet_id, $event_codes );

		if ( ! $test_data ) {
			return rest_ensure_response( [
				'code'    => 400,
				'success' => false,
				'message' => __( 'Could not generate test data. Make sure you have selected a data source, spreadsheet, and configured at least one column mapping.', 'sheet-wise' ),
			] );
		}

		return $this->execute_test_sync( $test_data, 0 );
	}

	/**
	 * Send test data to Google Sheets for a specific integration
	 *
	 * @since 2.0.0
	 *
	 * @param \WP_REST_Request $request
	 *
	 * @return \WP_REST_Response
	 */
	public function send_test( $request ) {
		$integration_id = $request->get_param( 'id' );

		$generator = new TestDataGenerator();
		$test_data = $generator->generate_for_integration( $integration_id );

		if ( ! $test_data ) {
			return rest_ensure_response( [
				'code'    => 400,
				'success' => false,
				'message' => __( 'Could not generate test data. Make sure the integration has a valid data source and sheet configured.', 'sheet-wise' ),
			] );
		}

		return $this->execute_test_sync( $test_data, $integration_id );
	}

	/**
	 * Execute the test sync against Google Sheets API
	 *
	 * Shared logic used by both the ID-based and inline-config test sync endpoints.
	 *
	 * @since 2.0.0
	 *
	 * @param array $test_data       Array with 'values', 'sheet_id', 'hook' keys
	 * @param int   $integration_id  The integration post ID (0 if unsaved)
	 *
	 * @return \WP_REST_Response
	 */
	private function execute_test_sync( $test_data, $integration_id ) {
		$spreadsheet_id = $test_data['sheet_id'];
		$values         = $test_data['values'];
		$hook           = $test_data['hook'];

		$value_range = new ValueRange();
		$value_range->setValues( [ $values ] );

		$sheet       = new GoogleSheet( $spreadsheet_id );
		$service     = $sheet->get_service();
		$sheet_title = apply_filters( 'swise_sheet_title_' . $hook, 'Sheet1', $spreadsheet_id );

		// Use RetryHandler with reduced retries for test sync (1 retry max)
		add_filter( 'swise_retry_settings', function ( $settings ) {
			$settings['max_retries'] = 1;

			return $settings;
		} );

		$retry_handler = new RetryHandler();
		$context       = [
			'integration_id' => $integration_id,
			'hook'           => $hook,
			'data_payload'   => $values,
			'spreadsheet_id' => $spreadsheet_id,
			'sheet_title'    => $sheet_title,
			'is_test'        => true,
		];

		$result = $retry_handler->execute(
			function () use ( $service, $spreadsheet_id, $sheet_title, $value_range ) {
				return $service->spreadsheets_values->append(
					$spreadsheet_id, $sheet_title, $value_range, [ 'valueInputOption' => 'USER_ENTERED' ]
				);
			},
			$context
		);

		// Log the test sync result
		$logger = new SyncLogger();
		$logger->log( [
			'integration_id' => $integration_id,
			'hook'           => $hook,
			'status'         => $result['status'],
			'attempts'       => $result['attempts'],
			'error_message'  => $result['error']['message'] ?? null,
			'error_code'     => isset( $result['error']['code'] ) ? (string) $result['error']['code'] : null,
			'data_payload'   => $values,
			'row_count'      => $result['status'] === 'success' ? 1 : 0,
		] );

		if ( $result['status'] === 'success' ) {
			return rest_ensure_response( [
				'code'    => 200,
				'success' => true,
				'message' => __( 'Test data sent successfully to your spreadsheet.', 'sheet-wise' ),
			] );
		}

		return rest_ensure_response( [
			'code'    => 400,
			'success' => false,
			'message' => sprintf(
				/* translators: %s: error message */
				__( 'Test sync failed: %s', 'sheet-wise' ),
				$result['error']['message'] ?? __( 'Unknown error', 'sheet-wise' )
			),
		] );
	}
}
