<?php

/**
 * Suppress "error - 0 - No summary was found for this file" on phpdoc generation
 *
 * @package WPDataProjects
 */
namespace WPDataProjects;

use WPDataAccess\Plugin_Table_Models\WPDP_Page_Model;
use WPDataAccess\Plugin_Table_Models\WPDP_Project_Model;
use WPDataAccess\Plugin_Table_Models\WPDP_Project_Design_Table_Model;
use WPDataAccess\Utilities\WPDA_Repository;
use WPDataAccess\WPDA;
use WPDataProjects\Project\WPDP_Project_Project_View;
use WPDataProjects\Project\WPDP_Project_Table_View;
use WPDataAccess\Dashboard\WPDA_Dashboard;
/**
 * Class WPDP
 *
 * Implements Data Projects and Project Templates pages:
 * (1) WPDP_Project_Project_View - To manage Data Projects
 * (2) WPDP_Project_Table_View   - To manage Table Options
 *
 * @author  Peter Schulz
 * @since   2.0.0
 */
class WPDP {
    /**
     * Menu slug of Data Project page
     */
    const PAGE_MAIN = 'wpda_wpdp';

    /**
     * Menu slug of Project Templates page
     */
    const PAGE_TEMPLATES = 'wpda_templates';

    /**
     * Menu slug taken from URL
     *
     * @var null
     */
    protected $page = null;

    /**
     * Templates Page title
     */
    protected $projects_page_title;

    /**
     * Projects Page title
     */
    protected $templates_page_title;

    /**
     * Data Projects menu
     *
     * @var
     */
    protected $wpdp_projects_menu;

    /**
     * Handle to Data Projects view
     *
     * @var
     */
    protected $wpdp_projects_view;

    /**
     * Handle to Project Templates view
     *
     * @var
     */
    protected $wpdp_templates_view;

    /**
     * Used for static pages
     *
     * @var
     */
    protected $wpdp_projects_content;

    /**
     * Array containing all project pages
     *
     * @var
     */
    protected $wpdp_project_menus;

    /**
     * Array containing all project page views
     *
     * @var
     */
    protected $wpdp_project_views;

    protected $wp_admin_toolbar = array();

    protected $main_menu_slug = null;

    /**
     * WPDP constructor
     */
    public function __construct( $main_menu_slug = null ) {
        if ( isset( $_REQUEST['page'] ) ) {
            $this->page = sanitize_text_field( wp_unslash( $_REQUEST['page'] ) );
            // input var okay.
        }
        $this->main_menu_slug = $main_menu_slug;
        $this->projects_page_title = 'Data Projects';
        $this->templates_page_title = 'Project Templates';
    }

    /**
     * Add menu items
     *
     * Adds Data Projects tool to dashboard menu.
     */
    public function add_menu_items() {
        if ( WPDA::current_user_is_admin() ) {
            if ( 'on' === WPDA::get_option( WPDA::OPTION_PLUGIN_HIDE_ADMIN_MENU ) ) {
                // Hide admin menu
                return;
            }
            global $wpdb;
            // Add Data Projects menu
            $this->wpdp_projects_menu = add_submenu_page(
                $this->main_menu_slug,
                'Form Builder',
                'Form Builder',
                'manage_options',
                self::PAGE_MAIN,
                [$this, 'data_projects_page']
            );
            if ( $this->page === self::PAGE_MAIN ) {
                $this->wpdp_projects_view = new WPDP_Project_Project_View([
                    'page_hook_suffix' => $this->wpdp_projects_menu,
                    'table_name'       => $wpdb->prefix . 'wpda_project',
                    'edit_form_class'  => 'WPDataProjects\\Project\\WPDP_Project_Project_Form',
                    'list_table_class' => 'WPDataProjects\\Project\\WPDP_Project_Project_List',
                    'title'            => $this->projects_page_title,
                ]);
            }
            // Add Project Templates menu
            $this->wpdp_projects_menu = add_submenu_page(
                $this->main_menu_slug,
                'Form Templates',
                'Form Templates',
                'manage_options',
                self::PAGE_TEMPLATES,
                [$this, 'project_templates_page']
            );
            if ( $this->page === self::PAGE_TEMPLATES ) {
                $this->wpdp_templates_view = new WPDP_Project_Table_View([
                    'page_hook_suffix' => $this->wpdp_projects_menu,
                    'table_name'       => $wpdb->prefix . 'wpda_project_table',
                    'list_table_class' => 'WPDataProjects\\Project\\WPDP_Project_Table_List',
                    'edit_form_class'  => 'WPDataProjects\\Project\\WPDP_Project_Table_Form',
                    'title'            => $this->templates_page_title,
                    'subtitle'         => '',
                ]);
            }
        }
    }

