<?php
/**
 * WP REST API proxy for Humanize Links.
 *
 * Two-step flow: suggest → check-slug → create.
 *
 * @package GoValid_QR
 */

defined( 'ABSPATH' ) || exit;

class GoValid_Link_Rest_Controller {

	private const NAMESPACE = 'govalid-qr/v1';

	/**
	 * Register hooks.
	 */
	public function register(): void {
		add_action( 'rest_api_init', array( $this, 'register_routes' ) );
	}

	/**
	 * Register REST routes.
	 */
	public function register_routes(): void {
		// List links.
		register_rest_route( self::NAMESPACE, '/links', array(
			'methods'             => 'GET',
			'callback'            => array( $this, 'list_links' ),
			'permission_callback' => array( $this, 'check_edit_permission' ),
			'args'                => array(
				'page'     => array(
					'type'              => 'integer',
					'default'           => 1,
					'sanitize_callback' => 'absint',
				),
				'per_page' => array(
					'type'              => 'integer',
					'default'           => 20,
					'sanitize_callback' => 'absint',
				),
				'search'   => array(
					'type'              => 'string',
					'default'           => '',
					'sanitize_callback' => 'sanitize_text_field',
				),
			),
		) );

		// Suggest slugs (Step 1).
		register_rest_route( self::NAMESPACE, '/links/suggest', array(
			'methods'             => 'POST',
			'callback'            => array( $this, 'suggest_link' ),
			'permission_callback' => array( $this, 'check_edit_permission' ),
		) );

		// Check slug availability (Step 2).
		register_rest_route( self::NAMESPACE, '/links/check-slug', array(
			'methods'             => 'GET',
			'callback'            => array( $this, 'check_slug' ),
			'permission_callback' => array( $this, 'check_edit_permission' ),
			'args'                => array(
				'slug'   => array(
					'type'              => 'string',
					'required'          => true,
					'sanitize_callback' => 'sanitize_text_field',
				),
				'domain' => array(
					'type'              => 'string',
					'required'          => true,
					'sanitize_callback' => 'sanitize_text_field',
				),
			),
		) );

		// Create link (Step 3).
		register_rest_route( self::NAMESPACE, '/links/create', array(
			'methods'             => 'POST',
			'callback'            => array( $this, 'create_link' ),
			'permission_callback' => array( $this, 'check_edit_permission' ),
		) );

		// Get link detail.
		register_rest_route( self::NAMESPACE, '/links/(?P<uuid>[a-f0-9-]+)', array(
			'methods'             => 'GET',
			'callback'            => array( $this, 'get_link' ),
			'permission_callback' => array( $this, 'check_edit_permission' ),
			'args'                => array(
				'uuid' => array(
					'type'              => 'string',
					'required'          => true,
					'sanitize_callback' => 'sanitize_text_field',
				),
			),
		) );

		// Update link target URL.
		register_rest_route( self::NAMESPACE, '/links/(?P<uuid>[a-f0-9-]+)/update', array(
			'methods'             => 'POST',
			'callback'            => array( $this, 'update_link' ),
			'permission_callback' => array( $this, 'check_edit_permission' ),
			'args'                => array(
				'uuid' => array(
					'type'              => 'string',
					'required'          => true,
					'sanitize_callback' => 'sanitize_text_field',
				),
			),
		) );

		// Toggle link active/inactive.
		register_rest_route( self::NAMESPACE, '/links/(?P<uuid>[a-f0-9-]+)/toggle', array(
			'methods'             => 'POST',
			'callback'            => array( $this, 'toggle_link' ),
			'permission_callback' => array( $this, 'check_edit_permission' ),
			'args'                => array(
				'uuid' => array(
					'type'              => 'string',
					'required'          => true,
					'sanitize_callback' => 'sanitize_text_field',
				),
			),
		) );

		// Delete link.
		register_rest_route( self::NAMESPACE, '/links/(?P<uuid>[a-f0-9-]+)', array(
			'methods'             => 'DELETE',
			'callback'            => array( $this, 'delete_link' ),
			'permission_callback' => array( $this, 'check_edit_permission' ),
			'args'                => array(
				'uuid' => array(
					'type'              => 'string',
					'required'          => true,
					'sanitize_callback' => 'sanitize_text_field',
				),
			),
		) );

		// Save QR design for a link.
		register_rest_route( self::NAMESPACE, '/links/(?P<uuid>[a-f0-9-]+)/qr-design', array(
			array(
				'methods'             => 'POST',
				'callback'            => array( $this, 'save_qr_design' ),
				'permission_callback' => array( $this, 'check_edit_permission' ),
				'args'                => array(
					'uuid' => array(
						'type'              => 'string',
						'required'          => true,
						'sanitize_callback' => 'sanitize_text_field',
					),
				),
			),
			array(
				'methods'             => 'GET',
				'callback'            => array( $this, 'get_qr_design' ),
				'permission_callback' => array( $this, 'check_edit_permission' ),
				'args'                => array(
					'uuid' => array(
						'type'              => 'string',
						'required'          => true,
						'sanitize_callback' => 'sanitize_text_field',
					),
				),
			),
		) );

		// Get link stats.
		register_rest_route( self::NAMESPACE, '/links/(?P<uuid>[a-f0-9-]+)/stats', array(
			'methods'             => 'GET',
			'callback'            => array( $this, 'get_link_stats' ),
			'permission_callback' => array( $this, 'check_edit_permission' ),
			'args'                => array(
				'uuid' => array(
					'type'              => 'string',
					'required'          => true,
					'sanitize_callback' => 'sanitize_text_field',
				),
			),
		) );
	}

