<?php

namespace Ugcify\Rest\V1;

use Ugcify\License\Licensing;
use Ugcify\License\LicenseHelper;
use Ugcify\License\ProFunctions;
use WP_REST_Controller;
use WP_REST_Request;
use WP_REST_Response;
use WP_Error;

defined( 'ABSPATH' ) || exit;

/**
 * REST API endpoints for license management.
 *
 * Base route: /wp-json/ugcify/v1/license/
 *
 * POST   /activate    — Activate a license key via EDD.
 * POST   /deactivate  — Deactivate the currently stored license.
 * GET    /status      — Return full license status and plan info.
 * POST   /check       — Perform a live remote license check.
 *
 * @since 1.0.0
 * @package Ugcify\Rest\V1
 */
class LicenseController extends WP_REST_Controller {

	/**
	 * REST namespace.
	 *
	 * @var string
	 */
	protected $namespace = 'ugcify/v1';

	/**
	 * Resource base.
	 *
	 * @var string
	 */
	protected $rest_base = 'license';

	/**
	 * Permission check — requires manage_options capability.
	 *
	 * @return bool
	 */
	public function check_license_permission() {
		return current_user_can( 'manage_options' );
	}

	/**
	 * Register all routes for this controller.
	 */
	public function register_routes() {
		register_rest_route(
			$this->namespace,
			'/' . $this->rest_base . '/activate',
			array(
				array(
					'methods'             => 'POST',
					'callback'            => array( $this, 'activate_license' ),
					'permission_callback' => array( $this, 'check_license_permission' ),
				),
			)
		);

		register_rest_route(
			$this->namespace,
			'/' . $this->rest_base . '/deactivate',
			array(
				array(
					'methods'             => 'POST',
					'callback'            => array( $this, 'deactivate_license' ),
					'permission_callback' => array( $this, 'check_license_permission' ),
				),
			)
		);

		register_rest_route(
			$this->namespace,
			'/' . $this->rest_base . '/status',
			array(
				array(
					'methods'             => 'GET',
					'callback'            => array( $this, 'get_license_status' ),
					'permission_callback' => array( $this, 'check_license_permission' ),
				),
			)
		);

		register_rest_route(
			$this->namespace,
			'/' . $this->rest_base . '/check',
			array(
				array(
					'methods'             => 'POST',
					'callback'            => array( $this, 'remote_license_check' ),
					'permission_callback' => array( $this, 'check_license_permission' ),
				),
			)
		);
	}

	// =========================================================================
	// Endpoint callbacks
	// =========================================================================

	/**
	 * POST /activate
	 *
	 * Expects body param: license_key (string, possibly masked).
	 *
	 * @param WP_REST_Request $request
	 * @return WP_REST_Response|WP_Error
	 */
	public function activate_license( WP_REST_Request $request ) {
		$raw_key     = $request->get_param( 'license_key' );
		$license_key = ProFunctions::decrypt_key( sanitize_text_field( (string) $raw_key ) );

		if ( empty( $license_key ) ) {
			return new WP_Error(
				'missing_license_key',
				__( 'License key is required.', 'ugcify' ),
				array( 'status' => 400 )
			);
		}

		if ( ! ProFunctions::is_valid_license_format( $license_key ) ) {
			return new WP_Error(
				'invalid_license_format',
				__( 'Invalid license key format.', 'ugcify' ),
				array( 'status' => 400 )
			);
		}

		$licensing = new Licensing();
		$result    = $licensing->process_license_operation( 'activate', $license_key );

		if ( ! $result['success'] ) {
			return new WP_Error(
				'license_activation_failed',
				$result['message'],
				array( 'status' => 400 )
			);
		}

		$needs_pro_install = (bool) get_option( 'ugcify_needs_pro_install' );

		return new WP_REST_Response(
			array(
				'success' => true,
				'message' => $result['message'],
				'data'    => array(
					'status'             => $result['status'],
					'license_key'        => ProFunctions::encrypt_key( Licensing::get_license_key() ),
					'start_date'         => isset( $result['data']['start_date'] ) ? $result['data']['start_date'] : '',
					'end_date'           => isset( $result['data']['end_date'] )   ? $result['data']['end_date']   : '',
					'plan'               => isset( $result['data']['plan'] )       ? $result['data']['plan']       : '',
					'plan_label'         => $this->get_plan_label( isset( $result['data']['plan'] ) ? $result['data']['plan'] : '' ),
					'is_dev_override'    => ! empty( $result['data']['is_dev_override'] ),
					'needs_pro_install'  => $needs_pro_install,
					'pro_install_nonce'  => $needs_pro_install ? wp_create_nonce( 'ugcify_install_pro_build' ) : '',
				),
			),
			200
		);
	}

