<?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\Backend\Tools\Migration;
use Vimeify\Core\Components\Database;

class Ui extends BaseProvider {

	const PAGE_VIMEO = 'vimeify';
	const PAGE_UPLOAD = 'vimeify-video';
	const PAGE_GALLERIES = 'vimeify-galleries';
	const PAGE_TOOLS = 'vimeify-tools';
	const PAGE_SETTINGS = 'vimeify';

	public $screen_options;

	/**
	 * Registers specific piece of functionality
	 * @return void
	 */
	public function register() {

		add_action( 'in_admin_header', [ $this, 'do_admin_notices' ], 50 );
		add_action( 'in_admin_header', [ $this, 'render_header_bar_for_wp_pages' ], 1 );
		add_action( 'admin_menu', [ $this, 'register_admin_menu' ], 5 );
		add_action( 'admin_menu', [ $this, 'reorder_tools_menu' ], 999 );
		add_action( 'add_meta_boxes', [ $this, 'register_media_library_upload_metabox' ] );
		add_filter( 'manage_media_columns', [ $this, 'manage_media_columns' ], 15, 1 );
		add_action( 'manage_media_custom_column', [ $this, 'manage_media_custom_column' ], 15, 2 );
		add_filter( 'plugin_action_links_' . $this->plugin->basename(), [ $this, 'plugin_action_links' ], 100, 1 );
		add_filter( 'parent_file', [ $this, 'parent_file' ] );
		add_filter( 'add_menu_classes', [ $this, 'menu_classes' ] );
		add_action( 'admin_init', [ $this, 'redirect_add_new_video' ] );

		// Prevent deletion.
		add_action( 'wp_trash_post', [ $this, 'prevent_deletion_if_used' ], 10, 1 );
		add_action( 'before_delete_post', [ $this, 'prevent_deletion_if_used' ], 10, 1 );
		add_action( 'display_post_states', [ $this, 'display_post_states' ], 10, 2 );

		// Disable 'Quick Edit' and trash for Upload profiles
		add_filter( 'post_row_actions', [ $this, 'remove_post_row_actions' ], 10, 2 );

		// Disable bulk actions for Upload profiles
		add_filter( 'bulk_actions-edit-' . Database::POST_TYPE_UPLOAD_PROFILE, '__return_empty_array' );

		$this->screen_options = new \Vimeify\Core\Utilities\ScreenOptions(
			[
				self::PAGE_VIMEO => [
					'description'              => __( 'Show Description', 'vimeify' ),
					'link_insteadof_shortcode' => __( 'Show Link instead of shortcode', 'vimeify' ),
				]
			]
		);

	}

	/**
	 * Make the $submenu_file to be equal to the
	 * Vimeify submenu links when visited an edit page.
	 *
	 * This will activate the submenu link if admin
	 * uses edit page of that submenu item. Eg. Upload Profiles.
	 *
	 * @param $parent_file
	 *
	 * @return mixed
	 */
	public function parent_file( $parent_file ) {
		global $submenu_file, $pagenow;

		if ( isset( $_GET['taxonomy'] ) && $_GET['taxonomy'] == Database::TAXONOMY_CATEGORY ) {
			$submenu_file = 'edit-tags.php?taxonomy=' . Database::TAXONOMY_CATEGORY . '&post_type=' . Database::POST_TYPE_VIDEO;
		} else if ( isset( $_GET['action'] ) && $_GET['action'] === 'edit' ) {
			global $post;
			if ( ! empty( $post->post_type ) && Database::POST_TYPE_VIDEO === $post->post_type ) {
				$submenu_file = 'edit.php?post_type=' . Database::POST_TYPE_VIDEO;
			}
		}

		return $parent_file;
	}

	/**
	 * Add the needed menu classes
	 *
	 * @param $menu
	 *
	 * @return array|mixed
	 */
	public function menu_classes( $menu ) {
		if ( self::is_upload_profiles() || self::is_categories() || self::is_galleries() ) {
			foreach ( $menu as $i => $item ) {
				if ( 'vimeify' === $item[2] ) {
					$menu[ $i ][4] = add_cssclass( 'wp-has-current-submenu wp-menu-open', $item[4] );
				}
			}
		}

		return $menu;
	}

	/**
	 * Check if page is edit
	 * @return bool
	 */
	public static function is_upload_profiles() {
		global $pagenow;

		return is_admin() && $pagenow === 'post.php' && isset( $_GET['post'] ) && get_post_type( intval( $_GET['post'] ) ) === Database::POST_TYPE_UPLOAD_PROFILE;
	}

