<?php
/**
 * Mailchimp Integration REST Controller.
 *
 * @since 2.14.4 [Free]
 *
 * @subpackage Masteriyo\Addons\MailchimpIntegration
 */

namespace Masteriyo\Addons\MailchimpIntegration\Controllers;

defined( 'ABSPATH' ) || exit;

use Masteriyo\Addons\MailchimpIntegration\MailchimpIntegrationSettings;
use Masteriyo\Helper\Permission;
use Masteriyo\Addons\MailchimpIntegration\API\API;
use Masteriyo\RestApi\Controllers\Version1\CrudController;

class MailchimpIntegrationController extends CrudController {

	/**
	 * Endpoint namespace.
	 *
	 * @var string
	 */
	protected $namespace = 'masteriyo/pro/v1';

	/**
	 * Route base.
	 *
	 * @var string
	 */
	protected $rest_base = 'mailchimp-integration';

	/**
	 * Object type.
	 *
	 * @var string
	 */
	protected $object_type = 'mailchimp-integration';

	/**
	 * Permission class.
	 *
	 * @var \Masteriyo\Helper\Permission
	 */
	protected $permission = null;

	/**
	 * API client instance.
	 *
	 * @var \Masteriyo\Addons\MailchimpIntegration\API\API
	 */
	private $api_client;

	/**
	 * Constructor.
	 *
	 * @param \Masteriyo\Helper\Permission $permission
	 */
	public function __construct( ?Permission $permission = null ) {
		$this->permission = $permission;
		$this->api_client = new API( MailchimpIntegrationSettings::get_api_key() );
	}

	/**
	 * Register routes.
	 */
	public function register_routes() {

		// Endpoint to get lists.
		register_rest_route(
			$this->namespace,
			'/' . $this->rest_base . '/lists',
			array(
				array(
					'methods'             => \WP_REST_Server::READABLE,
					'callback'            => array( $this, 'get_lists' ),
					'permission_callback' => array( $this, 'get_items_permissions_check' ),
				),
			)
		);

		// Endpoint to get groups for a given list.
		register_rest_route(
			$this->namespace,
			'/' . $this->rest_base . '/groups',
			array(
				array(
					'methods'             => \WP_REST_Server::READABLE,
					'callback'            => array( $this, 'get_groups' ),
					'permission_callback' => array( $this, 'get_items_permissions_check' ),
					'args'                => array(
						'list_id' => array(
							'required'          => true,
							'validate_callback' => function ( $param ) {
								return ! empty( $param );
							},
						),
					),
				),
			)
		);

		// Endpoint to get interests for a given list and group.
		register_rest_route(
			$this->namespace,
			'/' . $this->rest_base . '/interests',
			array(
				array(
					'methods'             => \WP_REST_Server::READABLE,
					'callback'            => array( $this, 'get_interests' ),
					'permission_callback' => array( $this, 'get_items_permissions_check' ),
					'args'                => array(
						'list_id'  => array(
							'required'          => true,
							'validate_callback' => function ( $param ) {
								return ! empty( $param );
							},
						),
						'group_id' => array(
							'required'          => true,
							'validate_callback' => function ( $param ) {
								return ! empty( $param );
							},
						),
					),
				),
			)
		);

		// Endpoint to connect.
		register_rest_route(
			$this->namespace,
			'/' . $this->rest_base . '/connect',
			array(
				array(
					'methods'             => \WP_REST_Server::CREATABLE,
					'callback'            => array( $this, 'connect' ),
					'permission_callback' => array( $this, 'get_items_permissions_check' ),
				),
			)
		);

		// Endpoint to disconnect.
		register_rest_route(
			$this->namespace,
			'/' . $this->rest_base . '/disconnect',
			array(
				array(
					'methods'             => \WP_REST_Server::DELETABLE,
					'callback'            => array( $this, 'disconnect' ),
					'permission_callback' => array( $this, 'get_items_permissions_check' ),
				),
			)
		);
	}

	/**
	 * Check permissions for requests.
	 *
	 * @param \WP_REST_Request $request The request.
	 * @return bool|\WP_Error
	 */
	public function get_items_permissions_check( $request ) {
		if ( is_null( $this->permission ) ) {
			return new \WP_Error(
				'masteriyo_null_permission',
				__( 'The permission object is missing. Unable to verify access rights.', 'learning-management-system' ),
				array( 'status' => 403 )
			);
		}

		return current_user_can( 'manage_options' ) || current_user_can( 'manage_masteriyo_settings' );
	}

