<?php

namespace SoftMultimediaPlayer;

defined( 'ABSPATH' ) || exit();

/**
 * Class Ajax.
 */
class Ajax {
	protected static $instance = null;

	/**
	 * Constructor.
	 *
	 * @since 1.0.0
	 */
	public function __construct() {

		// Get Players
		add_action( 'wp_ajax_smp_get_players', array( $this, 'get_players' ) );

		// Update Player
		add_action( 'wp_ajax_smp_update_player', array( $this, 'update_player' ) );

		// Delete Player
		add_action( 'wp_ajax_smp_delete_player', array( $this, 'delete_player' ) );

		// Update Settings
		add_action( 'wp_ajax_smp_update_settings', [ $this, 'update_settings' ] );

		// Get Pages
		add_action( 'wp_ajax_smp_get_pages', [ $this, 'get_pages' ] );

		// Create Page
		add_action( 'wp_ajax_smp_create_page', [ $this, 'create_page' ] );

		// Export Data
		add_action( 'wp_ajax_smp_get_export_data', [ $this, 'export_data' ] );

		// Import Data
		add_action( 'wp_ajax_smp_import_data', [ $this, 'import_data' ] );

		// Get Feed Items
		add_action( 'wp_ajax_smp_get_feed_items', [ $this, 'get_feed_items' ] );
		add_action( 'wp_ajax_nopriv_smp_get_feed_items', [ $this, 'get_feed_items' ] );


		// smp_hide_setup
		add_action( 'wp_ajax_smp_hide_setup', array( $this, 'hide_get_started_setup' ) );
	}

	public function hide_get_started_setup() {
		delete_option( 'smp_show_setup' );

		wp_send_json_success( __( 'Setup hidden successfully.', 'soft-multimedia-player' ) );
	}

	/**
	 * Handles the AJAX request to get players.
	 *
	 * @since 1.0.0
	 */
	public function get_players() {

		// Check nonce
		if ( ! check_ajax_referer( 'multimedia-player', 'nonce', false ) ) {
			wp_send_json_error( __( 'Invalid nonce', 'soft-multimedia-player' ) );
		}

		// Check permission
		if ( ! current_user_can( 'manage_options' ) ) {
			wp_send_json_error( __( 'You do not have permission to get players', 'soft-multimedia-player' ) );
		}

		global $wpdb;

		$table_name = $wpdb->prefix . 'smp_players';

		$players = $wpdb->get_results( "SELECT * FROM $table_name ORDER BY id DESC", ARRAY_A );

		$formatted_players = [];

		if ( ! empty( $players ) ) {
			foreach ( $players as $player ) {
				$formatted_players[] = smp_get_formatted_player( $player );
			}
		}

		wp_send_json_success( $formatted_players );
	}