	/**
	 * List links.
	 */
	public function list_links( WP_REST_Request $request ) {
		$api = new GoValid_Link_API();

		if ( ! GoValid_QR::is_connected() ) {
			// Return locally stored anonymous links.
			$links = $api->get_anonymous_links();
			return rest_ensure_response( array(
				'count'       => count( $links ),
				'results'     => $links,
				'page'        => 1,
				'total_pages' => 1,
			) );
		}

		$result = $api->list_links(
			$request->get_param( 'page' ),
			$request->get_param( 'per_page' ),
			$request->get_param( 'search' )
		);

		if ( is_wp_error( $result ) ) {
			return $result;
		}

		return rest_ensure_response( $result );
	}

	/**
	 * Suggest slugs (Step 1).
	 */
	public function suggest_link( WP_REST_Request $request ) {
		$body = $request->get_json_params();

		$url         = isset( $body['url'] ) ? esc_url_raw( $body['url'] ) : '';
		$title       = isset( $body['title'] ) ? sanitize_text_field( $body['title'] ) : '';
		$description = isset( $body['description'] ) ? sanitize_text_field( $body['description'] ) : '';
		$audience    = isset( $body['audience'] ) ? sanitize_text_field( $body['audience'] ) : 'local';

		if ( empty( $url ) ) {
			return new WP_Error(
				'missing_url',
				__( 'Target URL is required.', 'govalid-qr-validator' ),
				array( 'status' => 400 )
			);
		}

		$api = new GoValid_Link_API();

		if ( GoValid_QR::is_connected() ) {
			$result = $api->suggest_link( $url, $title, $description, $audience );
		} else {
			$result = $api->anon_suggest_link( $url, $title, $description, $audience );
		}

		if ( is_wp_error( $result ) ) {
			return $result;
		}

		return rest_ensure_response( $result );
	}

	/**
	 * Check slug availability (Step 2).
	 */
	public function check_slug( WP_REST_Request $request ) {
		$slug   = $request->get_param( 'slug' );
		$domain = $request->get_param( 'domain' );

		$api = new GoValid_Link_API();

		if ( GoValid_QR::is_connected() ) {
			$result = $api->check_slug( $slug, $domain );
		} else {
			$result = $api->anon_check_slug( $slug, $domain );
		}

		if ( is_wp_error( $result ) ) {
			return $result;
		}

		return rest_ensure_response( $result );
	}

	/**
	 * Create a link (Step 3).
	 */
	public function create_link( WP_REST_Request $request ) {
		$body = $request->get_json_params();

		$slug        = isset( $body['slug'] ) ? sanitize_text_field( $body['slug'] ) : '';
		$domain      = isset( $body['domain'] ) ? sanitize_text_field( $body['domain'] ) : '';
		$target_url  = isset( $body['target_url'] ) ? esc_url_raw( $body['target_url'] ) : '';
		$title       = isset( $body['title'] ) ? sanitize_text_field( $body['title'] ) : '';
		$ai_provider = isset( $body['ai_provider'] ) ? sanitize_text_field( $body['ai_provider'] ) : 'manual';

		if ( empty( $slug ) || empty( $domain ) || empty( $target_url ) ) {
			return new WP_Error(
				'missing_fields',
				__( 'Slug, domain, and target URL are required.', 'govalid-qr-validator' ),
				array( 'status' => 400 )
			);
		}

		$api = new GoValid_Link_API();

		if ( GoValid_QR::is_connected() ) {
			$result = $api->create_link( $slug, $domain, $target_url, $title, $ai_provider );
		} else {
			$result = $api->anon_create_link( $slug, $domain, $target_url, $title, $ai_provider );
		}

		if ( is_wp_error( $result ) ) {
			return $result;
		}

		return rest_ensure_response( $result );
	}

