<?php
/********************************************************************
 * Copyright (C) 2024 Darko Gjorgjijoski (https://darkog.com/)
 * Copyright (C) 2024 IDEOLOGIX MEDIA Dooel (https://ideologix.com/)
 *
 * This file is property of IDEOLOGIX MEDIA Dooel (https://ideologix.com)
 * This file is part of Vimeify Plugin - https://wordpress.org/plugins/vimeify/
 *
 * Vimeify - Formerly "WP Vimeo Videos" is free software: you can redistribute
 * it and/or modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation, either version 2 of the License,
 * or (at your option) any later version.
 *
 * Vimeify - Formerly "WP Vimeo Videos" is distributed in the hope that it
 * will be useful, but WITHOUT ANY WARRANTY; without even the implied
 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this plugin. If not, see <https://www.gnu.org/licenses/>.
 *
 * Code developed by Darko Gjorgjijoski <dg@darkog.com>.
 **********************************************************************/

namespace Vimeify\Core\Backend;

use Vimeify\Core\Abstracts\BaseProvider;
use Vimeify\Core\Components\Database;

class Galleries extends BaseProvider {

	/**
	 * Registers specific piece of functionality
	 * @return void
	 */
	public function register() {
		add_action( 'admin_init', [ $this, 'handle_gallery_actions' ] );
		add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_scripts' ] );
	}

	/**
	 * Enqueue scripts for galleries page
	 * @return void
	 */
	public function enqueue_scripts() {
		if ( ! Ui::is_galleries() ) {
			return;
		}

		wp_enqueue_script( 'jquery-ui-sortable' );
	}

	/**
	 * Handle gallery actions (add, edit, delete)
	 * @return void
	 */
	public function handle_gallery_actions() {
		if ( ! isset( $_GET['page'] ) || $_GET['page'] !== Ui::PAGE_GALLERIES ) {
			return;
		}

		// Handle gallery save
		if ( isset( $_POST['vimeify_save_gallery'] ) && check_admin_referer( 'vimeify_gallery_save' ) ) {
			$this->save_gallery();
		}

		// Handle gallery delete
		if ( isset( $_GET['action'] ) && $_GET['action'] === 'delete' && isset( $_GET['gallery_id'] ) && check_admin_referer( 'delete_gallery_' . $_GET['gallery_id'] ) ) {
			$this->delete_gallery( intval( $_GET['gallery_id'] ) );
		}
	}