	/**
	 * Get Mailchimp lists.
	 *
	 * This endpoint returns all available lists.
	 *
	 * @param \WP_REST_Request $request The request.
	 * @return \WP_REST_Response
	 */
	public function get_lists( $request ) {

		$force_fetch = masteriyo_string_to_bool( $request->get_param( 'force' ) );
		if ( $force_fetch ) {
			delete_option( 'masteriyo_mailchimp_lists' );
		}

		$list = get_option( 'masteriyo_mailchimp_lists', array() );

		if ( empty( $mailchimp_data['list'] ) ) {
			$lists = $this->api_client->get_all_audiences();
			if ( is_wp_error( $lists ) ) {
				return $lists;
			}
			// Mailchimp returns the lists inside an array key.
			if ( isset( $lists['lists'] ) ) {
				$lists = $lists['lists'];
			}
			$list['list'] = $lists;

			update_option( 'masteriyo_mailchimp_lists', $list );
		}

		return rest_ensure_response( $list );
	}

	/**
	 * Get groups for a given list.
	 *
	 * This endpoint returns the groups (audience categories) for a selected list.
	 *
	 * @param \WP_REST_Request $request The request.
	 * @return \WP_REST_Response
	 */
	public function get_groups( $request ) {

		$list_id = sanitize_text_field( $request->get_param( 'list_id' ) );

		$list_groups = $this->api_client->get_groups( $list_id );

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

		if ( isset( $list_groups['categories'] ) ) {
			$list_groups = $list_groups['categories'];
		}

		return rest_ensure_response( $list_groups );
	}

	/**
	 * Get interests for a given list and group.
	 *
	 * This endpoint returns the interests under a group for the selected list.
	 *
	 * @param \WP_REST_Request $request The request.
	 * @return \WP_REST_Response
	 */
	public function get_interests( $request ) {

		$list_id  = sanitize_text_field( $request->get_param( 'list_id' ) );
		$group_id = sanitize_text_field( $request->get_param( 'group_id' ) );

		$interests = $this->api_client->get_interests( $list_id, $group_id );

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

		if ( isset( $interests['interests'] ) ) {
			$interests = $interests['interests'];
		}

		return rest_ensure_response( $interests );
	}

	/**
	 * Connect to Mailchimp.
	 *
	 * Validates and stores the API key.
	 *
	 * @param \WP_REST_Request $request The request.
	 * @return \WP_REST_Response
	 */
	public function connect( $request ) {
		$api_key      = sanitize_text_field( $request['api_key'] ?? '' );
		$verify_again = masteriyo_string_to_bool( $request['verify_again'] ?? false );

		if ( $verify_again ) {
			$api_key = MailchimpIntegrationSettings::get_api_key();
		}

		if ( empty( $api_key ) ) {
			return new \WP_Error(
				'masteriyo_invalid_api_key',
				__( 'API key is required to establish a connection.', 'learning-management-system' ),
				array( 'status' => 400 )
			);
		}

		$is_valid = $this->api_client->validate_api_key( $api_key );
		if ( ! $is_valid ) {
			return new \WP_Error(
				'masteriyo_invalid_api_key',
				__( 'The provided API key is invalid. Please verify the key and try again.', 'learning-management-system' ),
				array( 'status' => 401 )
			);
		}

		MailchimpIntegrationSettings::set( 'api_key', $api_key );
		MailchimpIntegrationSettings::set( 'is_connected', true );

		$message = $verify_again
			? __( 'API key re-verified successfully.', 'learning-management-system' )
			: __( 'Connected to Mailchimp successfully.', 'learning-management-system' );

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

	/**
	 * Disconnect from Mailchimp.
	 *
	 * Clears the API key and marks the integration as disconnected.
	 *
	 * @param \WP_REST_Request $request The request.
	 * @return \WP_REST_Response
	 */
	public function disconnect( $request ) {
		MailchimpIntegrationSettings::set( 'api_key', '' );
		MailchimpIntegrationSettings::set( 'is_connected', false );
		MailchimpIntegrationSettings::settings_remove();

		return rest_ensure_response(
			array(
				'success' => true,
				'message' => __( 'Disconnected from Mailchimp successfully.', 'learning-management-system' ),
			)
		);
	}
}