	/**
	 * Get a single link.
	 */
	public function get_link( WP_REST_Request $request ) {
		$api    = new GoValid_Link_API();
		$result = $api->get_link_detail( $request->get_param( 'uuid' ) );

		if ( is_wp_error( $result ) ) {
			return $result;
		}

		return rest_ensure_response( $result );
	}

	/**
	 * Update a link's target URL.
	 */
	public function update_link( WP_REST_Request $request ) {
		$body = $request->get_json_params();

		$target_url = isset( $body['target_url'] ) ? esc_url_raw( $body['target_url'] ) : '';
		$title      = isset( $body['title'] ) ? sanitize_text_field( $body['title'] ) : '';

		if ( empty( $target_url ) ) {
			return new WP_Error(
				'missing_target_url',
				__( 'Target URL is required.', 'govalid-qr-validator' ),
				array( 'status' => 400 )
			);
		}

		$api    = new GoValid_Link_API();
		$result = $api->update_link( $request->get_param( 'uuid' ), $target_url, $title );

		if ( is_wp_error( $result ) ) {
			return $result;
		}

		return rest_ensure_response( $result );
	}

	/**
	 * Toggle link active/inactive.
	 */
	public function toggle_link( WP_REST_Request $request ) {
		$api    = new GoValid_Link_API();
		$result = $api->toggle_link( $request->get_param( 'uuid' ) );

		if ( is_wp_error( $result ) ) {
			return $result;
		}

		return rest_ensure_response( $result );
	}

	/**
	 * Delete a link.
	 */
	public function delete_link( WP_REST_Request $request ) {
		$api    = new GoValid_Link_API();
		$result = $api->delete_link( $request->get_param( 'uuid' ) );

		if ( is_wp_error( $result ) ) {
			return $result;
		}

		return rest_ensure_response( $result );
	}

	/**
	 * Get link click statistics.
	 */
	public function get_link_stats( WP_REST_Request $request ) {
		$api    = new GoValid_Link_API();
		$result = $api->get_link_stats( $request->get_param( 'uuid' ) );

		if ( is_wp_error( $result ) ) {
			return $result;
		}

		return rest_ensure_response( $result );
	}

	/**
	 * Save QR design settings for a link (stored locally in WP options).
	 */
	public function save_qr_design( WP_REST_Request $request ) {
		$uuid = $request->get_param( 'uuid' );
		$body = $request->get_json_params();

		$allowed_keys = array(
			'moduleShape', 'outerEye', 'innerEye',
			'moduleColor', 'outerColor', 'innerColor',
			'logoUrl',
		);

		$design = array();
		foreach ( $allowed_keys as $key ) {
			if ( isset( $body[ $key ] ) ) {
				$design[ $key ] = sanitize_text_field( $body[ $key ] );
			}
		}

		if ( empty( $design ) ) {
			return new WP_Error(
				'empty_design',
				__( 'No design settings provided.', 'govalid-qr-validator' ),
				array( 'status' => 400 )
			);
		}

		$all_designs = get_option( 'govalid_qr_designs', array() );
		$all_designs[ $uuid ] = $design;
		update_option( 'govalid_qr_designs', $all_designs, false );

		return rest_ensure_response( array(
			'success' => true,
			'design'  => $design,
		) );
	}

	/**
	 * Get saved QR design settings for a link.
	 */
	public function get_qr_design( WP_REST_Request $request ) {
		$uuid        = $request->get_param( 'uuid' );
		$all_designs = get_option( 'govalid_qr_designs', array() );
		$design      = isset( $all_designs[ $uuid ] ) ? $all_designs[ $uuid ] : null;

		return rest_ensure_response( array(
			'design' => $design,
		) );
	}

	/**
	 * Permission check: can edit posts.
	 */
	public function check_edit_permission(): bool {
		return current_user_can( 'edit_posts' );
	}
}
