<?php
/**
 * Social Share REST API Controller.
 *
 * @package Ugcify\Admin\API
 */

namespace Ugcify\Admin\API;

use Ugcify\Database\ReviewRepository;
use Ugcify\Helpers\FeatureGate;
use Ugcify\Points\PointsManager;
use WP_Error;
use WP_REST_Controller;
use WP_REST_Request;
use WP_REST_Server;

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

/**
 * Class SocialShareAPI
 */
class SocialShareAPI extends WP_REST_Controller {
	/**
	 * Namespace.
	 *
	 * @var string
	 */
	protected $namespace = 'ugcify/v1';

	/**
	 * Rest base.
	 *
	 * @var string
	 */
	protected $rest_base = 'share';

	/**
	 * Review repository.
	 *
	 * @var ReviewRepository
	 */
	private $review_repository;

	/**
	 * Constructor.
	 */
	public function __construct() {
		$this->review_repository = new ReviewRepository();
	}

	/**
	 * Register routes.
	 *
	 * @return void
	 */
	public function register_routes() {
		register_rest_route(
			$this->namespace,
			'/' . $this->rest_base . '/create',
			array(
				array(
					'methods'             => WP_REST_Server::CREATABLE,
					'callback'            => array( $this, 'create_share' ),
					'permission_callback' => '__return_true',
				),
			)
		);

		register_rest_route(
			$this->namespace,
			'/' . $this->rest_base . '/track',
			array(
				array(
					'methods'             => WP_REST_Server::CREATABLE,
					'callback'            => array( $this, 'track_share' ),
					'permission_callback' => '__return_true',
				),
			)
		);
	}

	/**
	 * Create share token + URL.
	 *
	 * @param WP_REST_Request $request Request.
	 * @return array|WP_Error
	 */
	public function create_share( $request ) {
		$params   = (array) $request->get_json_params();
		$review_id = absint( $params['review_id'] ?? 0 );
		$channel   = sanitize_key( (string) ( $params['channel'] ?? '' ) );

		if ( $review_id < 1 ) {
			return new WP_Error( 'invalid_review', __( 'Invalid review.', 'ugcify' ), array( 'status' => 400 ) );
		}

		if ( ! in_array( $channel, array( 'facebook', 'x', 'whatsapp', 'copy_link' ), true ) ) {
			return new WP_Error( 'invalid_channel', __( 'Invalid channel.', 'ugcify' ), array( 'status' => 400 ) );
		}

		$review = $this->review_repository->find( $review_id );
		if ( ! $review ) {
			return new WP_Error( 'not_found', __( 'Review not found.', 'ugcify' ), array( 'status' => 404 ) );
		}

		$review_data = $review->to_array();
		if ( 'approved' !== (string) ( $review_data['status'] ?? '' ) ) {
			return new WP_Error( 'not_approved', __( 'Review is not approved.', 'ugcify' ), array( 'status' => 400 ) );
		}

		$product_id = absint( $review_data['product_id'] ?? 0 );
		$author_id  = absint( get_current_user_id() );
		if ( $product_id < 1 ) {
			return new WP_Error( 'invalid_product', __( 'Review product missing.', 'ugcify' ), array( 'status' => 400 ) );
		}

		$permalink = get_permalink( $product_id );
		if ( ! $permalink ) {
			return new WP_Error( 'invalid_permalink', __( 'Product URL unavailable.', 'ugcify' ), array( 'status' => 400 ) );
		}

		$token = bin2hex( random_bytes( 16 ) );
		if ( ! $this->review_repository->create_share_token( $review_id, $token, $channel, $author_id, $product_id ) ) {
			return new WP_Error( 'share_create_failed', __( 'Could not create share token.', 'ugcify' ), array( 'status' => 500 ) );
		}

		$share_url = add_query_arg(
			array(
				'ugc_share' => $token,
			),
			$permalink
		);

		return rest_ensure_response(
			array(
				'success'   => true,
				'share_url' => esc_url_raw( $share_url ),
				'token'     => $token,
			)
		);
	}

	/**
	 * Track click landing for share token.
	 *
	 * @param WP_REST_Request $request Request.
	 * @return array|WP_Error
	 */
	public function track_share( $request ) {
		$params = (array) $request->get_json_params();
		$token  = sanitize_key( (string) ( $params['token'] ?? '' ) );

		if ( '' === $token ) {
			return new WP_Error( 'invalid_token', __( 'Invalid token.', 'ugcify' ), array( 'status' => 400 ) );
		}

		$meta = $this->review_repository->find_by_share_token( $token );
		if ( ! is_array( $meta ) ) {
			return new WP_Error( 'not_found', __( 'Share token not found.', 'ugcify' ), array( 'status' => 404 ) );
		}

		if ( ! empty( $meta['expires_at'] ) && is_string( $meta['expires_at'] ) && strtotime( $meta['expires_at'] ) < time() ) {
			return new WP_Error( 'expired_token', __( 'Share token expired.', 'ugcify' ), array( 'status' => 410 ) );
		}

		$this->review_repository->increment_share_click( $token );

		$rate_limited = (bool) get_transient( 'ugcify_share_track_' . $token );
		set_transient( 'ugcify_share_track_' . $token, '1', 10 );

		$awarded_click = false;
		$author_id     = absint( $meta['author_id'] ?? 0 );
		$review_id     = absint( $meta['review_id'] ?? 0 );
		$click_awarded = ! empty( $meta['awarded']['click'] );

		// Never award click points if the person clicking is the same person
		// who created the share link.
		$current_user_id   = get_current_user_id();
		$is_self_click     = $author_id > 0 && $current_user_id > 0 && $current_user_id === $author_id;

		if ( ! $is_self_click && ! $rate_limited && ! $click_awarded && $author_id > 0 && FeatureGate::is_enabled( 'advanced_gamification' ) && class_exists( '\\Ugcify\\Points\\PointsManager' ) ) {
			$manager       = new PointsManager();
			$awarded_click = ! empty(
				$manager->credit_with_reference_key(
					$author_id,
					'pts_share_click',
					__( 'Social share link clicked', 'ugcify' ),
					$review_id,
					'social_share_click',
					sprintf( 'social_share_click:pts_share_click:%s', $token ),
					array( 'token' => $token )
				)
			);
			if ( $awarded_click ) {
				$meta['awarded']['click'] = true;
				$this->review_repository->update_share_token_meta( $token, $meta );
			}
		}

		return rest_ensure_response(
			array(
				'success' => true,
				'data'    => array(
					'review_id'      => $review_id,
					'product_id'     => absint( $meta['product_id'] ?? 0 ),
					'author_id'      => $author_id,
					'awarded_click'  => $awarded_click,
					'rate_limited'   => $rate_limited,
					'self_click'     => $is_self_click,
				),
			)
		);
	}
}