    /**
     * Implementation of the Data Projects page
     */
    public function data_projects_page() {
        WPDA_Dashboard::add_dashboard();
        // Check for repository tables to prevent dashboard errors.
        if ( WPDP_Project_Design_Table_Model::table_exists() && WPDP_Project_Model::table_exists() ) {
            $this->wpdp_projects_view->show();
        } else {
            $this->data_projects_page_not_found();
        }
    }

    /**
     * Implementation of the Project Templates page
     */
    public function project_templates_page() {
        WPDA_Dashboard::add_dashboard();
        // Check for repository tables to prevent dashboard errors.
        if ( WPDP_Page_Model::table_exists() ) {
            $this->wpdp_templates_view->show();
        } else {
            $this->data_projects_page_not_found();
        }
    }

    /**
     * Data Designer repository table not found
     */
    public function data_projects_page_not_found() {
        $wpda_repository = new WPDA_Repository();
        $wpda_repository->inform_user();
        ?>
			<div class="wrap">
				<h1 class="wp-heading-inline">
					<span><?php 
        echo $this->projects_page_title;
        ?></span>
					<a href="<?php 
        echo 'https://wpdataaccess.com/docs/data-forms/data-projects/';
        ?>" target="_blank">
						<span class="dashicons dashicons-editor-help"
							  style="text-decoration:none;vertical-align:top;font-size:30px;">
						</span></a>
				</h1>
				<p>
					<?php 
        echo __( 'ERROR: Repository table(s) not found!', 'wp-data-access' );
        ?>
				</p>
			</div>
			<?php 
    }

    public function project_templates_page_not_found() {
        $wpda_repository = new WPDA_Repository();
        $wpda_repository->inform_user();
        ?>
			<div class="wrap">
				<h1 class="wp-heading-inline">
					<span><?php 
        echo $this->projects_page_title;
        ?></span>
					<a href="<?php 
        echo 'https://wpdataaccess.com/docs/templates/project-templates/';
        ?>" target="_blank">
						<span class="dashicons dashicons-editor-help"
							  style="text-decoration:none;vertical-align:top;font-size:30px;">
						</span></a>
				</h1>
				<p>
					<?php 
        echo __( 'ERROR: Repository table(s) not found!', 'wp-data-access' );
        ?>
				</p>
			</div>
			<?php 
    }

