<?php

namespace WeDevs\DokanPro\Modules\VendorVerification\Frontend;

use WeDevs\DokanPro\Modules\VendorVerification\Helper;

defined( 'ABSPATH' ) || exit;

/**
 * Contextual verification notices for vendors whose selling is disabled
 * pending verification while "Enable Selling" is set to "Verified Only".
 *
 * @since 5.0.15
 */
class Notices {

    /**
     * Class Constructor.
     *
     * @since 5.0.15
     */
    public function __construct() {
        add_action( 'template_redirect', [ $this, 'replace_selling_disabled_notices' ] );
        add_action( 'dokan_before_listing_product', [ $this, 'render_product_listing_notice' ] );
        add_action( 'dokan_subscription_packs_before', [ $this, 'render_subscription_page_notice' ], 10, 2 );
        add_action( 'dokan_render_settings_content', [ $this, 'render_verification_page_notice' ], 5 );
        add_filter( 'dokan_get_navigation_url', [ $this, 'redirect_setup_wizard_exit_to_verification' ], 10, 2 );
    }

    /**
     * Swap the generic "not enabled for selling" notices for verification guidance.
     *
     * The core notice tells vendors to contact the admin, which is the wrong
     * next step when the vendor can resolve it themselves through verification.
     *
     * @since 5.0.15
     *
     * @return void
     */
    public function replace_selling_disabled_notices() {
        if ( ! dokan_is_seller_dashboard() || ! $this->is_verification_pending( dokan_get_current_user_id() ) ) {
            return;
        }

        $templates = dokan()->dashboard->templates;

        $generic_notices = [
            'dokan_dashboard_content_inside_before' => [ $templates->dashboard, 'show_seller_dashboard_notice' ],
            'dokan_settings_content_inside_before'  => [ $templates->settings, 'show_enable_seller_message' ],
            'dokan_order_content_inside_before'     => [ $templates->orders, 'show_seller_enable_message' ],
            'dokan_withdraw_content_inside_before'  => [ $templates->withdraw, 'show_seller_enable_message' ],
        ];

        $renders_own_notice = $this->page_renders_own_notice();

        foreach ( $generic_notices as $hook => $callback ) {
            remove_action( $hook, $callback );

            if ( ! $renders_own_notice ) {
                add_action( $hook, [ $this, 'render_global_notice' ] );
            }
        }
    }

    /**
     * Whether the requested page prints its own verification notice.
     *
     * Only the legacy dashboard can be resolved here. The React dashboard routes
     * on the URL fragment, which never reaches the server, so its pages take the
     * global notice over on the client instead.
     *
     * @since 5.0.15
     *
     * @return bool
     */
    protected function page_renders_own_notice(): bool {
        global $wp;

        if ( isset( $wp->query_vars['new'] ) ) {
            return false;
        }

        if ( isset( $wp->query_vars['products'] ) || isset( $wp->query_vars['subscription'] ) ) {
            return true;
        }

        return isset( $wp->query_vars['settings'] ) && 'verification' === (string) $wp->query_vars['settings'];
    }

    /**
     * Render the dashboard-wide verification notice.
     *
     * Replaces the generic "contact the admin" notice, keeping its position above
     * the page heading. React pages with their own wording render into this same
     * container so their notice lands in the same place.
     *
     * @since 5.0.15
     *
     * @return void
     */
    public function render_global_notice() {
        ?>
        <div class="dokan-selling-disabled-notice">
            <?php // No <p> wrapper, like core's seller-warning.php: themes add paragraph margins that skew the alert padding. ?>
            <div class="dokan-alert dokan-alert-warning dokan-selling-disabled-notice__default">
                <strong><?php esc_html_e( 'Selling is disabled until your account is verified.', 'dokan' ); ?></strong>
                <?php esc_html_e( 'Your account is pending admin verification.', 'dokan' ); ?>
                <a class="dokan-alert-link" href="<?php echo esc_url( $this->get_verification_url() ); ?>">
                    <?php esc_html_e( 'Complete Verification →', 'dokan' ); ?>
                </a>
            </div>
        </div>
        <?php
    }

    /**
     * Whether the current vendor's selling is disabled pending verification.
     *
     * True only when the "Enable Selling" admin setting is "Verified Only",
     * the vendor's selling status is disabled, and the vendor is not verified
     * yet. Vendors disabled for any other reason are not targeted.
     *
     * @since 5.0.15
     *
     * @param int $vendor_id Vendor ID.
     *
     * @return bool
     */
    protected function is_verification_pending( $vendor_id ): bool {
        return Helper::is_selling_disabled_pending_verification( $vendor_id );
    }