	/**
	 * Get gallery types
	 *
	 * Extensible gallery types system. Add custom types via filter.
	 *
	 * Example: Adding "Folder Sync" type from pro version:
	 *
	 * add_filter( 'vimeify_gallery_types', function( $types, $plugin ) {
	 *     $types['folder_sync'] = [
	 *         'id'    => 'folder_sync',
	 *         'label' => __( 'Vimeo Folder Sync', 'vimeify-pro' ),
	 *         'desc'  => __( 'Automatically sync videos from a Vimeo folder', 'vimeify-pro' ),
	 *     ];
	 *     return $types;
	 * }, 10, 2 );
	 *
	 * Then add the UI for folder selection:
	 *
	 * add_action( 'vimeify_gallery_type_content_folder_sync', function( $gallery_id, $is_edit, $plugin ) {
	 *     $vimeo = $plugin->vimeo();
	 *     $folders = $vimeo->get_folders_query();
	 *     $selected_folder = \Vimeify\Core\Backend\Galleries::get_gallery_type_data( $gallery_id, 'folder_uri' );
	 *     ?>
	 *     <div class="postbox vimeify-gallery-type-section" data-type="folder_sync">
	 *         <div class="postbox-header"><h2><?php esc_html_e( 'Vimeo Folder', 'vimeify-pro' ); ?></h2></div>
	 *         <div class="inside" style="padding: 15px;">
	 *             <select name="vimeify_gallery_folder_uri" class="widefat">
	 *                 <option value=""><?php esc_html_e( 'Select a folder...', 'vimeify-pro' ); ?></option>
	 *                 <?php foreach ( $folders['results'] as $folder ) : ?>
	 *                     <option value="<?php echo esc_attr( $folder['uri'] ); ?>" <?php selected( $selected_folder, $folder['uri'] ); ?>>
	 *                         <?php echo esc_html( $folder['name'] ); ?>
	 *                     </option>
	 *                 <?php endforeach; ?>
	 *             </select>
	 *         </div>
	 *     </div>
	 *     <?php
	 * }, 10, 3 );
	 *
	 * And save the folder URI:
	 *
	 * add_action( 'vimeify_save_gallery_type_data', function( $term_id, $gallery_type, $post_data ) {
	 *     if ( $gallery_type === 'folder_sync' && isset( $post_data['vimeify_gallery_folder_uri'] ) ) {
	 *         update_term_meta( $term_id, 'vimeify_gallery_folder_uri', sanitize_text_field( $post_data['vimeify_gallery_folder_uri'] ) );
	 *     }
	 * }, 10, 3 );
	 *
	 * @return array
	 */
	public function get_gallery_types() {
		$types = [
			'selection' => [
				'id'    => 'selection',
				'label' => __( 'Manual Selection', 'vimeify' ),
				'desc'  => __( 'Manually select and order videos for this gallery', 'vimeify' ),
				'premium' => false,
				'settings' => [
					[
						'id'      => 'posts_per_page',
						'label'   => __( 'Videos per page', 'vimeify' ),
						'type'    => 'number',
						'default' => 10,
						'desc'    => __( 'Number of videos to display (Free: max 10)', 'vimeify' ),
						'min'     => 1,
						'max'     => 10,
					],
					[
						'id'      => 'orderby',
						'label'   => __( 'Order By', 'vimeify' ),
						'type'    => 'select',
						'options' => [
							'date'  => __( 'Date', 'vimeify' ),
							'title' => __( 'Title', 'vimeify' ),
						],
						'default' => 'date',
						'desc'    => __( 'Sort videos by', 'vimeify' ),
					],
					[
						'id'      => 'order',
						'label'   => __( 'Order Direction', 'vimeify' ),
						'type'    => 'select',
						'options' => [
							'desc' => __( 'Descending (Newest first)', 'vimeify' ),
							'asc'  => __( 'Ascending (Oldest first)', 'vimeify' ),
						],
						'default' => 'desc',
						'desc'    => __( 'Order direction for videos', 'vimeify' ),
					],
				],
			],
			'folder_sync' => [
				'id'    => 'folder_sync',
				'label' => __( 'Vimeo Folder Sync', 'vimeify' ),
				'desc'  => __( 'Automatically sync videos from a Vimeo folder', 'vimeify' ),
				'premium' => true,
				'settings' => [],
			],
		];

		return apply_filters( 'vimeify_gallery_types', $types, $this->plugin );
	}

