<?php
namespace Avirtum\GutenDraw\System;

defined( 'ABSPATH' ) || exit;

use Avirtum\GutenDraw\Models\DataModel;
use Avirtum\GutenDraw\Models\AccessModel;
use Avirtum\GutenDraw\Models\SettingsModel;

class Admin {
    public function __construct() {
        add_action( 'init', [ $this, 'init' ] );
    }

    public function init() {
        if ( AccessModel::currentUserCan( AccessModel::ACCESS_RIGHT_VIEW ) ) {
            self::registerPostType();

            add_action( 'admin_menu', [ $this, 'adminMenu' ] );
            add_filter( 'submenu_file', [ $this, 'highlightAdminMenu' ], 10, 2 );
            add_action( 'wp_loaded', [ $this, 'redirect' ] );
            add_action( 'script_loader_tag', [ $this, 'scriptLoaderTag' ], 10, 3 );
        } else if ( current_user_can( 'administrator' ) ) {
            add_action( 'admin_menu', [ $this, 'adminMenu' ] );
        }
    }

    public function registerPostType() {
        $labels = [
            'name' => esc_html__('GutenDraw Diagrams', 'gutendraw' ),
            'singular_name' => esc_html__( 'GutenDraw Diagram', 'gutendraw' ),
        ];
        $args = [
            'labels' => $labels,
            'public' => false,  // removes the permalink option
            'publicly_queryable' => false, // remove preview page
            'exclude_from_search' => true,
            'show_ui' => false,
            'show_in_menu' => false,
            'show_in_rest' => false,
            'rewrite' => false,
            'query_var' => false,
            'capability_type' => 'post',
            'has_archive' => false,
            'hierarchical' => false,
            'supports' => [ 'title' ]
        ];

        register_post_type( DataModel::POST_TYPE, $args );
    }

    public function adminMenu() {
        if ( AccessModel::currentUserCan( AccessModel::ACCESS_RIGHT_VIEW ) ) {
            // add "edit_posts" if we want to give access to author, editor and contributor roles
            add_menu_page( esc_html__('GutenDraw', 'gutendraw'), esc_html__('GutenDraw', 'gutendraw'), 'read', 'gutendraw', [ $this, 'showPage' ], 'data:image/svg+xml;base64,' . base64_encode( SettingsModel::ICON ) );
            add_submenu_page('gutendraw', esc_html__('GutenDraw', 'gutendraw'), esc_html__('All Diagrams', 'gutendraw'), 'read', 'gutendraw', [ $this, 'showPage' ] );
            add_submenu_page('gutendraw', esc_html__('GutenDraw', 'gutendraw'), esc_html__('Add New Diagram', 'gutendraw'), 'read', 'gutendraw&action=new', [ $this, 'showPage' ] );
            add_submenu_page('gutendraw', esc_html__('GutenDraw', 'gutendraw'), esc_html__('Settings', 'gutendraw'), 'manage_options', 'gutendraw-settings', [ $this, 'showPageSettings' ] );

            if( !AccessModel::getTicket() ) {
                add_submenu_page('gutendraw', esc_html__('GutenDraw', 'gutendraw'), esc_html__('Upgrade to Pro', 'gutendraw'), 'manage_options', 'gutendraw_upgrade_to_pro', [ $this, 'showPageUpgradeToPro' ] );
            }
        } else {
            add_menu_page( esc_html__('GutenDraw', 'gutendraw'), esc_html__('GutenDraw', 'gutendraw'), 'manage_options', 'gutendraw-settings', [ $this, 'showPageSettings' ], 'data:image/svg+xml;base64,' . base64_encode( SettingsModel::ICON ) );
        }
    }

    public function highlightAdminMenu( $submenu_file, $parent_file ) {
        $page = sanitize_key( filter_input(INPUT_GET, 'page', FILTER_DEFAULT ) );
        if ( in_array( $page, [ 'gutendraw' ] ) ) {
            $action = sanitize_key( filter_input(INPUT_GET, 'action', FILTER_DEFAULT ) );
            if ( in_array( $action, [ 'new' ] ) ) {
                $submenu_file = "gutendraw&action={$action}";
            }
        }
        return $submenu_file;
    }