    /**
     * Get the vendor dashboard verification page URL.
     *
     * On the React dashboard the link keeps the vendor inside the React shell.
     * The server can tell the two apart by the `new` query var, so this never
     * bounces a React-dashboard vendor to the legacy page. Outside the dashboard
     * (for example the setup wizard) the legacy URL is used, which matches where
     * the wizard already sends vendors today.
     *
     * @since 5.0.15
     *
     * @return string
     */
    protected function get_verification_url(): string {
        global $wp;

        $is_react_dashboard = dokan_is_seller_dashboard() && isset( $wp->query_vars['new'] );

        return dokan_get_navigation_url( 'settings/verification', $is_react_dashboard );
    }

    /**
     * Render an inline notice on the vendor dashboard products page.
     *
     * @since 5.0.15
     *
     * @return void
     */
    public function render_product_listing_notice() {
        if ( ! $this->is_verification_pending( dokan_get_current_user_id() ) ) {
            return;
        }
        ?>
        <div class="dokan-alert dokan-alert-warning dokan-verification-pending-notice">
            <strong><?php esc_html_e( 'One more step before you can list products.', 'dokan' ); ?></strong>
            <?php esc_html_e( 'Your account is pending admin verification.', 'dokan' ); ?>
            <a class="dokan-alert-link" href="<?php echo esc_url( $this->get_verification_url() ); ?>">
                <?php esc_html_e( 'Complete Verification →', 'dokan' ); ?>
            </a>
        </div>
        <?php
    }

    /**
     * Render a selling-status notice on the vendor dashboard subscription page.
     *
     * @since 5.0.15
     *
     * @param object|null $subscription The current vendor subscription object.
     * @param int         $user_id      The current vendor user ID.
     *
     * @return void
     */
    public function render_subscription_page_notice( $subscription, $user_id ) {
        /*
         * can_post_product() rather than has_subscription(): the latter only checks that the pack meta
         * exists, which it still does after a failed payment or a dispute, and for up to a day after a
         * pack expires. This is the same signal the subscription pack template treats as active.
         */
        if ( ! $subscription || ! $subscription->can_post_product() ) {
            return;
        }

        if ( ! $this->is_verification_pending( $user_id ) ) {
            return;
        }
        ?>
        <?php // <div> rather than <p> per line: themes add paragraph margins that skew the alert padding. ?>
        <div class="dokan-alert dokan-alert-warning dokan-verification-pending-notice">
            <div>
                <span aria-hidden="true">&#9989;</span>
                <strong><?php esc_html_e( 'Subscription:', 'dokan' ); ?></strong>
                <?php esc_html_e( 'Active', 'dokan' ); ?>
            </div>
            <div>
                <span aria-hidden="true">&#9888;&#65039;</span>
                <strong><?php esc_html_e( 'Selling Status:', 'dokan' ); ?></strong>
                <?php esc_html_e( 'Disabled — Verification required.', 'dokan' ); ?>
            </div>
            <div>
                <?php esc_html_e( 'Your subscription is active. However, selling is currently disabled on your account pending admin verification.', 'dokan' ); ?>
                <a class="dokan-alert-link" href="<?php echo esc_url( $this->get_verification_url() ); ?>">
                    <?php esc_html_e( 'Complete Verification →', 'dokan' ); ?>
                </a>
            </div>
        </div>
        <?php
    }

    /**
     * Render a contextual banner at the top of the verification page.
     *
     * Runs before the verification page content (priority 5, content loads at 10).
     *
     * @since 5.0.15
     *
     * @param array $query_vars Dashboard query vars.
     *
     * @return void
     */
    public function render_verification_page_notice( array $query_vars ) {
        if ( ! isset( $query_vars['settings'] ) || 'verification' !== (string) $query_vars['settings'] ) {
            return;
        }

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

        if ( ! $this->is_verification_pending( dokan_get_current_user_id() ) ) {
            return;
        }
        ?>
        <div class="dokan-alert dokan-alert-warning dokan-verification-pending-notice">
            <?php esc_html_e( 'To start listing products, please complete the verification steps below. Your selling access will be enabled once the admin approves your verification.', 'dokan' ); ?>
        </div>
        <?php
    }

    /**
     * Point the setup wizard exit links to the verification page.
     *
     * The seller setup wizard's "Go to your Store Dashboard!" and
     * "Not right now" links resolve the dashboard root through
     * `dokan_get_navigation_url()`. When the vendor still needs
     * verification to sell, send them to the verification page instead.
     *
     * @since 5.0.15
     *
     * @param string $url  Navigation URL.
     * @param string $name Subpage name, empty for the dashboard root.
     *
     * @return string
     */
    public function redirect_setup_wizard_exit_to_verification( $url, $name ) {
        if ( '' !== (string) $name ) {
            return $url;
        }

        // phpcs:ignore WordPress.Security.NonceVerification.Recommended
        $page = isset( $_GET['page'] ) ? sanitize_text_field( wp_unslash( $_GET['page'] ) ) : '';

        if ( 'dokan-seller-setup' !== $page ) {
            return $url;
        }

        if ( ! $this->is_verification_pending( dokan_get_current_user_id() ) ) {
            return $url;
        }

        return $this->get_verification_url();
    }
}