	/**
	 * Save gallery
	 * @return void
	 */
	private function save_gallery() {
		$gallery_id = isset( $_POST['gallery_id'] ) ? intval( $_POST['gallery_id'] ) : 0;
		$gallery_name = isset( $_POST['gallery_name'] ) ? sanitize_text_field( $_POST['gallery_name'] ) : '';
		$gallery_type = isset( $_POST['gallery_type'] ) ? sanitize_text_field( $_POST['gallery_type'] ) : 'selection';

		if ( empty( $gallery_name ) ) {
			wp_redirect( add_query_arg( [ 'error' => 'empty_name' ], wp_get_referer() ) );
			exit;
		}

		if ( $gallery_id > 0 ) {
			// Update existing gallery
			$result = wp_update_term( $gallery_id, Database::TAXONOMY_GALLERY, [
				'name' => $gallery_name,
			] );
		} else {
			// Create new gallery
			$result = wp_insert_term( $gallery_name, Database::TAXONOMY_GALLERY );
		}

		if ( is_wp_error( $result ) ) {
			wp_redirect( add_query_arg( [ 'error' => 'save_failed' ], wp_get_referer() ) );
			exit;
		}

		$term_id = $gallery_id > 0 ? $gallery_id : $result['term_id'];

		// Save gallery type
		update_term_meta( $term_id, 'vimeify_gallery_type', $gallery_type );

		// Save type-specific data
		$this->save_gallery_type_data( $term_id, $gallery_type );

		// Save videos (only for selection type) - use taxonomy relationships
		if ( $gallery_type === 'selection' ) {
			$selected_video_ids = isset( $_POST['vimeify_gallery_videos'] ) && is_array( $_POST['vimeify_gallery_videos'] )
				? array_map( 'intval', $_POST['vimeify_gallery_videos'] )
				: [];

			// Get ALL videos currently in this gallery
			$current_videos = get_posts( [
				'post_type'      => Database::POST_TYPE_VIDEO,
				'posts_per_page' => -1,
				'fields'         => 'ids',
				'post_status'    => 'any',
				'tax_query'      => [
					[
						'taxonomy' => Database::TAXONOMY_GALLERY,
						'field'    => 'term_id',
						'terms'    => $term_id,
					],
				],
			] );

			// Remove ALL videos that are not in the new selection
			foreach ( $current_videos as $video_id ) {
				if ( ! in_array( $video_id, $selected_video_ids, true ) ) {
					wp_remove_object_terms( $video_id, $term_id, Database::TAXONOMY_GALLERY );
				}
			}

			// Add selected videos to gallery (append mode to preserve other galleries)
			foreach ( $selected_video_ids as $video_id ) {
				wp_set_object_terms( $video_id, [ $term_id ], Database::TAXONOMY_GALLERY, true );
			}
		}

		// Save settings
		if ( isset( $_POST['vimeify_gallery_settings'] ) && is_array( $_POST['vimeify_gallery_settings'] ) ) {
			$settings = [];
			// Get display style and gallery type from POST to retrieve correct settings fields
			$display_style = isset( $_POST['vimeify_gallery_settings']['display_style'] )
				? sanitize_text_field( $_POST['vimeify_gallery_settings']['display_style'] )
				: 'slider';
			$fields = $this->get_settings_fields( $display_style, $gallery_type );

			foreach ( $fields as $field ) {
				$field_id = $field['id'];

				if ( isset( $_POST['vimeify_gallery_settings'][ $field_id ] ) ) {
					$value = $_POST['vimeify_gallery_settings'][ $field_id ];

					switch ( $field['type'] ) {
						case 'number':
							$int_value = intval( $value );
							// Apply max constraint if specified
							if ( isset( $field['max'] ) && $int_value > $field['max'] ) {
								$int_value = $field['max'];
							}
							$settings[ $field_id ] = $int_value;
							break;
						case 'checkbox':
							$settings[ $field_id ] = (bool) $value;
							break;
						case 'text':
							$settings[ $field_id ] = sanitize_text_field( $value );
							break;
						default:
							$settings[ $field_id ] = sanitize_text_field( $value );
					}
				} else {
					if ( $field['type'] === 'checkbox' ) {
						$settings[ $field_id ] = false;
					}
				}
			}

			update_term_meta( $term_id, 'vimeify_gallery_settings', $settings );
		}

		$redirect_url = add_query_arg( [
			'page' => Ui::PAGE_GALLERIES,
			'action' => 'edit',
			'gallery_id' => $term_id,
			'message' => 'saved'
		], admin_url( 'admin.php' ) );

		wp_redirect( $redirect_url );
		exit;
	}

	/**
	 * Delete gallery
	 * @param int $gallery_id
	 * @return void
	 */
	private function delete_gallery( $gallery_id ) {
		wp_delete_term( $gallery_id, Database::TAXONOMY_GALLERY );

		$redirect_url = add_query_arg( [
			'page' => Ui::PAGE_GALLERIES,
			'message' => 'deleted'
		], admin_url( 'admin.php' ) );

		wp_redirect( $redirect_url );
		exit;
	}

	/**
	 * Get gallery display styles
	 * @return array
	 */
	public function get_display_styles() {
		$styles = [
			'slider' => [
				'id'    => 'slider',
				'label' => __( 'Slider with Thumbnails', 'vimeify' ),
				'desc'  => __( 'Display videos in a slider with thumbnails underneath', 'vimeify' ),
				'premium' => false,
				'settings' => [
					[
						'id'      => 'show_title',
						'label'   => __( 'Show Video Title', 'vimeify' ),
						'type'    => 'checkbox',
						'default' => true,
						'desc'    => __( 'Display video titles in thumbnails', 'vimeify' ),
					],
					[
						'id'      => 'show_date',
						'label'   => __( 'Show Date Posted', 'vimeify' ),
						'type'    => 'checkbox',
						'default' => false,
						'desc'    => __( 'Display date posted in thumbnails', 'vimeify' ),
					],
					[
						'id'      => 'show_description',
						'label'   => __( 'Show Description', 'vimeify' ),
						'type'    => 'checkbox',
						'default' => false,
						'desc'    => __( 'Display video description below main player', 'vimeify' ),
					],
				],
			],
			'playlist' => [
				'id'    => 'playlist',
				'label' => __( 'Playlist (Scrollable Sidebar)', 'vimeify' ),
				'desc'  => __( 'Display main video with scrollable playlist on the side', 'vimeify' ),
				'premium' => true,
				'settings' => [],
			],
		];

		return apply_filters( 'vimeify_gallery_display_styles', $styles, $this->plugin );
	}