	/**
	 * Check if page is categories
	 * @return bool
	 */
	public static function is_categories() {
		global $pagenow;

		return is_admin() && in_array( $pagenow, [
				'edit-tags.php',
				'term.php'
			] ) && isset( $_GET['taxonomy'] ) && $_GET['taxonomy'] === Database::TAXONOMY_CATEGORY;
	}

	/**
	 * Check if page is galleries
	 * @return bool
	 */
	public static function is_galleries() {
		return is_admin() && isset( $_GET['page'] ) && $_GET['page'] === self::PAGE_GALLERIES;
	}

	/**
	 * Register the admin menus
	 *
	 * @since 1.0.0
	 */
	public function register_admin_menu() {

		add_menu_page(
			__( 'Vimeify - Vimeo Uploads', 'vimeify' ),
			__( 'Vimeify', 'vimeify' ),
			'edit_others_posts',
			'vimeify',
			array( $this, 'render_main_page' ),
			$this->plugin->icon( '20' ),
			5
		);

		add_submenu_page( 'vimeify',
			__( 'Vimeify - All Videos', 'vimeify' ),
			__( 'All Videos', 'vimeify' ),
			'edit_others_posts',
			'vimeify'
		);

		add_submenu_page( 'vimeify',
			__( 'Vimeify - All Videos', 'vimeify' ),
			__( 'Upload New', 'vimeify' ),
			'upload_files',
			self::PAGE_UPLOAD,
			array( $this, 'render_upload_page' ),
		);

		add_submenu_page(
			'vimeify',
			__( 'Vimeify - Upload Profiles', 'vimeify' ),
			__( 'Upload Profiles', 'vimeify' ),
			'upload_files',
			'edit.php?post_type=' . Database::POST_TYPE_UPLOAD_PROFILE
		);

		add_submenu_page(
			'vimeify',
			__( 'Vimeify - Categories', 'vimeify' ),
			__( 'Categories' ),
			'edit_others_posts',
			'edit-tags.php?taxonomy=vimeify-category&post_type=' . Database::POST_TYPE_VIDEO
		);

		add_submenu_page(
			'vimeify',
			__( 'Vimeify - Galleries', 'vimeify' ),
			__( 'Galleries', 'vimeify' ),
			'edit_others_posts',
			self::PAGE_GALLERIES,
			array( $this, 'render_galleries_page' )
		);

		add_submenu_page(
			'vimeify',
			__( 'Vimeify - Tools', 'vimeify' ),
			__( 'Tools', 'vimeify' ),
			'manage_options',
			self::PAGE_TOOLS,
			array( $this, 'render_tools_page' )
		);

	}

	/**
	 * Renders the vimeo pages
	 */
	public function render_main_page() {
		$this->plugin->system()->views()->render_view( 'admin/partials/library', [
			'plugin' => $this->plugin,
		] );
	}

	/**
	 * Renders the vimeo pages
	 */
	public function render_upload_page() {
		$this->plugin->system()->views()->render_view( 'admin/partials/library-upload', [
			'plugin' => $this->plugin,
		] );
	}

	/**
	 * Renders the galleries page
	 */
	public function render_galleries_page() {
		$this->plugin->system()->views()->render_view( 'admin/partials/galleries', [
			'plugin' => $this->plugin,
		] );
	}

	/**
	 * Renders the vimeo pages
	 */
	public function render_tools_page() {
		$this->plugin->system()->views()->render_view( 'admin/partials/tools', [
			'plugin' => $this->plugin,
		] );
	}

	/**
	 * Reorder the Tools menu to appear after Settings
	 * @return void
	 */
	public function reorder_tools_menu() {
		global $submenu;

		if ( ! isset( $submenu['vimeify'] ) ) {
			return;
		}

		// Find the Tools menu item
		$tools_item = null;
		$tools_key = null;
		foreach ( $submenu['vimeify'] as $key => $item ) {
			if ( isset( $item[2] ) && $item[2] === self::PAGE_TOOLS ) {
				$tools_item = $item;
				$tools_key = $key;
				break;
			}
		}

		if ( $tools_item && $tools_key !== null ) {
			// Remove Tools from current position
			unset( $submenu['vimeify'][$tools_key] );

			// Find Settings position and insert Tools right after it
			$new_submenu = [];
			foreach ( $submenu['vimeify'] as $key => $item ) {
				$new_submenu[$key] = $item;
				// Insert Tools after Settings
				if ( isset( $item[2] ) && $item[2] === 'vimeify-settings' ) {
					$new_submenu[$tools_key] = $tools_item;
				}
			}

			$submenu['vimeify'] = $new_submenu;
		}
	}