	/**
	 * Handle AJAX request to update player.
	 *
	 * @param array $data Optional. The posted data.
	 *
	 * @return array|void The updated player data if $data is provided, otherwise void.
	 * @since 1.0.0
	 *
	 */
	public function update_player( $data = null ) {
		global $wpdb;

		$table = $wpdb->prefix . 'smp_players';

		// Verify nonce if $data is not provided (expecting AJAX POST)
		if ( ! $data ) {
			$nonce = ! empty( $_POST['nonce'] ) ? sanitize_text_field( wp_unslash( $_POST['nonce'] ) ) : '';

			if ( ! wp_verify_nonce( $nonce, 'multimedia-player' ) ) {
				wp_send_json_error( __( 'Invalid nonce', 'soft-multimedia-player' ) );
			}
		}

		// Check user capability
		if ( ! current_user_can( 'manage_options' ) ) {
			wp_send_json_error( __( 'You do not have permission to update this player', 'soft-multimedia-player' ) );
		}

		// Decode posted data if not passed as argument
		if ( ! $data ) {
			if ( empty( $_POST['data'] ) ) {
				wp_send_json_error( __( 'No data provided', 'soft-multimedia-player' ) );
			}

			$posted = json_decode( base64_decode( wp_unslash( $_POST['data'] ) ), true );

			if ( ! is_array( $posted ) ) {
				wp_send_json_error( __( 'Invalid data format', 'soft-multimedia-player' ) );
			}
		} else {
			$posted = $data;
		}

		// Set default type
		$type = ! empty( $posted['type'] ) ? sanitize_text_field( $posted['type'] ) : 'audio-player';

		// Sanitize inputs
		$id     = ! empty( $posted['id'] ) ? intval( $posted['id'] ) : 0;
		$title  = ! empty( $posted['title'] ) ? sanitize_text_field( $posted['title'] ) : '';
		$status = ! isset( $posted['status'] ) || ! empty( $posted['status'] );
		$config = ! empty( $posted['config'] ) ? smp_sanitize_array( $posted['config'] ) : $posted;

		// Handle genres creation
		if ( ! empty( $posted['items'] ) && is_array( $posted['items'] ) ) {
			$existing_genres = smp_get_genres();
			$new_genres      = [];

			foreach ( $posted['items'] as $item ) {
				if ( empty( $item['genre'] ) || ! is_array( $item['genre'] ) ) {
					continue;
				}

				foreach ( $item['genre'] as $genre ) {
					$genre = sanitize_text_field( $genre );

					if ( ! in_array( $genre, $existing_genres, true ) ) {
						$new_genres[] = $genre;
					}
				}
			}

			if ( $new_genres ) {
				$saved_genres  = get_option( 'smp_genres', [] );
				$merged_genres = array_unique( array_merge( $saved_genres, $new_genres ) );

				update_option( 'smp_genres', $merged_genres );
			}
		}

		$data_to_save = [
			'title'  => $title,
			'status' => $status,
			'type'   => $type,
			'config' => maybe_serialize( $config ),
		];

		// Insert or update record
		if ( $id > 0 && empty( $data ) ) {
			$updated = $wpdb->update( $table, $data_to_save, [ 'id' => $id ], [ '%s', '%d', '%s', '%s' ], [ '%d' ] );

			if ( false === $updated ) {
				wp_send_json_error( __( 'Failed to update player.', 'soft-multimedia-player' ) );
			}
		} else {
			$inserted = $wpdb->insert( $table, $data_to_save, [ '%s', '%d', '%s', '%s' ] );

			if ( false === $inserted ) {
				wp_send_json_error( __( 'Failed to create player.', 'soft-multimedia-player' ) );
			}

			$id = $wpdb->insert_id;
		}

		// If title is empty, generate default title and update DB
		if ( empty( $title ) ) {

			$default_title = sprintf( 'Player (#%d)', $id );

			$config = array_merge( $config, [
				'id'    => $id,
				'title' => $default_title
			] );

			$wpdb->update(
				$table,
				[
					'title'  => $default_title,
					'config' => maybe_serialize( $config ),
				],
				[ 'id' => $id ],
				[ '%s', '%s' ],
				[ '%d' ]
			);

			$title = $default_title;
		}

		// Prepare return data
		$response = [
			'id'     => $id,
			'title'  => $title,
			'status' => $status,
			'config' => $config,
		];

		if ( ! empty( $data ) ) {
			return $response;
		}

		wp_send_json_success( $response );
	}


	/**
	 * Delete a player through AJAX request.
	 *
	 * @since 1.0.0
	 */
	public function delete_player() {

		// Check nonce
		if ( ! check_ajax_referer( 'multimedia-player', 'nonce', false ) ) {
			wp_send_json_error( __( 'Invalid nonce', 'soft-multimedia-player' ) );
		}

		if ( ! current_user_can( 'manage_options' ) ) {
			wp_send_json_error( __( 'You do not have permission to delete this player', 'soft-multimedia-player' ) );
		}

		$player_id = ! empty( $_POST['id'] ) ? intval( $_POST['id'] ) : '';

		global $wpdb;
		$table = $wpdb->prefix . 'smp_players';

		$wpdb->delete( $table, [ 'id' => $player_id ] );

		wp_send_json_success( [ 'success' => true ] );
	}