    public function redirect() {
        $page = sanitize_key( filter_input(INPUT_GET, 'page', FILTER_DEFAULT ) );
        if ( in_array( $page, [ 'gutendraw' ] ) ) {
            $action = sanitize_key( filter_input(INPUT_GET, 'action', FILTER_DEFAULT ) );
            if ( $action ) {
                if ( !in_array( $action, [ 'new', 'edit' ] ) && !empty( $_SERVER[ 'REQUEST_URI' ] ) ) {
                    $url = remove_query_arg( ['action', 'id', '_wpnonce'], sanitize_url( wp_unslash( $_SERVER['REQUEST_URI'] ) ) );
                    header('Refresh:0; url="' . $url . '"', true, 303);
                } else if ( in_array( $action, [ 'new' ] ) ) {
                    if ( !AccessModel::currentUserCan( AccessModel::ACCESS_RIGHT_CREATE ) ) {
                        wp_die( esc_html__( 'Sorry, you are not allowed to access this page.', 'gutendraw' ), 403 );
                    }
                } else if ( in_array( $action, [ 'edit' ] ) ) {
                    $id = sanitize_key( filter_input(INPUT_GET, 'id', FILTER_DEFAULT ) );
                    if ( !DataModel::currentUserCan( $id, AccessModel::ACCESS_RIGHT_EDIT ) ) {
                        wp_die( esc_html__( 'Sorry, you are not allowed to access this page.', 'gutendraw' ), 403 );
                    }
                }
            }
        }
    }

    public function scriptLoaderTag( $tag, $handle, $src ) {
        $page = sanitize_key( filter_input(INPUT_GET, 'page', FILTER_DEFAULT ) );
        if ( in_array( $page, [ 'gutendraw' ] ) ) {
            if ( $handle == 'gutendraw-editor' ) {
                $script = [];

                $script[] = '<script>';
                $script[] = 'window.EXCALIDRAW_EXPORT_SOURCE = "https://excalidraw.com";';
                $script[] = 'window.EXCALIDRAW_ASSET_PATH = "' . GUTENDRAW_PLUGIN_URL . 'assets/vendor/excalidraw/' . '";';
                $script[] = '</script>';

                // phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedScript
                $script[] = '<script type="module" src="' . esc_url( $src ) . '" defer></script>';
                return join("\n", $script);
            } else if ( $handle == 'gutendraw-settings' ) {
                $script = [];

                // phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedScript
                $script[] = '<script type="module" src="' . esc_url( $src ) . '" defer></script>';
                return join("\n", $script);
            }
        }
        return $tag;
    }

    public function showPage() {
        $page = sanitize_key( filter_input(INPUT_GET, 'page', FILTER_DEFAULT ) );
        if ( in_array( $page, [ 'gutendraw' ] ) ) {
            $action = sanitize_key( filter_input(INPUT_GET, 'action', FILTER_DEFAULT ) );

            switch ( $action ) {
                case 'edit':
                case 'new': {
                    wp_enqueue_style( 'gutendraw-style', GUTENDRAW_PLUGIN_URL . 'assets/css/style.css', [], GUTENDRAW_PLUGIN_VERSION, 'all' );

                    if ( $action == 'new' && !AccessModel::getTicket() && DataModel::getItemsCount() >= 3 ) {
                        echo '<div class="notice notice-error is-dismissible">';
                        echo '<p>GutenDraw: ' . esc_html__( 'You can create only 3 diagrams. If you need more, upgrade to the pro version.', 'gutendraw' ) . '</p>';
                        echo '</div>';
                        return;
                    }

                    $id = sanitize_key( filter_input(INPUT_GET, 'id', FILTER_DEFAULT ) );

                    if ( $action == 'edit' ) {
                        $post = get_post( $id );
                        if ( !$post || $post->post_type !== DataModel::POST_TYPE ) {
                            echo '<div class="notice notice-error is-dismissible">';
                            echo '<p>GutenDraw: ' . esc_html__( "The item doesn't exist or is in the wrong format.", 'gutendraw' ) . '</p>';
                            echo '</div>';
                            return;
                        }
                    }

                    wp_enqueue_style( 'gutendraw-notify', GUTENDRAW_PLUGIN_URL . 'assets/css/notify.css', [], GUTENDRAW_PLUGIN_VERSION, 'all' );
                    wp_enqueue_script( 'gutendraw-notify', GUTENDRAW_PLUGIN_URL . 'assets/js/notify.js', [], GUTENDRAW_PLUGIN_VERSION, false );
                    wp_enqueue_script( 'gutendraw-editor', GUTENDRAW_PLUGIN_URL . 'assets/editor/index.js', [], GUTENDRAW_PLUGIN_VERSION, false );

                    wp_localize_script( 'gutendraw-editor', 'gutendraw_globals', $this->getGlobalsForEditor( $id )  );

                    require_once( GUTENDRAW_PLUGIN_PATH . '/includes/Views/item.php' );
                } break;
                default: {
                    wp_enqueue_style( 'gutendraw-style', GUTENDRAW_PLUGIN_URL . 'assets/css/style.css', [], GUTENDRAW_PLUGIN_VERSION, 'all' );
                    wp_enqueue_script( 'gutendraw-items', GUTENDRAW_PLUGIN_URL . 'assets/js/items.js', [], GUTENDRAW_PLUGIN_VERSION, false );

                    $table = new ListTable();
                    $table->prepare_items();

                    require_once(GUTENDRAW_PLUGIN_PATH . '/includes/Views/items.php');
                }
            }
        }
    }