	/**
	 * Get settings fields configuration
	 * @param string $display_style Optional display style to get style-specific settings
	 * @param string $gallery_type Optional gallery type to get type-specific settings
	 * @return array
	 */
	public function get_settings_fields( $display_style = '', $gallery_type = '' ) {
		// Common settings (apply to all galleries)
		$fields = [
			[
				'id'      => 'display_style',
				'label'   => __( 'Display Style', 'vimeify' ),
				'type'    => 'select',
				'options' => array_column( $this->get_display_styles(), 'label', 'id' ),
				'default' => 'slider',
				'desc'    => __( 'Choose how to display the gallery', 'vimeify' ),
			],
		];

		// Add gallery type-specific settings if type is specified
		if ( ! empty( $gallery_type ) ) {
			$types = $this->get_gallery_types();
			if ( isset( $types[ $gallery_type ]['settings'] ) ) {
				$fields = array_merge( $fields, $types[ $gallery_type ]['settings'] );
			}
		}

		// Add display style-specific settings if style is specified
		if ( ! empty( $display_style ) ) {
			$styles = $this->get_display_styles();
			if ( isset( $styles[ $display_style ]['settings'] ) ) {
				$fields = array_merge( $fields, $styles[ $display_style ]['settings'] );
			}
		}

		return apply_filters( 'vimeify_gallery_settings_fields', $fields, $display_style, $gallery_type, $this->plugin );
	}

	/**
	 * Save type-specific gallery data
	 * @param int $term_id
	 * @param string $gallery_type
	 * @return void
	 */
	private function save_gallery_type_data( $term_id, $gallery_type ) {
		// Allow extensions to save their own type-specific data
		do_action( 'vimeify_save_gallery_type_data', $term_id, $gallery_type, $_POST );
	}

	/**
	 * Get gallery type
	 * @param int $gallery_id
	 * @return string
	 */
	public static function get_gallery_type( $gallery_id ) {
		$type = get_term_meta( $gallery_id, 'vimeify_gallery_type', true );
		return ! empty( $type ) ? $type : 'selection';
	}

	/**
	 * Get gallery settings
	 * @param int $gallery_id
	 * @return array
	 */
	public static function get_gallery_settings( $gallery_id ) {
		$settings = get_term_meta( $gallery_id, 'vimeify_gallery_settings', true );
		if ( ! is_array( $settings ) ) {
			$settings = [];
		}

		return $settings;
	}

	/**
	 * Get gallery videos
	 * @param int $gallery_id
	 * @return array
	 */
	public static function get_gallery_videos( $gallery_id ) {
		// Check if we need to migrate from old term meta storage
		$old_videos = get_term_meta( $gallery_id, 'vimeify_gallery_videos', true );
		if ( is_array( $old_videos ) && ! empty( $old_videos ) ) {
			// Migrate to taxonomy relationships
			foreach ( $old_videos as $video_id ) {
				wp_set_object_terms( $video_id, [ $gallery_id ], Database::TAXONOMY_GALLERY, true );
			}
			// Remove old meta after migration
			delete_term_meta( $gallery_id, 'vimeify_gallery_videos' );
		}

		// Get video IDs from taxonomy relationship
		$videos = get_posts( [
			'post_type'      => Database::POST_TYPE_VIDEO,
			'posts_per_page' => -1,
			'fields'         => 'ids',
			'post_status'    => 'publish',
			'tax_query'      => [
				[
					'taxonomy' => Database::TAXONOMY_GALLERY,
					'field'    => 'term_id',
					'terms'    => $gallery_id,
				],
			],
		] );

		return is_array( $videos ) ? $videos : [];
	}

	/**
	 * Get gallery type-specific data
	 * @param int $gallery_id
	 * @param string $key
	 * @param mixed $default
	 * @return mixed
	 */
	public static function get_gallery_type_data( $gallery_id, $key, $default = null ) {
		$value = get_term_meta( $gallery_id, 'vimeify_gallery_' . $key, true );
		return ! empty( $value ) ? $value : $default;
	}
}