	/**
	 * POST /deactivate
	 *
	 * Deactivates the currently stored license.
	 *
	 * @param WP_REST_Request $request
	 * @return WP_REST_Response|WP_Error
	 */
	public function deactivate_license( WP_REST_Request $request ) {
		$stored_license = get_option( 'ugcify_pro_license_key', '' );
		$license_key    = ProFunctions::decrypt_key( $stored_license );

		if ( ! ProFunctions::is_valid_license_format( $license_key ) ) {
			return new WP_Error(
				'invalid_license_format',
				__( 'No valid license key found to deactivate.', 'ugcify' ),
				array( 'status' => 400 )
			);
		}

		$licensing = new Licensing();
		$result    = $licensing->process_license_operation( 'deactivate', $license_key );

		if ( ! $result['success'] ) {
			return new WP_Error(
				'license_deactivation_failed',
				$result['message'],
				array( 'status' => 400 )
			);
		}

		// The pro build is detectable by the presence of License/Updater.php, which is
		// stripped from the free build. When it's present we offer to restore the free
		// build from WordPress.org so the site stops running pro-only files.
		$needs_free_install = file_exists( UGCIFY_PATH . 'includes/License/Updater.php' );

		return new WP_REST_Response(
			array(
				'success' => true,
				'message' => $result['message'],
				'data'    => array(
					'status'             => $result['status'],
					'is_dev_override'    => ! empty( $result['data']['is_dev_override'] ),
					'needs_free_install' => $needs_free_install,
					'free_install_nonce' => $needs_free_install ? wp_create_nonce( 'ugcify_install_free_build' ) : '',
				),
			),
			200
		);
	}

	/**
	 * GET /status
	 *
	 * Returns the full stored license state including plan details and expiry.
	 *
	 * @param WP_REST_Request $request
	 * @return WP_REST_Response
	 */
	public function get_license_status( WP_REST_Request $request ) {
		$license_key    = Licensing::get_license_key();
		$license_status = Licensing::get_license_status();
		$license_data   = Licensing::get_license_data();
		$is_premium     = Licensing::is_premium();
		$is_valid       = Licensing::is_license_valid();
		$plan           = isset( $license_data['plan'] ) ? $license_data['plan'] : '';

		$needs_pro_install = (bool) get_option( 'ugcify_needs_pro_install' );

		$response_data = array(
			'license_key'        => ! empty( $license_key ) ? ProFunctions::encrypt_key( $license_key ) : '',
			'status'             => $license_status,
			'is_premium'         => $is_premium,
			'is_valid'           => $is_valid,
			'start_date'         => ! empty( $license_data['start_date'] ) ? $license_data['start_date'] : null,
			'end_date'           => ! empty( $license_data['end_date'] )   ? $license_data['end_date']   : null,
			'last_check'         => ! empty( $license_data['last_check'] ) ? $license_data['last_check'] : null,
			'plan'               => $plan,
			'plan_label'         => $this->get_plan_label( $plan ),
			'plan_features'      => $is_valid ? ( LicenseHelper::get_plan_features()[ $plan ] ?? array() ) : array(),
			'is_expired'         => false,
			'remaining_days'     => 0,
			'is_expiring_soon'   => false,
			'is_dev_override'    => ! empty( $license_data['is_dev_override'] ),
			'needs_pro_install'  => $needs_pro_install,
			'pro_install_nonce'  => $needs_pro_install ? wp_create_nonce( 'ugcify_install_pro_build' ) : '',
		);

		if ( ! empty( $license_data['end_date'] ) ) {
			$response_data['is_expired']       = ProFunctions::is_license_expired( $license_data['end_date'] );
			$response_data['remaining_days']   = ProFunctions::get_license_remaining_days( $license_data['end_date'] );
			$response_data['is_expiring_soon'] = LicenseHelper::is_license_expiring_soon();
		}

		return new WP_REST_Response(
			array(
				'success' => true,
				'data'    => $response_data,
			),
			200
		);
	}

	/**
	 * POST /check
	 *
	 * Performs a live remote status-check against the EDD license server.
	 *
	 * @param WP_REST_Request $request
	 * @return WP_REST_Response
	 */
	public function remote_license_check( WP_REST_Request $request ) {
		$licensing = new Licensing();
		$is_valid  = $licensing->remote_license_check();

		return new WP_REST_Response(
			array(
				'success'  => true,
				'is_valid' => $is_valid,
				'message'  => $is_valid
					? __( 'License is valid.', 'ugcify' )
					: __( 'License is invalid or has expired.', 'ugcify' ),
			),
			200
		);
	}

	// =========================================================================
	// Internal helpers
	// =========================================================================

	/**
	 * Return a human-readable tier label for a plan slug.
	 *
	 * @param string $plan_slug Raw plan slug.
	 * @return string
	 */
	private function get_plan_label( $plan_slug ) {
		$plan_features = LicenseHelper::get_plan_features();

		$labels = array(
			'free'     => __( 'Free', 'ugcify' ),
			'growth'   => __( 'Growth', 'ugcify' ),
			'pro'      => __( 'Pro', 'ugcify' ),
			'business' => __( 'Business', 'ugcify' ),
		);

		if ( ! isset( $plan_features[ $plan_slug ] ) ) {
			return $labels['free'];
		}

		foreach ( array( 'business', 'businesslifetime', 'business-lifetime', 'business_lifetime', 'businessannual', 'business-annual', 'business_annual' ) as $slug ) {
			if ( $plan_slug === $slug ) {
				return $labels['business'];
			}
		}
		foreach ( array( 'pro', 'prolifetime', 'pro-lifetime', 'pro_lifetime', 'proannual', 'pro-annual', 'pro_annual' ) as $slug ) {
			if ( $plan_slug === $slug ) {
				return $labels['pro'];
			}
		}
		foreach ( array( 'growth', 'growthlifetime', 'growth-lifetime', 'growth_lifetime', 'growthannual', 'growth-annual', 'growth_annual' ) as $slug ) {
			if ( $plan_slug === $slug ) {
				return $labels['growth'];
			}
		}

		return $labels['free'];
	}
}