    /**
     * Add projects to menu
     *
     * Menu items are taken from active projects. Project pages marked as "add to menu" are added to the
     * dashboard menu.
     */
    public function add_projects() {
        if ( !is_admin() && 'on' !== WPDA::get_option( WPDA::OPTION_FE_ADD_PROJECTS_TO_TOOLBAR ) ) {
            return;
        }
        // Add project Menus.
        global $wpdb;
        $project_project_table_name = $wpdb->prefix . 'wpda_project';
        $project_page_table_name = $wpdb->prefix . 'wpda_project_page';
        $query_projects = "select * from {$project_project_table_name} where add_to_menu = 'Yes' order by project_sequence";
        $projects = $wpdb->get_results( $query_projects, 'ARRAY_A' );
        // phpcs:ignore Standard.Category.SniffName.ErrorCode
        if ( count( $projects ) > 0 ) {
            //phpcs:ignore - 8.1 proof
            // Check for repository tables to prevent dashboard errors.
            if ( !WPDP_Project_Design_Table_Model::table_exists() || !WPDP_Page_Model::table_exists() ) {
                return;
            }
        }
        foreach ( $projects as $project ) {
            if ( null === $project['menu_name'] || '' === trim( $project['menu_name'] ) ) {
                $menu_name = 'UNNAMED';
            } else {
                $menu_name = $project['menu_name'];
            }
            $user_roles = WPDA::get_current_user_roles();
            if ( false === $user_roles ) {
                // Cannot determine the user role(s). Not able to show project menus.
                break;
            }
            $query_pages = $wpdb->prepare( " select * from {$project_page_table_name} " . " where project_id = %d " . " and add_to_menu = 'Yes' " . " order by page_sequence", [$project['project_id']] );
            $pages = $wpdb->get_results( $query_pages, 'ARRAY_A' );
            // phpcs:ignore Standard.Category.SniffName.ErrorCode
            $project_menu_shown = false;
            foreach ( $pages as $page ) {
                $user_has_role = false;
                if ( '' === $page['page_role'] || null === $page['page_role'] ) {
                    $user_has_role = in_array( 'administrator', $user_roles );
                    //phpcs:ignore - 8.1 proof
                } else {
                    $user_role_array = explode( ',', $page['page_role'] );
                    //phpcs:ignore - 8.1 proof
                    foreach ( $user_role_array as $user_role_array_item ) {
                        $user_has_role = in_array( $user_role_array_item, $user_roles );
                        //phpcs:ignore - 8.1 proof
                        if ( $user_has_role ) {
                            break;
                        }
                    }
                }
                if ( $user_has_role ) {
                    if ( is_admin() ) {
                        $page_name = self::PAGE_MAIN . '_' . $page['project_id'] . '_' . $page['page_id'];
                        $page_schema_name = $page['page_schema_name'];
                        $page_table_name = $page['page_table_name'];
                        $page_type = $page['page_type'];
                        if ( !$project_menu_shown ) {
                            $main_page_name = $page_name;
                            add_menu_page(
                                $menu_name,
                                $menu_name,
                                WPDA::get_current_user_capability(),
                                $main_page_name,
                                null,
                                'dashicons-database-view'
                            );
                            $project_menu_shown = true;
                        }
                        $this->wpdp_project_menus[$page['project_id'] . '_' . $page['page_id']] = add_submenu_page(
                            $main_page_name,
                            $menu_name,
                            $page['page_name'],
                            WPDA::get_current_user_capability(),
                            $page_name,
                            [$this, 'manage_project_page']
                        );
                        if ( $this->page === self::PAGE_MAIN . '_' . $page['project_id'] . '_' . $page['page_id'] ) {
                            if ( 'static' !== $page_type && null !== $page['page_where'] && '' !== $page['page_where'] ) {
                                if ( 'where' === strtolower( substr( str_replace( ' ', '', $page['page_where'] ), 0, 5 ) ) ) {
                                    $where_clause = " {$page['page_where']}";
                                } else {
                                    $where_clause = " where {$page['page_where']} ";
                                }
                                $where_clause = WPDA::substitute_environment_vars( $where_clause );
                            } else {
                                $where_clause = '';
                            }
                            switch ( $page_type ) {
                                case 'static':
                                    $this->wpdp_projects_content[$page['project_id'] . '_' . $page['page_id']] = $page['page_content'];
                                    break;
                                case 'table':
                                    $args = array(
                                        'page_hook_suffix' => $this->wpdp_project_menus[$page['project_id'] . '_' . $page['page_id']],
                                        'wpdaschema_name'  => $page_schema_name,
                                        'table_name'       => $page_table_name,
                                        'project_id'       => $page['project_id'],
                                        'page_id'          => $page['page_id'],
                                        'list_table_class' => 'WPDataProjects\\List_Table\\WPDP_List_Table',
                                        'edit_form_class'  => 'WPDataProjects\\Simple_Form\\WPDP_Simple_Form',
                                        'where_clause'     => $where_clause,
                                        'orderby_clause'   => $page['page_orderby'],
                                    );
                                    if ( 'view' === $page['page_mode'] ) {
                                        $args['allow_update'] = 'off';
                                        $args['allow_import'] = 'off';
                                    }
                                    if ( 'no' === $page['page_allow_insert'] ) {
                                        $args['allow_insert'] = 'off';
                                        $args['allow_import'] = 'off';
                                    }
                                    if ( 'no' === $page['page_allow_delete'] ) {
                                        $args['allow_delete'] = 'off';
                                    }
                                    if ( 'only' === $page['page_allow_insert'] ) {
                                        $args['action'] = 'new';
                                        $args['allow_insert'] = 'only';
                                        $args['allow_update'] = 'off';
                                        $args['allow_import'] = 'off';
                                        $args['allow_delete'] = 'off';
                                    }
                                    if ( 'no' === $page['page_allow_import'] ) {
                                        $args['allow_import'] = 'off';
                                    }
                                    if ( 'no' === $page['page_allow_bulk'] ) {
                                        $args['bulk_actions_enabled'] = false;
                                    }
                                    $this->wpdp_project_views[$page['project_id'] . '_' . $page['page_id']] = new \WPDataProjects\List_Table\WPDP_List_View($args);
                                    break;
                                case 'parent/child':
                                    $args = array(
                                        'page_hook_suffix' => $this->wpdp_project_menus[$page['project_id'] . '_' . $page['page_id']],
                                        'wpdaschema_name'  => $page_schema_name,
                                        'table_name'       => $page_table_name,
                                        'list_table_class' => 'WPDataProjects\\Parent_Child\\WPDP_Parent_List_Table',
                                        'edit_form_class'  => 'WPDataProjects\\Parent_Child\\WPDP_Parent_Form',
                                        'project_id'       => $page['project_id'],
                                        'page_id'          => $page['page_id'],
                                        'where_clause'     => $where_clause,
                                        'orderby_clause'   => $page['page_orderby'],
                                    );
                                    if ( 'view' === $page['page_mode'] ) {
                                        $args['allow_update'] = 'off';
                                        $args['allow_import'] = 'off';
                                    }
                                    if ( 'no' === $page['page_allow_insert'] ) {
                                        $args['allow_insert'] = 'off';
                                        $args['allow_import'] = 'off';
                                    }
                                    if ( 'no' === $page['page_allow_delete'] ) {
                                        $args['allow_delete'] = 'off';
                                    }
                                    if ( 'only' === $page['page_allow_insert'] ) {
                                        $args['action'] = 'new';
                                        $args['allow_insert'] = 'only';
                                        $args['allow_update'] = 'off';
                                        $args['allow_import'] = 'off';
                                        $args['allow_delete'] = 'off';
                                    }
                                    if ( 'no' === $page['page_allow_import'] ) {
                                        $args['allow_import'] = 'off';
                                    }
                                    if ( 'no' === $page['page_allow_bulk'] ) {
                                        $args['bulk_actions_enabled'] = false;
                                    }
                                    $this->wpdp_project_views[$page['project_id'] . '_' . $page['page_id']] = new \WPDataProjects\Parent_Child\WPDP_Parent_List_View($args);
                            }
                        }
                    } else {
                        $page_title = $page['page_title'];
                        if ( null === $page_title || '' === trim( $page_title ) ) {
                            $page_title = 'Untitled';
                        }
                        $title = $project['project_description'];
                        if ( null === $title || '' === trim( $title ) ) {
                            $title = $page_title;
                        }
                        $menu = array(
                            'menu_id'    => self::PAGE_MAIN . '_' . $page['project_id'] . '_' . $page['page_id'],
                            'menu_name'  => $project['menu_name'],
                            'menu_title' => $title,
                            'page_title' => $page_title,
                        );
                        if ( !isset( $this->wp_admin_toolbar[$page['project_id']] ) ) {
                            $this->wp_admin_toolbar[$page['project_id']][] = $menu;
                        } else {
                            $this->wp_admin_toolbar[$page['project_id']][] = $menu;
                        }
                    }
                }
            }
        }
        if ( !is_admin() ) {
            $this->wpda_add_project_to_toolbar();
        }
    }