	/**
	 * Unset third party notices.
	 */
	public function do_admin_notices() {
		if ( $this->is_any_page() ) {
			\remove_all_actions( 'admin_notices' );
		}
		do_action( 'vimeify_admin_notices' );
		$this->instructions();
		$this->migration_notice();
	}

	/**
	 * Registers the Media Library Integration Button
	 */
	public function register_media_library_upload_metabox() {
		if ( isset( $_GET['post'] ) && 'attachment' === get_post_type( (int) $_GET['post'] ) ) {
			add_meta_box(
				'vimeify_info_metabox_' . (int) $_GET['post'],
				__( 'WP Vimeo', 'vimeify' ),
				array( $this, 'render_media_library_upload_metabox' ),
				null,
				'side'
			);
		}
	}

	/**
	 * Renders the Media Library Integration Button
	 */
	public function render_media_library_upload_metabox() {
		$attachment_id = isset( $_GET['post'] ) ? intval( $_GET['post'] ) : null;
		if ( ! is_null( $attachment_id ) && 'attachment' === get_post_type( $attachment_id ) ) {
			echo wp_kses(
				sprintf( '<div class="vimeify-mlmb-%s">', esc_attr( $attachment_id ) ) .
				$this->plugin->system()->views()->get_view( 'admin/partials/media-buttons', [
					'id'     => $attachment_id,
					'plugin' => $this->plugin,
				] ) . '</div>',
				wp_kses_allowed_html( 'vimeify' )
			);
		}
	}

	/**
	 * Add WP Vimeo in the Media Library table
	 *
	 * @param $columns
	 *
	 * @return mixed
	 */
	public function manage_media_columns( $columns ) {
		if ( $this->plugin->system()->vimeo()->state->is_connected ) {
			$columns['vimeify_info'] = __( 'WP Vimeo', 'vimeify' );
		}

		return $columns;
	}

	/**
	 * Render WP Vimeo in the Media Library table
	 *
	 * @param $column_name
	 * @param $attachment_id
	 */
	public function manage_media_custom_column( $column_name, $attachment_id ) {
		if ( $this->plugin->system()->vimeo()->state->is_connected ) {
			switch ( $column_name ) {
				case 'vimeify_info':
					echo wp_kses(
						sprintf( '<div id="vimeify-mlmb-%s">', esc_attr( $attachment_id ) ) .
						$this->plugin->system()->views()->get_view( 'admin/partials/media-buttons', [
							'id'     => $attachment_id,
							'plugin' => $this->plugin,
						] ) . '</div>',
						wp_kses_allowed_html( 'vimeify' )
					);
					break;
			}
		}
	}

	/**
	 * Add instructions view
	 */
	public function instructions() {
		if ( ! current_user_can( 'install_plugins' ) || ! $this->needs_to_welcome() ) {
			return;
		}

		// Verify dismiss
		// Render if not dismissed.
		echo wp_kses(
			$this->plugin->system()->views()->get_view(
				'admin/partials/instructions',
				[
					'plugin' => $this->plugin,
					'needs_migration' => $this->needs_migration()
				]
			),
			wp_kses_allowed_html( 'vimeify' )
		);
	}

	/**
	 * Print the migration notice
	 * @return void
	 */
	public function migration_notice() {

		// Do not show notice is welcome is needed because it will be shown in the welcome notice.
		$show_notice = $this->needs_migration() && ! $this->needs_to_welcome();

		if( ! $show_notice ) {
			return;
		}

		echo wp_kses(
			$this->plugin->system()->views()->get_view(
				'admin/partials/migration',
				[
					'plugin' => $this->plugin,
				]
			),
			wp_kses_allowed_html( 'vimeify' )
		);

	}

	/**
	 * Is migration needed?
	 * @return bool
	 */
	public function needs_migration() {

		if(isset($_GET['page']) && $_GET['page'] === self::PAGE_TOOLS) {
			return false;
		}

		$settings = get_option('dgv_settings', []);

		if(!empty($settings)) {
			$status = get_option('vimeify_migration_legacy_migrator', []);
			if(!empty($status['completed_at'])){
				return false;
			} else {
				return true;
			}
		}
		return false;
	}

	/**
	 * Is welcome needed?
	 * @return bool
	 */
	public function needs_to_welcome() {
		return ! ((int) get_option( 'vimeify_welcome' ));
	}