    public function showPageSettings() {
        $page = sanitize_key( filter_input(INPUT_GET, 'page', FILTER_DEFAULT ) );
        if ( in_array( $page, [ 'gutendraw-settings' ] ) ) {
            if ( !AccessModel::getTicket() ) {
                echo '<div class="notice notice-error is-dismissible">';
                echo '<p>GutenDraw: ' . esc_html__( 'The ability to change and save settings is a pro feature.', 'gutendraw' ) . '</p>';
                echo '</div>';
            }

            wp_enqueue_style( 'gutendraw-style', GUTENDRAW_PLUGIN_URL . 'assets/css/style.css', [], GUTENDRAW_PLUGIN_VERSION, 'all' );

            wp_enqueue_script( 'gutendraw-feather-icons', GUTENDRAW_PLUGIN_URL . 'assets/vendor/feather-icons/feather.js', [], GUTENDRAW_PLUGIN_VERSION, false );

            wp_enqueue_style( 'gutendraw-notify', GUTENDRAW_PLUGIN_URL . 'assets/css/notify.css', [], GUTENDRAW_PLUGIN_VERSION, 'all' );
            wp_enqueue_script( 'gutendraw-notify', GUTENDRAW_PLUGIN_URL . 'assets/js/notify.js', [], GUTENDRAW_PLUGIN_VERSION, false );

            wp_enqueue_script( 'gutendraw-settings', GUTENDRAW_PLUGIN_URL . 'assets/settings/index.js', [], GUTENDRAW_PLUGIN_VERSION, false );
            wp_localize_script( 'gutendraw-settings', 'gutendraw_globals', $this->getGlobalsForSettings()  );

            require_once( GUTENDRAW_PLUGIN_PATH . '/includes/Views/settings.php' );
        }
    }

    public function showPageUpgradeToPro() {
        $page = sanitize_key( filter_input(INPUT_GET, 'page', FILTER_DEFAULT ) );
        if ( $page === 'gutendraw_upgrade_to_pro' ) {
            echo '<script>window.location = "https://1.envato.market/getgutendraw"</script>';
        }
    }

    private function getGlobalsForEditor( $id = null ) {
        $data = [
            'item' => [ 'id' => $id ],
            'rights' => [ 'publish' => AccessModel::currentUserCan(AccessModel::ACCESS_RIGHT_PUBLISH) ],
            'url' => urlencode( add_query_arg( [ 'page' => 'gutendraw', 'action' => 'new' ], admin_url( 'admin.php' ) ) ),
            'url_back' => sanitize_url( add_query_arg( [ 'page' => 'gutendraw' ], admin_url( 'admin.php' ) ) ),
            'ticket' => AccessModel::getTicket()
        ];

        if ( $id ) {
            $item = DataModel::getItem( $id );
            if ( $item ) {
                $data['url'] = urlencode( add_query_arg( [ 'page' => 'gutendraw', 'action' => 'edit', 'id' => $data['item']['id'] ], admin_url( 'admin.php' ) ) );
                $data['item']['title'] = $item['title'];
                $data['item']['status'] = $item['status'];
                $data['item']['source'] = $item['source'];
                $data['item']['files'] = $item['files'];
            }
        }

        return [
            'data' => $data,
            'i18n' => I18n::getTranslation(),
            'api' => [
                'nonce' => wp_create_nonce( 'wp_rest' ),
                'url' => esc_url_raw( rest_url( GUTENDRAW_PLUGIN_REST_URL ) )
            ]
        ];
    }

    private function getGlobalsForSettings() {
        $data = [
            'url_back' => sanitize_url( add_query_arg( [ 'page' => 'gutendraw' ], admin_url( 'admin.php' ) ) ),
            'ticket' => AccessModel::getTicket()
        ];

        return [
            'data' => $data,
            'i18n' => I18n::getTranslation(),
            'api' => [
                'nonce' => wp_create_nonce( 'wp_rest' ),
                'url' => esc_url_raw( rest_url( GUTENDRAW_PLUGIN_REST_URL ) )
            ]
        ];
    }
}