	/**
	 * Handles the AJAX request to update the plugin settings.
	 *
	 * @since 1.0.0
	 */
	public function update_settings() {
		// Check nonce
		if ( ! check_ajax_referer( 'multimedia-player', 'nonce', false ) ) {
			wp_send_json_error( __( 'Invalid nonce', 'soft-multimedia-player' ) );
		}

		// Check permission
		if ( ! current_user_can( 'manage_options' ) ) {
			wp_send_json_error( __( 'You do not have permission to update settings', 'soft-multimedia-player' ) );
		}

		$data = ! empty( $_POST['data'] ) ? smp_sanitize_array( $_POST['data'] ) : array();

		update_option( 'smp_settings', $data );

		wp_send_json_success( [ 'success' => true ] );
	}

	public function get_pages() {
		// Check nonce
		if ( ! check_ajax_referer( 'multimedia-player', 'nonce', false ) ) {
			wp_send_json_error( __( 'Invalid nonce', 'soft-multimedia-player' ) );
		}

		$pages = get_posts( [
			'post_type'      => 'page',
			'post_status'    => 'publish',
			'posts_per_page' => 100,
			'fields'         => [ 'ID', 'post_title' ],
		] );

		if ( empty( $pages ) ) {
			wp_send_json_success( [] );
		}

		$formatted = array_map( function ( $page ) {
			return [
				'id'    => $page->ID,
				'title' => esc_html( $page->post_title ),
			];
		}, $pages );

		wp_send_json_success( $formatted );
	}

	public function create_page() {

		// Check nonce
		if ( ! check_ajax_referer( 'multimedia-player', 'nonce', false ) ) {
			wp_send_json_error( __( 'Invalid nonce', 'soft-multimedia-player' ) );
		}

		// Check permission
		if ( ! current_user_can( 'edit_pages' ) ) {
			wp_send_json_error( __( 'Permission denied.', 'soft-multimedia-player' ) );
		}

		$title     = sanitize_text_field( $_POST['title'] ?? '' );
		$player_id = sanitize_text_field( $_POST['id'] ?? '' );

		$post_type = 'page';

		// Check if block editor is enabled for this post-type
		if ( function_exists( 'use_block_editor_for_post_type' ) && use_block_editor_for_post_type( $post_type ) ) {
			$content = sprintf( '<!-- wp:smp/multimedia-player {"id":%d} /-->', $player_id );
		} else {
			$content = sprintf( '[multimedia_player id="%d"]', $player_id );
		}

		$page_id = wp_insert_post( [
			'post_title'   => $title,
			'post_content' => $content,
			'post_status'  => 'draft',
			'post_type'    => $post_type,
		] );

		if ( is_wp_error( $page_id ) ) {
			wp_send_json_error( $page_id->get_error_message() );
		}

		wp_send_json_success( [
			'id'    => $page_id,
			'title' => $title,
		] );
	}

	/**
	 * Handles the AJAX request to export data.
	 *
	 * @param string $type Optional. The type of data to export. Possible values are:
	 *                     'all', 'settings', 'players'. Default is 'all'.
	 *
	 * @return array The exported data.
	 * @since 1.0.0
	 *
	 */
	public function export_data() {

		// Check nonce
		if ( ! check_ajax_referer( 'multimedia-player', 'nonce', false ) ) {
			wp_send_json_error( __( 'Invalid nonce', 'soft-multimedia-player' ) );
		}

		// Check permission
		if ( ! current_user_can( 'manage_options' ) ) {
			wp_send_json_error( __( 'You do not have permission to export data', 'soft-multimedia-player' ) );
		}

		$type = ! empty( $_POST['type'] ) ? sanitize_text_field( wp_unslash( $_POST['type'] ) ) : 'all';

		$export_data = array();

		switch ( $type ) {
			case 'all':
				$export_data['settings'] = smp_get_settings();
				$export_data['players']  = smp_get_players();
				break;

			case 'settings':
				$export_data['settings'] = smp_get_settings();
				break;

			case 'players':
				$export_data['players'] = smp_get_players();
				break;

			default:
				break;
		}

		wp_send_json_success( $export_data );
	}