	/**
	 * Add a link to the settings page on the plugins.php page.
	 *
	 * @param array $links List of existing plugin action links.
	 *
	 * @return array         List of modified plugin action links.
	 *
	 */
	public function plugin_action_links( $links ) {
		$links = array_merge( array(
			'<a href="' . esc_url( admin_url( '/admin.php?page=vimeify-settings' ) ) . '">' . __( 'Settings',
				'vimeify' ) . '</a>'
		), $links );

		return $links;
	}

	/**
	 * Is any page?
	 * @return bool
	 */
	public function is_any_page() {
		return is_admin() && isset( $_GET['page'] ) && in_array( $_GET['page'], array(
				self::PAGE_VIMEO,
				self::PAGE_SETTINGS
			) );
	}

	/**
	 * Prevent deletion if used
	 *
	 * @param $post_id
	 *
	 * @return void
	 */
	public function prevent_deletion_if_used( $post_id ) {
		$settings = $this->plugin->system()->settings();
		if ( Database::POST_TYPE_UPLOAD_PROFILE === get_post_type( $post_id ) ) {
			if ( $settings->profile()->in_use( $post_id ) ) {
				wp_die( esc_html__( 'Sorry, you can\'t delete Upload profile that is already in use.', 'vimeify' ) );
			}
		}
	}

	/**
	 * Display the post states
	 *
	 * @param array $post_states
	 * @param \WP_Post $post
	 *
	 * @return array
	 */
	public function display_post_states( $post_states, $post ) {
		if ( Database::POST_TYPE_UPLOAD_PROFILE === $post->post_type ) {
			$settings = $this->plugin->system()->settings();
			if ( $settings->profile()->in_use( $post->ID ) ) {
				$post_states['in_use'] = 'In use';
			}
		}

		return $post_states;
	}

	/**
	 * Removes:
	 *  - Quick edit form certain post types
	 *  - Trash action if used
	 *
	 * @param $actions
	 * @param $post
	 *
	 * @return mixed
	 */
	public function remove_post_row_actions( $actions, $post ) {
		if ( $post->post_type == Database::POST_TYPE_UPLOAD_PROFILE ) {
			// Remove "Quick Edit"
			if ( isset( $actions['inline hide-if-no-js'] ) ) {
				unset( $actions['inline hide-if-no-js'] );
			}

			// Remove trash
			$settings = $this->plugin->system()->settings();
			if ( isset( $actions['trash'] ) && $settings->profile()->in_use( $post->ID ) ) {
				unset( $actions['trash'] );
			}
		}

		return $actions;
	}

	/**
	 * Is the list page?
	 * @return bool
	 */
	public function is_list_page() {
		return $this->is_any_page() && ! isset( $_GET['action'] );
	}

	/**
	 * Is the edit page?
	 * @return bool
	 */
	public function is_edit_page() {
		return $this->is_any_page() && isset( $_GET['action'] ) && 'edit' === $_GET['action'];
	}

	/**
	 * Redirect Add New video attempts to the upload page
	 * @return void
	 */
	public function redirect_add_new_video() {
		global $pagenow;

		// Check if we're on post-new.php for the vimeify_video post type
		if ( $pagenow === 'post-new.php' && isset( $_GET['post_type'] ) && $_GET['post_type'] === Database::POST_TYPE_VIDEO ) {
			wp_redirect( admin_url( 'admin.php?page=' . self::PAGE_UPLOAD ) );
			exit;
		}
	}

	/**
	 * Render header bar for standard WordPress admin pages (Upload Profiles, Categories)
	 * @return void
	 */
	public function render_header_bar_for_wp_pages() {
		// Only render on Upload Profiles (list/edit/new) or Categories pages
		if ( ! self::is_upload_profiles() && ! self::is_upload_profiles_list() && ! self::is_upload_profile_new() && ! self::is_categories() ) {
			return;
		}

		$plugin = $this->plugin;
		include $this->plugin->path() . 'views/admin/partials/header-bar.php';
	}

	/**
	 * Check if page is upload profiles list
	 * @return bool
	 */
	public static function is_upload_profiles_list() {
		global $pagenow;

		return is_admin() && $pagenow === 'edit.php' && isset( $_GET['post_type'] ) && $_GET['post_type'] === Database::POST_TYPE_UPLOAD_PROFILE;
	}

	/**
	 * Check if page is new upload profile
	 * @return bool
	 */
	public static function is_upload_profile_new() {
		global $pagenow;

		return is_admin() && $pagenow === 'post-new.php' && isset( $_GET['post_type'] ) && $_GET['post_type'] === Database::POST_TYPE_UPLOAD_PROFILE;
	}
}