    protected function wpda_add_project_to_toolbar() {
        foreach ( $this->wp_admin_toolbar as $pid => $toolbar ) {
            foreach ( $toolbar as $key => $menu ) {
                if ( 0 === $key ) {
                    $this->additem_to_toolbar( $pid, $menu );
                }
                $this->additem_to_toolbar( $menu['menu_id'], $menu, $pid );
            }
        }
    }

    protected function additem_to_toolbar( $pid, $menu, $parent = null ) {
        global $wp_admin_bar;
        $args = array(
            'id'     => $pid,
            'title'  => ( null === $parent ? $menu['menu_name'] : $menu['page_title'] ),
            'href'   => admin_url( 'admin.php' ) . '?page=' . $menu['menu_id'],
            'zindex' => '9999',
            'meta'   => array(
                'class' => ( null === $parent ? 'wpda-wpdp-toolbar' : '' ),
                'title' => ( null === $parent ? $menu['menu_title'] : $menu['page_title'] ),
            ),
        );
        if ( null !== $parent ) {
            $args['parent'] = $parent;
        }
        $wp_admin_bar->add_node( $args );
    }

    /**
     * Manage project page
     */
    public function manage_project_page() {
        $ids = explode( '_', (string) $this->page );
        //phpcs:ignore - 8.1 proof
        if ( 4 !== count( $ids ) ) {
            //phpcs:ignore - 8.1 proof
            wp_die( __( 'ERROR: Wrong arguments [missing page]', 'wp-data-access' ) );
        }
        $project_id = $ids[2];
        $page_id = $ids[3];
        if ( isset( $this->wpdp_project_views[$project_id . '_' . $page_id] ) ) {
            $this->wpdp_project_views[$project_id . '_' . $page_id]->show();
        } else {
            if ( isset( $this->wpdp_projects_content[$project_id . '_' . $page_id] ) ) {
                $post_id = $this->wpdp_projects_content[$project_id . '_' . $page_id];
                $post = get_post( $post_id );
                $content = $post->post_content;
                $content = apply_filters( 'the_content', $content );
                $content = str_replace( ']]>', ']]&gt;', $content );
                echo $content;
            } else {
                wp_die( __( 'ERROR: Project page initialization failed', 'wp-data-access' ) );
            }
        }
    }

}