	/**
	 * Handles the AJAX request to import data.
	 *
	 * This function verifies the AJAX request's nonce and user permissions
	 * before importing multimedia player settings and players from POST data.
	 * It updates the options with new settings and truncates the players table
	 * to insert the updated players data.
	 *
	 * @since 1.0.0
	 */
	public function import_data() {

		// Check nonce
		if ( ! check_ajax_referer( 'multimedia-player', 'nonce', false ) ) {
			wp_send_json_error( __( 'Invalid nonce', 'soft-multimedia-player' ) );
		}

		// Check permission
		if ( ! current_user_can( 'manage_options' ) ) {
			wp_send_json_error( __( 'You do not have permission to import data', 'soft-multimedia-player' ) );
		}

		$settings = ! empty( $_POST['data']['settings'] ) ? smp_sanitize_array( $_POST['data']['settings'] ) : [];
		$players  = ! empty( $_POST['data']['players'] ) ? smp_sanitize_array( $_POST['data']['players'] ) : [];

		if ( ! empty( $settings ) ) {
			update_option( 'smp_settings', $settings );
		}

		if ( ! empty( $players ) ) {
			global $wpdb;
			$table = $wpdb->prefix . 'smp_players';

			$wpdb->query( "TRUNCATE TABLE $table" );

			foreach ( $players as $player ) {
				$this->update_player( $player );
			}
		}

		wp_send_json_success();
	}

	/**
	 * Handles the AJAX request to get feed items from a given URL.
	 *
	 * The function verifies the AJAX request's nonce and user permissions
	 * before importing feed items from the given URL.
	 *
	 * @since 1.0.0
	 */
	public function get_feed_items() {
		// Verify nonce for security
		if ( ! check_ajax_referer( 'multimedia-player', 'nonce', false ) ) {
			wp_send_json_error( __( 'Invalid security token.', 'soft-multimedia-player' ) );
		}

		// Get and validate the feed URL
		$url = isset( $_POST['url'] ) ? esc_url_raw( $_POST['url'] ) : '';
		if ( empty( $url ) || ! filter_var( $url, FILTER_VALIDATE_URL ) ) {
			wp_send_json_error( __( 'Invalid feed URL.', 'soft-multimedia-player' ) );
		}

		// Suppress errors and load the RSS feed
		libxml_use_internal_errors( true );
		$feed = simplexml_load_file( $url );
		if ( ! $feed || ! isset( $feed->channel->item ) ) {
			wp_send_json_error( __( 'Failed to load or parse RSS feed.', 'soft-multimedia-player' ) );
		}

		$items     = [];
		$thumbnail = isset( $feed->channel->image->url ) ? (string) $feed->channel->image->url : '';

		foreach ( $feed->channel->item as $item ) {
			if ( empty( $item->enclosure['url'] ) ) {
				continue;
			}

			$items[] = array(
				'title'       => (string) $item->title,
				'desc'        => (string) $item->description,
				'sourceType'  => 'rss-feed',
				'source'      => (string) $item->enclosure['url'],
				'thumbnail'   => $thumbnail,
				'duration'    => (string) $item->enclouser['length'],
				'artist'      => (string) $item->author,
				'album'       => '',
				'genre'       => '',
				'publishDate' => (string) $item->pubDate,
				'episodeLink' => (string) $item->link,
			);
		}

		wp_send_json_success( $items );
	}


	/**
	 * Returns the singleton instance of the Ajax class.
	 *
	 * @return Ajax The instance of the Ajax class.
	 */
	public static function instance() {
		if ( is_null( self::$instance ) ) {
			self::$instance = new self();
		}

		return self::$instance;
	}
}

Ajax::instance();
