<?php
/**
 * Free Screen Lock module.
 *
 * Strict-isolation entrypoint for the Screen Lock admin section.
 * Owns:
 * - section registration
 * - shell-layer eager assets on the plugin admin screen (header padlock / overlay)
 * - screen-lock / screensaver defaults
 * - sanitization of screen-lock-owned fields
 * - screen-lock-specific shared i18n for the shell bridge
 *
 * @package Noesia_Smart_Waiter
 */

if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

if ( ! class_exists( 'Noesia_Swa_Module_Screen_Lock' ) ) {
    /**
     * Free Screen Lock module.
     */
    class Noesia_Swa_Module_Screen_Lock implements Noesia_SWA_Module_Interface {

        /**
         * Unique module identifier.
         *
         * @return string
         */
        public function get_id() {
            return 'screen-lock';
        }

        /**
         * Human-readable module label.
         *
         * @return string
         */
        public function get_label() {
            return __( 'Screen Lock', 'noesia-smart-waiter' );
        }

        /**
         * Module tier.
         *
         * @return string
         */
        public function get_tier() {
            return 'free';
        }

        /**
         * Whether the module is enabled.
         *
         * @return bool
         */
        public function is_enabled() {
            $enabled = true;

            /**
             * Filter whether the free Screen Lock module is enabled.
             *
             * @param bool                          $enabled Enabled state.
             * @param Noesia_Swa_Module_Screen_Lock $module Module instance.
             */
            $enabled = apply_filters( 'noesia_swa_module_screen_lock_enabled', $enabled, $this );

            return (bool) $enabled;
        }

        /**
         * Register module hooks.
         *
         * @return void
         */
        public function register_hooks() {
            add_action( 'noesia_swa_register_admin_sections', array( $this, 'register_admin_section' ) );
            add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_assets' ) );
            add_filter( 'noesia_swa_shell_topbar_actions', array( $this, 'filter_topbar_actions' ), 20, 4 );

            add_filter( 'noesia_swa_option_defaults', array( $this, 'filter_option_defaults' ), 10, 3 );
            add_filter( 'noesia_swa_sanitize_options', array( $this, 'sanitize_screen_lock_fields' ), 10, 4 );
            add_filter( 'noesia_swa_admin_i18n', array( $this, 'filter_admin_i18n' ), 10, 2 );
            add_filter( 'noesia_swa_localized_options', array( $this, 'filter_localized_options' ) );

            /**
             * Fires when the Screen Lock module is booted.
             *
             * @param Noesia_Swa_Module_Screen_Lock $this Module instance.
             */
            do_action( 'noesia_swa_module_screen_lock_loaded', $this );
        }

        /**
         * Register the Screen Lock admin section.
         *
         * @param mixed $registry Admin sections registry.
         * @return void
         */
        public function register_admin_section( $registry ) {
            if ( ! $registry instanceof Noesia_SWA_Admin_Sections ) {
                return;
            }

            $registry->register_section(
                array(
                    'id'          => 'screen-lock',
                    'label'       => $this->get_label(),
                    'nav_label'   => $this->get_label(),
                    'nav_sub'     => __( 'Focus & Privacy', 'noesia-smart-waiter' ),
                    'icon'        => 'dashicons-lock',
                    'priority'    => 95,
                    'tier'        => 'free',
                    'owner'       => 'screen-lock',
                    'hero'        => false,
                    'is_visible'  => true,
                    'nav_visible' => true,
                    'callback'    => array( $this, 'render_admin' ),
                )
            );
        }

        /**
         * Eager-load only shell-layer assets on the plugin admin page so the
         * header padlock and overlay work from any section.
         *
         * Section UI assets remain shell-manifest lazy loaded via the admin shell.
         *
         * @param string $hook Current admin page hook.
         * @return void
         */
        public function enqueue_admin_assets( $hook ) {
            if ( 'toplevel_page_noesia_swa_settings' !== (string) $hook ) {
                return;
            }

            if ( ! current_user_can( 'manage_options' ) ) {
                return;
            }

            $module_dir = trailingslashit( __DIR__ );
            $module_url = trailingslashit( NOESIA_SWA_PLUGIN_URL . 'modules/free/screen-lock' );

            $shell_js_file  = $module_dir . 'assets/js/shell.js';
            $shell_css_file = $module_dir . 'assets/css/shell.css';

            if ( file_exists( $shell_css_file ) ) {
                wp_enqueue_style(
                    'noesia-swa-module-screen-lock-shell',
                    $module_url . 'assets/css/shell.css',
                    array( 'noesia-admin-css' ),
                    (string) filemtime( $shell_css_file )
                );
            }

            if ( file_exists( $shell_js_file ) ) {
                wp_enqueue_script(
                    'noesia-swa-module-screen-lock-shell',
                    $module_url . 'assets/js/shell.js',
                    array( 'jquery', 'noesia-admin-js' ),
                    (string) filemtime( $shell_js_file ),
                    true
                );
            }
        }

        /**
         * Provide module-owned defaults.
         *
         * @param array<string,mixed> $defaults Existing defaults.
         * @param array<string,mixed> $options Existing saved options.
         * @param mixed               $context Caller context.
         * @return array<string,mixed>
         */
        public function filter_option_defaults( $defaults, $options, $context ) {
            if ( ! is_array( $defaults ) ) {
                $defaults = array();
            }

            $defaults['screensaver_enabled']      = 'no';
            $defaults['screensaver_idle_minutes'] = 5;
            $defaults['screensaver_show_clock']   = 'yes';
            $defaults['screensaver_show_updates'] = 'yes';
            $defaults['screensaver_show_center_box'] = 'yes';
            $defaults['screensaver_message']      = __( 'Move the pointer, tap, click, or press ESC to return.', 'noesia-smart-waiter' );
            $defaults['screensaver_timeout']      = '300';

            return $defaults;
        }

        /**
         * Sanitize module-owned settings fields.
         *
         * @param array<string,mixed> $new_input Sanitized output so far.
         * @param array<string,mixed> $input Raw submitted input.
         * @param array<string,mixed> $existing Previously saved options.
         * @param mixed               $admin Admin instance.
         * @return array<string,mixed>
         */
        public function sanitize_screen_lock_fields( $new_input, $input, $existing, $admin ) {
            if ( ! is_array( $new_input ) ) {
                $new_input = array();
            }

            if ( ! is_array( $input ) ) {
                return $new_input;
            }

            if ( isset( $input['screensaver_enabled'] ) ) {
                $enabled = sanitize_key( wp_unslash( (string) $input['screensaver_enabled'] ) );
                $new_input['screensaver_enabled'] = 'yes' === $enabled ? 'yes' : 'no';
            }

            if ( isset( $input['screensaver_idle_minutes'] ) ) {
                $idle_minutes = absint( wp_unslash( (string) $input['screensaver_idle_minutes'] ) );
                $new_input['screensaver_idle_minutes'] = max( 1, min( 120, $idle_minutes ) );
                $new_input['screensaver_timeout']      = (string) ( (int) $new_input['screensaver_idle_minutes'] * MINUTE_IN_SECONDS );
            } elseif ( isset( $input['screensaver_timeout'] ) ) {
                $timeout = absint( wp_unslash( (string) $input['screensaver_timeout'] ) );
                $timeout = max( 60, min( 7200, $timeout ) );
                $new_input['screensaver_timeout']      = (string) $timeout;
                $new_input['screensaver_idle_minutes'] = max( 1, min( 120, (int) ceil( $timeout / MINUTE_IN_SECONDS ) ) );
            }

            if ( isset( $input['screensaver_show_clock'] ) ) {
                $show_clock = sanitize_key( wp_unslash( (string) $input['screensaver_show_clock'] ) );
                $new_input['screensaver_show_clock'] = 'no' === $show_clock ? 'no' : 'yes';
            }

            if ( isset( $input['screensaver_show_updates'] ) ) {
                $show_updates = sanitize_key( wp_unslash( (string) $input['screensaver_show_updates'] ) );
                $new_input['screensaver_show_updates'] = 'no' === $show_updates ? 'no' : 'yes';
            }

            if ( isset( $input['screensaver_show_center_box'] ) ) {
                $show_center_box = sanitize_key( wp_unslash( (string) $input['screensaver_show_center_box'] ) );
                $new_input['screensaver_show_center_box'] = 'no' === $show_center_box ? 'no' : 'yes';
            }

            if ( isset( $input['screensaver_message'] ) ) {
                $new_input['screensaver_message'] = sanitize_text_field( wp_unslash( (string) $input['screensaver_message'] ) );
            }

            return $new_input;
        }

        /**
         * Provide module-owned i18n for the shared shell bridge.
         *
         * @param array<string,string> $i18n Existing i18n payload.
         * @param mixed                $admin Admin instance.
         * @return array<string,string>
         */
        public function filter_admin_i18n( $i18n, $admin ) {
            if ( ! is_array( $i18n ) ) {
                $i18n = array();
            }

            $i18n['overlay_dialog_label']      = __( 'Screen Overlay', 'noesia-smart-waiter' );
            $i18n['overlay_lock_title']        = __( 'Screen is locked (blurred).', 'noesia-smart-waiter' );
            $i18n['overlay_lock_message']      = __( 'Click outside this box or press ESC to unlock.', 'noesia-smart-waiter' );
            $i18n['overlay_saver_title']       = __( 'Screen Saver', 'noesia-smart-waiter' );
            $i18n['overlay_saver_message']     = __( 'Move the pointer, tap, click, or press ESC to return.', 'noesia-smart-waiter' );
            $i18n['screen_saver_one_update']   = __( '1 active update', 'noesia-smart-waiter' );
            /* translators: %d: number of active updates. */
            $i18n['screen_saver_many_updates'] = __( '%d active updates', 'noesia-smart-waiter' );

            return $i18n;
        }

        /**
         * Ensure the shell bridge receives the fields it needs for the header
         * padlock and screensaver behavior.
         *
         * @param array<string,mixed> $options Localized options payload.
         * @return array<string,mixed>
         */
        public function filter_localized_options( $options ) {
            if ( ! is_array( $options ) ) {
                $options = array();
            }

            $defaults = $this->filter_option_defaults( array(), $options, $this );

            foreach ( $defaults as $key => $default_value ) {
                if ( ! array_key_exists( $key, $options ) ) {
                    $options[ $key ] = $default_value;
                }
            }

            return $options;
        }

        /**
         * Register the Screen Lock topbar action inside the shared shell.
         *
         * Transitional ownership move:
         * - today the shell may still have default topbar actions
         * - this module now asserts ownership of the screen-lock action metadata
         * - later, kernel defaults can be emptied safely
         *
         * @param array<int,array<string,mixed>>    $actions Existing topbar actions.
         * @param array<string,array<string,mixed>> $sections Registered admin sections.
         * @param array<string,mixed>               $options Saved options.
         * @param mixed                             $shell_data Shell data helper.
         * @return array<int,array<string,mixed>>
         */
        public function filter_topbar_actions( $actions, $sections, $options, $shell_data ) {
            if ( ! is_array( $actions ) ) {
                $actions = array();
            }

            $replacement = array(
                'id'       => 'screen-lock',
                'type'     => 'nav',
                'target'   => 'screen-lock',
                'icon'     => 'dashicons-lock',
                'label'    => __( 'Screen Lock', 'noesia-smart-waiter' ),
                'position' => 'left',
                'priority' => 50,
                'owner'    => 'screen-lock',
            );

            $found = false;

            foreach ( $actions as $index => $action ) {
                if ( ! is_array( $action ) ) {
                    continue;
                }

                $action_id     = isset( $action['id'] ) ? sanitize_key( (string) $action['id'] ) : '';
                $action_target = isset( $action['target'] ) ? sanitize_key( (string) $action['target'] ) : '';

                if ( 'screen-lock' === $action_id || 'screen-lock' === $action_target ) {
                    $actions[ $index ] = array_merge( $action, $replacement );
                    $found             = true;
                    break;
                }
            }

            if ( ! $found ) {
                $actions[] = $replacement;
            }

            return $actions;
        }

        /**
         * Render the module-local Screen Lock admin view.
         *
         * @return void
         */
        public function render_admin() {
            $module_view = trailingslashit( __DIR__ ) . 'views/admin.php';
            $legacy_view = NOESIA_SWA_PLUGIN_DIR . 'admin/partials/sections/screen-lock.php';

            /**
             * Fires before the Screen Lock admin module view renders.
             *
             * @param Noesia_Swa_Module_Screen_Lock $this Module instance.
             */
            do_action( 'noesia_swa_before_render_screen_lock_admin', $this );

            if ( file_exists( $module_view ) ) {
                include $module_view;

                /**
                 * Fires after the Screen Lock admin module view renders.
                 *
                 * @param Noesia_Swa_Module_Screen_Lock $this Module instance.
                 */
                do_action( 'noesia_swa_after_render_screen_lock_admin', $this );
                return;
            }

            if ( file_exists( $legacy_view ) ) {
                include $legacy_view;

                /**
                 * Fires after the Screen Lock legacy fallback view renders.
                 *
                 * @param Noesia_Swa_Module_Screen_Lock $this Module instance.
                 */
                do_action( 'noesia_swa_after_render_screen_lock_admin', $this );
                return;
            }

            echo '<div class="noesia-swa-card noesia-swa-card--span2">';
            echo '<div class="noesia-swa-card-header"><div>';
            echo '<h3>' . esc_html__( 'Screen Lock', 'noesia-smart-waiter' ) . '</h3>';
            echo '<p class="noesia-swa-muted">' . esc_html__( 'Module view missing.', 'noesia-smart-waiter' ) . '</p>';
            echo '</div></div>';
            echo '</div>';

            /**
             * Fires after the Screen Lock missing-view fallback renders.
             *
             * @param Noesia_Swa_Module_Screen_Lock $this Module instance.
             */
            do_action( 'noesia_swa_after_render_screen_lock_admin', $this );
        }
    }
}
