<?php
/**
 * Free Reminders module.
 *
 * Strict-isolation entrypoint for the Reminders admin section.
 * Owns:
 * - section registration
 * - local Reminders AJAX bootstrap
 * - local Reminders CPT bootstrap
 * - module-local admin view
 * - Reminders-specific shared i18n used by its local JS / shared briefing UI
 * - reminders badge context for the shared shell
 * - module-owned topbar action metadata for the shared shell
 *
 * This module remains strict lazy-load for its section assets.
 *
 * @package Noesia_Smart_Waiter
 */

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

if ( ! class_exists( 'Noesia_Swa_Module_Reminders' ) ) {
    /**
     * Free Reminders module.
     */
    class Noesia_Swa_Module_Reminders implements Noesia_SWA_Module_Interface {

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

        /**
         * Human-readable module label.
         *
         * @return string
         */
        public function get_label() {
            return __( 'Reminders', '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 Reminders module is enabled.
             *
             * @param bool                         $enabled Enabled state.
             * @param Noesia_Swa_Module_Reminders $module  Module instance.
             */
            $enabled = apply_filters( 'noesia_swa_module_reminders_enabled', $enabled, $this );

            return (bool) $enabled;
        }

        /**
         * Register module hooks.
         *
         * @return void
         */
        public function register_hooks() {
            $this->boot_local_ajax_handlers();
            $this->boot_local_cpt();

            add_action( 'noesia_swa_register_admin_sections', array( $this, 'register_admin_section' ) );
            add_filter( 'noesia_swa_admin_i18n', array( $this, 'filter_admin_i18n' ), 10, 2 );
            add_filter( 'noesia_swa_shell_active_badge_context', array( $this, 'filter_active_badge_context' ), 10, 3 );
            add_filter( 'noesia_swa_shell_topbar_actions', array( $this, 'filter_topbar_actions' ), 20, 4 );
            add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_shell_css' ), 20 );
            add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_shell_css' ), 20 );
            add_filter( 'noesia_swa_factory_reset_post_types', array( $this, 'filter_factory_reset_post_types' ), 10, 2 );

            /**
             * Fires when the Reminders module is booted.
             *
             * @param Noesia_Swa_Module_Reminders $this Module instance.
             */
            do_action( 'noesia_swa_module_reminders_loaded', $this );
        }

        /**
         * Boot the module-local Reminders AJAX handlers.
         *
         * @return void
         */
        private function boot_local_ajax_handlers() {
            $ajax_file = trailingslashit( __DIR__ ) . 'includes/class-noesia-swa-module-reminders-ajax.php';

            if ( file_exists( $ajax_file ) ) {
                require_once $ajax_file;

                if ( class_exists( 'Noesia_SWA_Module_Reminders_Ajax' ) ) {
                    new Noesia_SWA_Module_Reminders_Ajax();
                }
            }
        }

        /**
         * Boot the module-local Reminders CPT owner.
         *
         * @return void
         */
        private function boot_local_cpt() {
            $cpt_file = trailingslashit( __DIR__ ) . 'includes/class-noesia-swa-module-reminders-cpt.php';

            if ( file_exists( $cpt_file ) ) {
                require_once $cpt_file;

                if ( class_exists( 'Noesia_SWA_Module_Reminders_CPT' ) ) {
                    new Noesia_SWA_Module_Reminders_CPT();
                }
            }
        }

        /**
         * Register the Reminders 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'          => 'reminders',
                    'label'       => $this->get_label(),
                    'nav_label'   => $this->get_label(),
                    'nav_sub'     => __( 'Daily Workflow', 'noesia-smart-waiter' ),
                    'icon'        => 'dashicons-bell',
                    'priority'    => 80,
                    'tier'        => 'free',
                    'owner'       => 'reminders',
                    'is_visible'  => true,
                    'nav_visible' => true,
                    'callback'    => array( $this, 'render_admin' ),
                )
            );
        }

        /**
         * Provide Reminders-owned i18n used by local JS / briefing UI.
         *
         * @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['briefing_open_reminders']       = __( 'Open Reminders', 'noesia-smart-waiter' );
            $i18n['briefing_reminders_today']      = __( 'Reminders today', 'noesia-smart-waiter' );
            $i18n['briefing_active_reminder_one']  = __( '1 active reminder', 'noesia-smart-waiter' );
            /* translators: %d: number of active reminders. */
            $i18n['briefing_active_reminder_many'] = __( '%d active reminders', 'noesia-smart-waiter' );
            $i18n['badge_reminders_label']         = __( 'Reminders', 'noesia-smart-waiter' );
            $i18n['badge_reminder_singular']       = __( 'Reminder', 'noesia-smart-waiter' );

            return $i18n;
        }

        /**
         * Provide live Reminders badge context to the shared shell.
         *
         * This module owns the "reminders" badge type. It only fills the shell
         * context when the selected dashboard stat source is reminders.
         *
         * @param array<string,mixed> $context Default shell context.
         * @param array<string,mixed> $options Saved options.
         * @param mixed               $helper Shell data helper.
         * @return array<string,mixed>
         */
        public function filter_active_badge_context( $context, $options, $helper ) {
            if ( ! is_array( $context ) ) {
                $context = array();
            }

            if ( ! is_array( $options ) ) {
                $options = array();
            }

            $source = '';

            if ( ! empty( $options['dashboard_stats_source'] ) ) {
                $source = sanitize_key( (string) $options['dashboard_stats_source'] );
            } elseif ( ! empty( $options['global_active_badge_type'] ) ) {
                $source = sanitize_key( (string) $options['global_active_badge_type'] );
            }

            if ( 'reminders' !== $source ) {
                return $context;
            }

            $count = $this->get_open_reminders_total_count();

            return array_merge(
                $context,
                array(
                    'type'            => 'reminders',
                    'visible'         => $count > 0,
                    'count'           => $count,
                    'label'           => ( 1 === $count ) ? __( 'Reminder', 'noesia-smart-waiter' ) : __( 'Reminders', 'noesia-smart-waiter' ),
                    'text'            => ( 1 === $count ) ? __( 'Reminder', 'noesia-smart-waiter' ) : __( 'Reminders', 'noesia-smart-waiter' ),
                    'target'          => 'reminders',
                    'reminders_count' => $count,
                )
            );
        }

        /**
         * Register the Reminders topbar action inside the shared shell.
         *
         * Transitional ownership move:
         * - today the shell still has default topbar actions
         * - this module now asserts ownership of the reminders 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();
            }

            $badge_count = $this->get_open_reminders_total_count();

            $replacement = array(
                'id'           => 'reminders',
                'type'         => 'nav',
                'target'       => 'reminders',
                'icon'         => 'dashicons-bell',
                'label'        => __( 'Reminders', 'noesia-smart-waiter' ),
                'position'     => 'left',
                'priority'     => 30,
                'owner'        => 'reminders',
                'badge_count'  => $badge_count,
                'badge_label'  => __( 'Open reminders', 'noesia-smart-waiter' ),
                'badge_hidden' => $badge_count < 1,
            );

            $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 ( 'reminders' === $action_id || 'reminders' === $action_target ) {
                    $actions[ $index ] = array_merge( $action, $replacement );
                    $found             = true;
                    break;
                }
            }

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

            return $actions;
        }

        /**
         * Count all open reminders.
         *
         * The topbar bell and shared shell badge must be visible on first paint
         * without opening the Reminders tab, so this count is resolved server-side
         * for the whole plugin screen.
         *
         * @return int
         */
        private function get_open_reminders_total_count() {
            $query = new WP_Query(
                array(
                    'post_type'      => 'noesia_reminder',
                    'post_status'    => 'publish',
                    'posts_per_page' => 1,
                    'fields'         => 'ids',
                    // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query -- The topbar bell requires a server-side count of open reminder posts by status meta.
                    'meta_query'     => array(
                        array(
                            'key'   => 'noesia_rem_status',
                            'value' => 'open',
                        ),
                    ),
                    'no_found_rows'  => false,
                )
            );

            return absint( $query->found_posts );
        }

        /**
         * Enqueue shell CSS required for the shared topbar bell badge.
         *
         * This stays module-local and loads outside the lazy section bundle so the
         * badge is visible immediately on Dashboard / first paint.
         *
         * @param string $hook Current admin hook.
         * @return void
         */
        public function enqueue_shell_css( $hook ) {
            if ( ! $this->is_plugin_admin_screen( $hook ) ) {
                return;
            }

            $relative_path = 'modules/free/reminders/assets/css/shell.css';
            $absolute_path = NOESIA_SWA_PLUGIN_DIR . $relative_path;

            if ( ! file_exists( $absolute_path ) ) {
                return;
            }

            wp_enqueue_style(
                'noesia-swa-reminders-shell-css',
                NOESIA_SWA_PLUGIN_URL . $relative_path,
                array( 'noesia-admin-css' ),
                (string) filemtime( $absolute_path )
            );
        }

        /**
         * Whether the current screen is the plugin admin page.
         *
         * @param string $hook Current admin page hook.
         * @return bool
         */
        private function is_plugin_admin_screen( $hook ) {
            if ( 'toplevel_page_noesia_swa_settings' !== (string) $hook ) {
                return false;
            }

            return current_user_can( 'manage_options' );
        }


        /**
         * Register Reminders-owned entities for the factory reset pipeline.
         *
         * @param array<int,string> $post_types Existing reset post types.
         * @param mixed             $ajax_handler AJAX handler instance.
         * @return array<int,string>
         */
        public function filter_factory_reset_post_types( $post_types, $ajax_handler ) {
            if ( ! is_array( $post_types ) ) {
                $post_types = array();
            }

            $post_types[] = 'noesia_reminder';

            return array_values(
                array_unique(
                    array_filter(
                        array_map( 'sanitize_key', $post_types )
                    )
                )
            );
        }

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

            /**
             * Fires before the Reminders admin module view renders.
             *
             * @param Noesia_Swa_Module_Reminders $this Module instance.
             */
            do_action( 'noesia_swa_before_render_reminders_admin', $this );

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

                /**
                 * Fires after the Reminders admin module view renders.
                 *
                 * @param Noesia_Swa_Module_Reminders $this Module instance.
                 */
                do_action( 'noesia_swa_after_render_reminders_admin', $this );
                return;
            }

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

                /**
                 * Fires after the Reminders legacy fallback view renders.
                 *
                 * @param Noesia_Swa_Module_Reminders $this Module instance.
                 */
                do_action( 'noesia_swa_after_render_reminders_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__( 'Reminders', '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 Reminders missing-view fallback renders.
             *
             * @param Noesia_Swa_Module_Reminders $this Module instance.
             */
            do_action( 'noesia_swa_after_render_reminders_admin', $this );
        }
    }
}
