<?php
/**
 * AG WP Plugin Install Manager — プラグイン一覧テーブルクラス。
 *
 * WP_List_Table を拡張し、登録されたプラグインの
 * 一覧表示・フィルタ・バルク操作を担う。
 *
 * @package AG_WP_Plugin_Install_Manager
 */

// WordPress 外からの直接アクセスを禁止。
if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

// WP_List_Table が未読み込みの場合は読み込む。
if ( ! class_exists( 'WP_List_Table' ) ) {
	require_once ABSPATH . 'wp-admin/includes/class-wp-list-table.php';
}

if ( ! class_exists( 'AG_WP_Plugin_List_Table' ) ) {

	/**
	 * プラグイン一覧テーブルクラス。
	 *
	 * @since 1.0.0
	 */
	class AG_WP_Plugin_List_Table extends WP_List_Table {

		/**
		 * コアクラスのインスタンス。
		 *
		 * @since 1.0.0
		 * @var AG_WP_Plugin_Install_Manager
		 */
		protected $manager;

		/**
		 * 現在選択中のフィルタータブ。
		 *
		 * @since 1.0.0
		 * @var string
		 */
		protected $current_filter = 'all';

		/**
		 * コンストラクタ。
		 *
		 * @since 1.0.0
		 *
		 * @param AG_WP_Plugin_Install_Manager $manager コアクラスのインスタンス。
		 */
		public function __construct( AG_WP_Plugin_Install_Manager $manager ) {
			$this->manager = $manager;

			parent::__construct(
				array(
					'singular' => 'plugin',
					'plural'   => 'plugins',
					'ajax'     => false,
				)
			);
		}

		/**
		 * テーブルのカラム定義を返す。
		 *
		 * @since 1.0.0
		 * @return array<string, string>
		 */
		public function get_columns() {
			return array(
				'cb'     => '<input type="checkbox" />',
				'name'   => __( 'プラグイン名', AG_WPIM_TEXTDOMAIN ),
				'type'   => __( '種別', AG_WPIM_TEXTDOMAIN ),
				'status' => __( '状態', AG_WPIM_TEXTDOMAIN ),
				'action' => __( 'アクション', AG_WPIM_TEXTDOMAIN ),
			);
		}

		/**
		 * ソート可能なカラムを返す。
		 *
		 * @since 1.0.0
		 * @return array<string, array>
		 */
		protected function get_sortable_columns() {
			return array(
				'name' => array( 'name', true ),
				'type' => array( 'type', false ),
			);
		}

		/**
		 * バルク操作の定義を返す。
		 *
		 * @since 1.0.0
		 * @return array<string, string>
		 */
		protected function get_bulk_actions() {
			return array(
				'install-activate' => __( 'インストールして有効化', AG_WPIM_TEXTDOMAIN ),
				'activate'         => __( '有効化', AG_WPIM_TEXTDOMAIN ),
			);
		}

		/**
		 * フィルタータブ（ビュー）を返す。
		 *
		 * @since 1.0.0
		 * @return array<string, string>
		 */
		protected function get_views() {
			$config      = $this->manager->get_config();
			$base_url    = admin_url( $config['parent_slug'] . '?page=' . $config['menu_slug'] );
			$all         = count( $this->manager->get_plugins() );
			$missing     = count( $this->manager->get_plugins_by_status( 'missing' ) );
			$inactive    = count( $this->manager->get_plugins_by_status( 'inactive' ) );
			$active      = count( $this->manager->get_plugins_by_status( 'active' ) );

			$current = isset( $_GET['plugin_status'] ) ? sanitize_key( $_GET['plugin_status'] ) : 'all'; // phpcs:ignore WordPress.Security.NonceVerification

			$views = array(
				'all' => sprintf(
					'<a href="%s"%s>%s <span class="count">(%d)</span></a>',
					esc_url( $base_url ),
					'all' === $current ? ' class="current"' : '',
					esc_html__( 'すべて', AG_WPIM_TEXTDOMAIN ),
					$all
				),
			);

			if ( $missing > 0 ) {
				$views['missing'] = sprintf(
					'<a href="%s"%s>%s <span class="count">(%d)</span></a>',
					esc_url( add_query_arg( 'plugin_status', 'missing', $base_url ) ),
					'missing' === $current ? ' class="current"' : '',
					esc_html__( '未インストール', AG_WPIM_TEXTDOMAIN ),
					$missing
				);
			}

			if ( $inactive > 0 ) {
				$views['inactive'] = sprintf(
					'<a href="%s"%s>%s <span class="count">(%d)</span></a>',
					esc_url( add_query_arg( 'plugin_status', 'inactive', $base_url ) ),
					'inactive' === $current ? ' class="current"' : '',
					esc_html__( '未有効化', AG_WPIM_TEXTDOMAIN ),
					$inactive
				);
			}

			if ( $active > 0 ) {
				$views['active'] = sprintf(
					'<a href="%s"%s>%s <span class="count">(%d)</span></a>',
					esc_url( add_query_arg( 'plugin_status', 'active', $base_url ) ),
					'active' === $current ? ' class="current"' : '',
					esc_html__( '有効', AG_WPIM_TEXTDOMAIN ),
					$active
				);
			}

			return $views;
		}

		/**
		 * テーブルのデータを準備する。
		 *
		 * @since 1.0.0
		 * @return void
		 */
		public function prepare_items() {
			$filter  = isset( $_GET['plugin_status'] ) ? sanitize_key( $_GET['plugin_status'] ) : 'all'; // phpcs:ignore WordPress.Security.NonceVerification
			$plugins = 'all' === $filter
				? $this->manager->get_plugins()
				: $this->manager->get_plugins_by_status( $filter );

			$this->_column_headers = array(
				$this->get_columns(),
				array(),
				$this->get_sortable_columns(),
			);

			$this->items = array_values( $plugins );
		}

		/**
		 * チェックボックスカラムの出力。
		 *
		 * @since 1.0.0
		 *
		 * @param array $item プラグインデータ。
		 * @return string
		 */
		protected function column_cb( $item ) {
			return sprintf(
				'<input type="checkbox" name="plugins[]" value="%s" />',
				esc_attr( $item['slug'] )
			);
		}

		/**
		 * プラグイン名カラムの出力。
		 *
		 * @since 1.0.0
		 *
		 * @param array $item プラグインデータ。
		 * @return string
		 */
		protected function column_name( $item ) {
			$name = esc_html( $item['name'] );

			if ( ! empty( $item['version'] ) ) {
				$name .= ' <span class="ag-wpim-version">'
					. sprintf(
						/* translators: %s: バージョン番号 */
						esc_html__( '（%s以上）', AG_WPIM_TEXTDOMAIN ),
						esc_html( $item['version'] )
					)
					. '</span>';
			}

			return $name;
		}

		/**
		 * 種別カラムの出力。
		 *
		 * @since 1.0.0
		 *
		 * @param array $item プラグインデータ。
		 * @return string
		 */
		protected function column_type( $item ) {
			if ( ! empty( $item['required'] ) ) {
				return '<span class="ag-wpim-badge ag-wpim-badge--required">'
					. esc_html__( '必須', AG_WPIM_TEXTDOMAIN )
					. '</span>';
			}

			return '<span class="ag-wpim-badge ag-wpim-badge--recommended">'
				. esc_html__( '推奨', AG_WPIM_TEXTDOMAIN )
				. '</span>';
		}

		/**
		 * 状態カラムの出力。
		 *
		 * @since 1.0.0
		 *
		 * @param array $item プラグインデータ。
		 * @return string
		 */
		protected function column_status( $item ) {
			$slug   = $item['slug'];
			$status = $this->manager->get_plugin_status( $slug );

			$labels = array(
				'active'   => array( 'label' => __( '有効', AG_WPIM_TEXTDOMAIN ), 'class' => 'active' ),
				'inactive' => array( 'label' => __( '無効', AG_WPIM_TEXTDOMAIN ), 'class' => 'inactive' ),
				'missing'  => array( 'label' => __( '未インストール', AG_WPIM_TEXTDOMAIN ), 'class' => 'missing' ),
			);

			$info = $labels[ $status ] ?? $labels['missing'];

			return '<span class="ag-wpim-status ag-wpim-status--' . esc_attr( $info['class'] ) . '">'
				. esc_html( $info['label'] )
				. '</span>';
		}

		/**
		 * アクションカラムの出力。
		 *
		 * @since 1.0.0
		 *
		 * @param array $item プラグインデータ。
		 * @return string
		 */
		protected function column_action( $item ) {
			$slug      = $item['slug'];
			$status    = $this->manager->get_plugin_status( $slug );
			$config    = $this->manager->get_config();
			$base_url  = admin_url( $config['parent_slug'] . '?page=' . $config['menu_slug'] );

			if ( 'active' === $status ) {
				return '<span class="ag-wpim-action-done">'
					. esc_html__( '有効化済み', AG_WPIM_TEXTDOMAIN )
					. '</span>';
			}

			if ( 'inactive' === $status ) {
				$url = wp_nonce_url(
					add_query_arg( array( 'action' => 'activate', 'plugin' => $slug ), $base_url ),
					'ag-wpim-activate-' . $slug
				);
				return '<a href="' . esc_url( $url ) . '" class="button button-small">'
					. esc_html__( '有効化', AG_WPIM_TEXTDOMAIN )
					. '</a>';
			}

			// missing の場合はインストールして有効化ボタン。
			$url = wp_nonce_url(
				add_query_arg( array( 'action' => 'install-activate', 'plugin' => $slug ), $base_url ),
				'ag-wpim-install-activate-' . $slug
			);
			return '<a href="' . esc_url( $url ) . '" class="button button-primary button-small">'
				. esc_html__( 'インストールして有効化', AG_WPIM_TEXTDOMAIN )
				. '</a>';
		}

		/**
		 * データが空のときのメッセージ。
		 *
		 * @since 1.0.0
		 * @return void
		 */
		public function no_items() {
			esc_html_e( '必要なプラグインはすべてインストール・有効化されています。', AG_WPIM_TEXTDOMAIN );
		}
	}
}
