<?php
namespace Storzen;
defined('ABSPATH') || exit;

class Panel {
    /** @var string */   protected $slug;
    /** @var string */   protected $title;
    /** @var string */   protected $capability = 'manage_options';
    /** @var string */   protected $icon       = 'dashicons-screenoptions';
    /** @var int    */   protected $position   = 56;
    /** @var array|null */ protected $banner   = null;
    /** @var Menu[] */   protected $menus      = array();

    /** @return static */
    public static function make( $slug, $title ) { return new static( $slug, $title ); }

    public function __construct( $slug, $title ) {
        $this->slug  = $slug;
        $this->title = $title;
    }

    /** @return static */ public function set_capability( $c ) { $this->capability = $c;  return $this; }
    /** @return static */ public function capability( $c )     { return $this->set_capability($c); }
    /** @return static */ public function set_icon( $i )       { $this->icon = $i;         return $this; }
    /** @return static */ public function icon( $i )           { return $this->set_icon($i); }
    /** @return static */ public function set_position( $p )   { $this->position = (int)$p; return $this; }
    /** @return static */ public function position( $p )       { return $this->set_position($p); }

    /** @return static */
    public function set_banner( $text, $btn_url = '', $btn_label = 'Upgrade →' ) {
        $this->banner = array( 'text' => $text, 'btn_url' => $btn_url, 'btn_label' => $btn_label );
        return $this;
    }
    /** @return static */
    public function banner( $text, $btn_url = '', $btn_label = 'Upgrade →' ) {
        return $this->set_banner($text, $btn_url, $btn_label);
    }

    /** @return static */
    public function add_menu( Menu $menu ) {
        $menu->set_panel( $this );
        $this->menus[] = $menu;
        return $this;
    }

    public function get_slug()       { return $this->slug; }
    public function get_title()      { return $this->title; }
    public function get_banner()     { return $this->banner; }
    public function get_menus()      { return $this->menus; }
    public function get_capability() { return $this->capability; }

    public function find_menu( $slug ) {
        foreach ( $this->menus as $m ) {
            if ( $m->get_slug() === $slug ) return $m;
        }
        return null;
    }

    public function register() {
        add_action( 'admin_menu',            array( $this, '_wp_menus' ) );
        add_action( 'admin_enqueue_scripts', array( $this, '_assets' ) );
        add_action( 'wp_ajax_pk_save',       array( $this, '_ajax_save' ) );
    }

    public function _wp_menus() {
        add_menu_page(
            $this->title, $this->title, $this->capability, $this->slug,
            array( $this, '_render' ), $this->icon, $this->position
        );

        foreach ( $this->menus as $menu ) {
            add_submenu_page(
                $this->slug,
                $menu->get_title(),
                $menu->get_nav_label(),
                $this->capability,
                $menu->get_page_slug(),
                array( $this, '_render' )
            );
        }
    }

    public function _assets( $hook ) {
        if ( strpos( $hook, $this->slug ) === false ) return;
        wp_enqueue_style(  'sz-admin', SZ_URL . 'admin/css/admin.css', array(), SZ_VERSION );
        wp_enqueue_script( 'sz-admin', SZ_URL . 'admin/js/admin.js', array('jquery'), SZ_VERSION, true );
        wp_localize_script( 'sz-admin', 'PK', array(
            'ajax_url' => admin_url('admin-ajax.php'),
            'nonce'    => wp_create_nonce('pk_save'),
            'i18n'     => array(
                'save'   => __('Save Settings','storzen'),
                'saving' => __('Saving…','storzen'),
                'saved'  => __('Settings saved!','storzen'),
                'error'  => __('Error saving settings.','storzen'),
            ),
        ));
        // storzen required-fields i18n
        wp_localize_script( 'sz-admin', 'WCP', array(
            'i18n' => array(
                'required'      => __( 'This field is required.', 'storzen' ),
                'fill_required' => __( 'Please fill in all required fields before saving.', 'storzen' ),
            ),
        ));
    }

    public function _render() {
        // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only admin navigation parameters.
        $page_slug  = sanitize_key( isset( $_GET['page'] ) ? $_GET['page'] : '' ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
        $tab_slug   = sanitize_key( isset( $_GET['tab'] ) ? $_GET['tab'] : '' ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
        $prefix     = $this->slug . '--';
        $menu_slug  = ( strpos($page_slug, $prefix) === 0 ) ? substr($page_slug, strlen($prefix)) : '';

        $menus       = $this->menus;
        $active_menu = $this->find_menu($menu_slug);
        if ( ! $active_menu && ! empty($menus) ) $active_menu = $menus[0];
        if ( ! $active_menu ) { echo '<div class="wrap"><p>No menus configured.</p></div>'; return; }

        $tabs       = $active_menu->get_tabs();
        $active_tab = $active_menu->find_tab($tab_slug);
        if ( ! $active_tab && ! empty($tabs) ) $active_tab = $tabs[0];

        Renderer::page( $this, $active_menu, $active_tab );
    }

    public function _ajax_save() {
        check_ajax_referer('pk_save','nonce');
        if ( ! current_user_can($this->capability) ) {
            wp_send_json_error(array('message'=>'Forbidden'));
        }

        $menu_slug = sanitize_key( isset($_POST['menu']) ? $_POST['menu'] : '' );
        $tab_slug  = sanitize_key( isset($_POST['tab'])  ? $_POST['tab']  : '' );
        $menu      = $this->find_menu($menu_slug);
        if ( ! $menu ) wp_send_json_error(array('message'=>'Unknown menu: ' . $menu_slug));
        $tab = $menu->find_tab($tab_slug);
        if ( ! $tab  ) wp_send_json_error(array('message'=>'Unknown tab: '  . $tab_slug));

        // Block saving PRO-locked content when not licensed.
        $is_pro_active = defined('STORZEN_IS_PRO') && STORZEN_IS_PRO === 'yes';
        if ( ! $is_pro_active && ( $menu->is_pro() || $tab->is_pro() ) ) {
            wp_send_json_error( array( 'message' => __( 'A PRO license is required to save these settings.', 'storzen' ) ) );
        }

        $raw   = isset( $_POST['pk_fields'] ) ? wp_unslash( $_POST['pk_fields'] ) : array(); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Data is sanitized field-by-field inside $tab->save().
        $saved = $tab->save( $raw );
        wp_send_json_success(array('message' => __('Settings saved!','storzen'), 'data' => $saved));
    }
}
