<?php
/**
 * Standalone “shop” grid: all subscription plans with links to checkout.
 *
 * @package Invizo\SubscriptionsLite\Frontend
 */

namespace Invizo\SubscriptionsLite\Frontend;

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

class Store {

    /** Query arg for plan detail view on the store page (title/image links). */
    const PLAN_DETAIL_QUERY = 'invizo_plan';

    public static function init() {
        add_shortcode( 'invizo_store', array( __CLASS__, 'render' ) );
        add_shortcode( 'invizo_plans', array( __CLASS__, 'render' ) );
        add_action( 'wp_enqueue_scripts', array( __CLASS__, 'maybe_enqueue_assets' ) );
    }

    public static function maybe_enqueue_assets() {
        global $post;
        if ( ! is_a( $post, 'WP_Post' ) ) {
            return;
        }
        if ( has_shortcode( $post->post_content, 'invizo_store' ) || has_shortcode( $post->post_content, 'invizo_plans' ) ) {
            wp_enqueue_style(
                'invizo-store',
                INVIZO_LITE_URL . 'css/store.css',
                array(),
                INVIZO_LITE_VERSION
            );
        }
    }

    /**
     * Resolve checkout base URL for ?plan= links.
     *
     * @param string $override Shortcode checkout_url attribute.
     * @return string Empty if not configured.
     */
    protected static function get_checkout_base_url( $override ) {
        $override = trim( (string) $override );
        if ( $override !== '' ) {
            return esc_url( $override );
        }
        $page_id = (int) get_option( 'invizo_standalone_checkout_page_id', 0 );
        if ( $page_id ) {
            $url = get_permalink( $page_id );
            return $url ? esc_url( $url ) : '';
        }
        return '';
    }

    /**
     * Base URL for plan detail links (?invizo_plan=ID). Prefer Settings → Store page, else current singular permalink.
     *
     * @param string $override Shortcode store_url attribute.
     * @return string Empty if not resolvable.
     */
    protected static function get_store_details_base_url( $override ) {
        $override = trim( (string) $override );
        if ( $override !== '' ) {
            return esc_url( $override );
        }
        $page_id = (int) get_option( 'invizo_standalone_store_page_id', 0 );
        if ( $page_id ) {
            $url = get_permalink( $page_id );
            return $url ? esc_url( $url ) : '';
        }
        if ( is_singular() ) {
            global $post;
            if ( is_a( $post, 'WP_Post' ) ) {
                $url = get_permalink( $post );
                return $url ? esc_url( $url ) : '';
            }
        }
        return '';
    }

    /**
     * @param int $plan_id Plan post ID.
     * @return string e.g. "mo", "yr", or raw interval.
     */
    protected static function interval_short_label( $plan_id ) {
        $interval = get_post_meta( $plan_id, '_interval', true ) ?: 'month';
        $i        = strtolower( substr( $interval, 0, 2 ) );
        if ( $i === 'mo' ) {
            return 'mo';
        }
        if ( $i === 'ye' ) {
            return 'yr';
        }
        return $interval;
    }

    /**
     * Short kicker line for plan detail hero (e.g. “Annual subscription”).
     *
     * @param int $plan_id Plan post ID.
     * @return string
     */
    protected static function get_plan_interval_kicker( $plan_id ) {
        $interval = strtolower( (string) get_post_meta( $plan_id, '_interval', true ) );
        if ( strpos( $interval, 'year' ) !== false ) {
            return __( 'Annual subscription', 'invizo-subscriptions-lite' );
        }
        if ( strpos( $interval, 'week' ) !== false ) {
            return __( 'Weekly subscription', 'invizo-subscriptions-lite' );
        }
        if ( strpos( $interval, 'day' ) !== false ) {
            return __( 'Daily subscription', 'invizo-subscriptions-lite' );
        }
        return __( 'Monthly subscription', 'invizo-subscriptions-lite' );
    }

    /**
     * Feature / highlight lines for “What’s included” (newline list or comma-separated tags).
     *
     * @param int $plan_id Plan post ID.
     * @return string[]
     */
    public static function get_plan_feature_lines( $plan_id ) {
        $lines = array();
        $raw   = get_post_meta( $plan_id, '_features', true );
        if ( is_string( $raw ) && trim( $raw ) !== '' ) {
            $lines = array_filter( array_map( 'trim', preg_split( '/\r\n|\r|\n/', $raw ) ) );
        }
        if ( empty( $lines ) ) {
            $tags = get_post_meta( $plan_id, '_tags', true );
            if ( is_string( $tags ) && trim( $tags ) !== '' ) {
                $lines = array_filter( array_map( 'trim', preg_split( '/\s*,\s*/', $tags ) ) );
            }
        }
        return array_values( $lines );
    }

    /**
     * @param array $atts Shortcode attributes.
     * @return string
     */
    public static function render( $atts ) {
        $atts = shortcode_atts(
            array(
                'checkout_url'     => '',
                'store_url'        => '',
                'columns'          => '3',
                'show_description' => 'yes',
                'button_text'      => '',
            ),
            $atts,
            'invizo_store'
        );

        // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- read-only plan ID for shortcode output.
        $detail_id = isset( $_GET[ self::PLAN_DETAIL_QUERY ] ) ? absint( wp_unslash( $_GET[ self::PLAN_DETAIL_QUERY ] ) ) : 0;
        if ( $detail_id > 0 ) {
            // Detail views are query-arg based and can be stale under aggressive page caches.
            if ( ! headers_sent() ) {
                nocache_headers();
            }
            return self::render_plan_detail( $detail_id, $atts );
        }

        $checkout_base = self::get_checkout_base_url( $atts['checkout_url'] );
        if ( $checkout_base === '' ) {
            return '<div class="invizo-store invizo-store--notice"><p>' . esc_html__(
                'Set your checkout page in Invizo Subscriptions → Settings → General, or pass the checkout_url attribute to this shortcode.',
                'invizo-subscriptions-lite'
            ) . '</p></div>';
        }

        $columns = max( 1, min( 4, absint( $atts['columns'] ) ) );
        if ( ! $columns ) {
            $columns = 3;
        }

        $show_desc = in_array( strtolower( (string) $atts['show_description'] ), array( 'yes', '1', 'true' ), true );

        $button_default = get_option( 'invizo_checkout_btn_subscribe', '' );
        if ( ! is_string( $button_default ) || $button_default === '' ) {
            $button_default = __( 'Subscribe', 'invizo-subscriptions-lite' );
        }
        $button_text = trim( (string) $atts['button_text'] );
        if ( $button_text === '' ) {
            $button_text = $button_default;
        }

        $plans = get_posts(
            array(
                'post_type'      => 'invizo_plan',
                'posts_per_page' => -1,
                'post_status'    => 'publish',
                'orderby'        => 'title',
                'order'          => 'ASC',
            )
        );

        if ( empty( $plans ) ) {
            return '<div class="invizo-store invizo-store--notice"><p>' . esc_html__(
                'No subscription plans are available yet.',
                'invizo-subscriptions-lite'
            ) . '</p></div>';
        }

        $store_base = self::get_store_details_base_url( $atts['store_url'] );

        ob_start();
        ?>
        <div class="invizo-store" style="--invizo-store-cols: <?php echo esc_attr( (string) $columns ); ?>;">
            <ul class="invizo-store__grid">
                <?php foreach ( $plans as $plan ) : ?>
                    <?php
                    $pid      = (int) $plan->ID;
                    $price    = get_post_meta( $pid, '_price', true );
                    $price_f  = is_numeric( $price ) ? number_format( (float) $price, 2 ) : esc_html( (string) $price );
                    $int_lbl  = self::interval_short_label( $pid );
                    $media    = get_post_meta( $pid, '_media', true );
                    $checkout_href = esc_url( add_query_arg( 'plan', $pid, $checkout_base ) );
                    if ( $store_base !== '' ) {
                        $detail_href = esc_url( add_query_arg( self::PLAN_DETAIL_QUERY, $pid, $store_base ) );
                    } else {
                        $detail_href = $checkout_href;
                    }
                    $excerpt  = $plan->post_content ? wp_trim_words( wp_strip_all_tags( $plan->post_content ), 28 ) : '';
                    $signup   = get_post_meta( $pid, '_signup_fee', true );
                    $trial    = get_post_meta( $pid, '_trial_period', true );
                    ?>
                    <li class="invizo-store__item">
                        <article class="invizo-store__card">
                            <?php if ( $media ) : ?>
                                <a class="invizo-store__media" href="<?php echo esc_url( $detail_href ); ?>" aria-label="<?php echo esc_attr( sprintf( /* translators: %s plan title */ __( 'View details: %s', 'invizo-subscriptions-lite' ), $plan->post_title ) ); ?>">
                                    <img src="<?php echo esc_url( $media ); ?>" alt="<?php echo esc_attr( $plan->post_title ); ?>" loading="lazy" width="400" height="225" />
                                </a>
                            <?php endif; ?>
                            <div class="invizo-store__body">
                                <h3 class="invizo-store__title">
                                    <a href="<?php echo esc_url( $detail_href ); ?>"><?php echo esc_html( $plan->post_title ); ?></a>
                                </h3>
                                <div class="invizo-store__price">
                                    <span class="invizo-store__amount">$<?php echo esc_html( $price_f ); ?></span>
                                    <span class="invizo-store__period">/<?php echo esc_html( $int_lbl ); ?></span>
                                </div>
                                <?php if ( $show_desc && $excerpt !== '' ) : ?>
                                    <p class="invizo-store__desc"><?php echo esc_html( $excerpt ); ?></p>
                                <?php endif; ?>
                                <?php if ( $signup || $trial ) : ?>
                                    <ul class="invizo-store__meta">
                                        <?php if ( $signup && is_numeric( $signup ) && (float) $signup > 0 ) : ?>
                                            <li><?php echo esc_html( sprintf( /* translators: %s formatted price */ __( 'Signup fee: $%s', 'invizo-subscriptions-lite' ), number_format( (float) $signup, 2 ) ) ); ?></li>
                                        <?php endif; ?>
                                        <?php if ( $trial && is_numeric( $trial ) && (int) $trial > 0 ) : ?>
                                            <li><?php echo esc_html( sprintf( /* translators: %d number of days */ __( '%d-day free trial', 'invizo-subscriptions-lite' ), (int) $trial ) ); ?></li>
                                        <?php endif; ?>
                                    </ul>
                                <?php endif; ?>
                                <a class="invizo-store__button" href="<?php echo esc_url( $checkout_href ); ?>"><?php echo esc_html( $button_text ); ?></a>
                            </div>
                        </article>
                    </li>
                <?php endforeach; ?>
            </ul>
        </div>
        <?php
        return ob_get_clean();
    }

    /**
     * Single-plan detail view (linked from store grid title/image).
     *
     * @param int   $plan_id Plan post ID.
     * @param array $atts    Shortcode attributes (checkout_url, store_url, button_text, show_description).
     * @return string
     */
    protected static function render_plan_detail( $plan_id, $atts ) {
        $plan = get_post( $plan_id );
        if ( ! $plan || $plan->post_type !== 'invizo_plan' || $plan->post_status !== 'publish' ) {
            $store_base = self::get_store_details_base_url( isset( $atts['store_url'] ) ? $atts['store_url'] : '' );
            $back       = $store_base !== '' ? $store_base : home_url( '/' );

            return '<div class="invizo-store invizo-store--notice"><p>' . esc_html__( 'This subscription plan is not available.', 'invizo-subscriptions-lite' ) . '</p><p><a class="invizo-plan-page__back" href="' . esc_url( remove_query_arg( self::PLAN_DETAIL_QUERY, $back ) ) . '">' . esc_html__( '← Back to plans', 'invizo-subscriptions-lite' ) . '</a></p></div>';
        }

        $checkout_base = self::get_checkout_base_url( isset( $atts['checkout_url'] ) ? $atts['checkout_url'] : '' );
        if ( $checkout_base === '' ) {
            return '<div class="invizo-store invizo-store--notice"><p>' . esc_html__(
                'Checkout is not configured. Set your checkout page in Invizo Subscriptions → Settings.',
                'invizo-subscriptions-lite'
            ) . '</p></div>';
        }

        $store_base = self::get_store_details_base_url( isset( $atts['store_url'] ) ? $atts['store_url'] : '' );
        $back_base  = $store_base !== '' ? $store_base : $checkout_base;
        $back_url   = remove_query_arg( self::PLAN_DETAIL_QUERY, $back_base );

        $pid     = (int) $plan->ID;
        $price   = get_post_meta( $pid, '_price', true );
        $price_f = is_numeric( $price ) ? number_format( (float) $price, 2 ) : esc_html( (string) $price );
        $int_lbl = self::interval_short_label( $pid );
        $media   = get_post_meta( $pid, '_media', true );
        $signup  = get_post_meta( $pid, '_signup_fee', true );
        $trial   = get_post_meta( $pid, '_trial_period', true );

        $button_default = get_option( 'invizo_checkout_btn_subscribe', '' );
        if ( ! is_string( $button_default ) || $button_default === '' ) {
            $button_default = __( 'Subscribe', 'invizo-subscriptions-lite' );
        }
        $button_text = isset( $atts['button_text'] ) ? trim( (string) $atts['button_text'] ) : '';
        if ( $button_text === '' ) {
            $button_text = $button_default;
        }

        $show_desc    = isset( $atts['show_description'] ) && in_array( strtolower( (string) $atts['show_description'] ), array( 'yes', '1', 'true' ), true );
        $content_html = '';
        $plain_desc   = trim( wp_strip_all_tags( (string) $plan->post_content ) );
        if ( $show_desc && trim( (string) $plan->post_content ) !== '' ) {
            $content_html = apply_filters( 'the_content', $plan->post_content );
        }

        $gallery_desc_plain = $plain_desc !== '' ? wp_trim_words( $plain_desc, 100, '…' ) : '';
        $kicker        = self::get_plan_interval_kicker( $pid );
        $checkout_href = esc_url( add_query_arg( 'plan', $pid, $checkout_base ) );

        $default_faqs = array(
            array(
                'q' => __( 'How does billing work?', 'invizo-subscriptions-lite' ),
                'a' => __( 'You are charged according to the plan interval. You can cancel from your account area before the next renewal when using our member portal.', 'invizo-subscriptions-lite' ),
            ),
            array(
                'q' => __( 'Can I cancel anytime?', 'invizo-subscriptions-lite' ),
                'a' => __( 'Yes. Cancel from your account settings; access continues until the end of the period you already paid for.', 'invizo-subscriptions-lite' ),
            ),
            array(
                'q' => __( 'What happens after I subscribe?', 'invizo-subscriptions-lite' ),
                'a' => __( 'You will receive a confirmation email and immediate access according to your plan.', 'invizo-subscriptions-lite' ),
            ),
        );
        $faqs = apply_filters( 'invizo_plan_detail_faqs', $default_faqs, $pid );

        $site_name = get_bloginfo( 'name' );

        ob_start();
        ?>
        <div class="invizo-store invizo-store--detail invizo-plan-page">
            <header class="invizo-plan-page__topbar">
                <a class="invizo-plan-page__back" href="<?php echo esc_url( $back_url ); ?>">
                    <span class="invizo-plan-page__back-arrow" aria-hidden="true">←</span>
                    <?php esc_html_e( 'All plans', 'invizo-subscriptions-lite' ); ?>
                </a>
                <span class="invizo-plan-page__brand"><?php echo esc_html( $site_name ); ?></span>
            </header>

            <section class="invizo-plan-page__hero">
                <div class="invizo-plan-page__hero-grid">
                    <div class="invizo-plan-page__gallery">
                        <div class="invizo-plan-page__figure">
                            <?php if ( $media ) : ?>
                                <img src="<?php echo esc_url( $media ); ?>" alt="<?php echo esc_attr( $plan->post_title ); ?>" loading="lazy" width="900" height="1125" />
                            <?php else : ?>
                                <div class="invizo-plan-page__figure-placeholder" aria-hidden="true"></div>
                            <?php endif; ?>
                        </div>
                        <?php if ( $show_desc && $content_html !== '' ) : ?>
                            <div class="invizo-plan-page__gallery-desc invizo-plan-page__gallery-desc--rich" aria-label="<?php esc_attr_e( 'Plan description', 'invizo-subscriptions-lite' ); ?>">
                                <?php echo wp_kses_post( $content_html ); ?>
                            </div>
                        <?php elseif ( $gallery_desc_plain !== '' ) : ?>
                            <div class="invizo-plan-page__gallery-desc">
                                <p class="invizo-plan-page__gallery-desc-text"><?php echo esc_html( $gallery_desc_plain ); ?></p>
                            </div>
                        <?php endif; ?>
                    </div>
                    <div class="invizo-plan-page__sticky">
                        <p class="invizo-plan-page__kicker"><?php echo esc_html( $kicker ); ?></p>
                        <h1 class="invizo-plan-page__title"><?php echo esc_html( $plan->post_title ); ?></h1>
                        <div class="invizo-plan-page__price-row">
                            <span class="invizo-plan-page__price">$<?php echo esc_html( $price_f ); ?></span>
                            <span class="invizo-plan-page__period">/<?php echo esc_html( $int_lbl ); ?></span>
                        </div>
                        <?php
                        $show_info_card = ( $signup && is_numeric( $signup ) && (float) $signup > 0 )
                            || ( $trial && is_numeric( $trial ) && (int) $trial > 0 );
                        ?>
                        <?php if ( $show_info_card ) : ?>
                            <div class="invizo-plan-page__card">
                                <?php if ( $signup && is_numeric( $signup ) && (float) $signup > 0 ) : ?>
                                    <div class="invizo-plan-page__card-row">
                                        <span class="invizo-plan-page__card-label"><?php esc_html_e( 'Signup fee', 'invizo-subscriptions-lite' ); ?></span>
                                        <span class="invizo-plan-page__card-value">$<?php echo esc_html( number_format( (float) $signup, 2 ) ); ?></span>
                                    </div>
                                <?php endif; ?>
                                <?php if ( $trial && is_numeric( $trial ) && (int) $trial > 0 ) : ?>
                                    <div class="invizo-plan-page__card-row">
                                        <span class="invizo-plan-page__card-label"><?php esc_html_e( 'Trial period', 'invizo-subscriptions-lite' ); ?></span>
                                        <span class="invizo-plan-page__card-value"><?php echo esc_html( sprintf( /* translators: %d days */ __( '%d days free', 'invizo-subscriptions-lite' ), (int) $trial ) ); ?></span>
                                    </div>
                                <?php endif; ?>
                            </div>
                        <?php endif; ?>
                        <a class="invizo-plan-page__cta" href="<?php echo esc_url( $checkout_href ); ?>"><?php echo esc_html( $button_text ); ?></a>
                        <p class="invizo-plan-page__cta-note"><?php esc_html_e( 'Secure payment via Stripe. Cancel anytime.', 'invizo-subscriptions-lite' ); ?></p>
                    </div>
                </div>
            </section>

            <section class="invizo-plan-page__section invizo-plan-page__benefits" aria-labelledby="invizo-benefits-heading">
                <div class="invizo-plan-page__benefits-inner">
                    <div class="invizo-plan-page__benefits-intro">
                        <h2 id="invizo-benefits-heading" class="invizo-plan-page__benefits-kicker"><?php esc_html_e( 'Benefits', 'invizo-subscriptions-lite' ); ?></h2>
                        <p class="invizo-plan-page__benefits-lead"><?php esc_html_e( 'Everything you need in one membership.', 'invizo-subscriptions-lite' ); ?></p>
                    </div>
                    <div class="invizo-plan-page__benefits-grid">
                        <div class="invizo-plan-page__benefit">
                            <span class="invizo-plan-page__benefit-icon" aria-hidden="true"><?php echo wp_kses( invizo_plan_detail_icon_devices(), self::get_allowed_svg_html() ); ?></span>
                            <h4 class="invizo-plan-page__benefit-title"><?php esc_html_e( 'Any device', 'invizo-subscriptions-lite' ); ?></h4>
                            <p class="invizo-plan-page__benefit-text"><?php esc_html_e( 'Use your subscription wherever you sign in—desktop, tablet, or phone.', 'invizo-subscriptions-lite' ); ?></p>
                        </div>
                        <div class="invizo-plan-page__benefit">
                            <span class="invizo-plan-page__benefit-icon" aria-hidden="true"><?php echo wp_kses( invizo_plan_detail_icon_shield(), self::get_allowed_svg_html() ); ?></span>
                            <h4 class="invizo-plan-page__benefit-title"><?php esc_html_e( 'Secure billing', 'invizo-subscriptions-lite' ); ?></h4>
                            <p class="invizo-plan-page__benefit-text"><?php esc_html_e( 'Payments are processed by Stripe with industry-standard encryption.', 'invizo-subscriptions-lite' ); ?></p>
                        </div>
                        <div class="invizo-plan-page__benefit">
                            <span class="invizo-plan-page__benefit-icon" aria-hidden="true"><?php echo wp_kses( invizo_plan_detail_icon_book(), self::get_allowed_svg_html() ); ?></span>
                            <h4 class="invizo-plan-page__benefit-title"><?php esc_html_e( 'Member access', 'invizo-subscriptions-lite' ); ?></h4>
                            <p class="invizo-plan-page__benefit-text"><?php esc_html_e( 'Your benefits stay tied to your account for easy renewal and support.', 'invizo-subscriptions-lite' ); ?></p>
                        </div>
                    </div>
                </div>
            </section>

            <?php if ( is_array( $faqs ) && ! empty( $faqs ) ) : ?>
                <section class="invizo-plan-page__section invizo-plan-page__faq" aria-labelledby="invizo-faq-heading">
                    <h2 id="invizo-faq-heading" class="invizo-plan-page__faq-title"><?php esc_html_e( 'Frequently asked questions', 'invizo-subscriptions-lite' ); ?></h2>
                    <div class="invizo-plan-page__faq-list">
                        <?php foreach ( $faqs as $item ) : ?>
                            <?php
                            if ( empty( $item['q'] ) || empty( $item['a'] ) ) {
                                continue;
                            }
                            ?>
                            <div class="invizo-plan-page__faq-item">
                                <h3 class="invizo-plan-page__faq-q"><?php echo esc_html( $item['q'] ); ?></h3>
                                <p class="invizo-plan-page__faq-a"><?php echo esc_html( $item['a'] ); ?></p>
                            </div>
                        <?php endforeach; ?>
                    </div>
                </section>
            <?php endif; ?>
        </div>
        <?php
        return ob_get_clean();
    }

    /**
     * @return array<string, array<string, bool>>
     */
    protected static function get_allowed_svg_html() {
        return array(
            'path' => array(
                'd'               => true,
                'fill'            => true,
                'stroke'          => true,
                'stroke-linecap'  => true,
                'stroke-linejoin' => true,
                'stroke-width'    => true,
            ),
            'svg'  => array(
                'aria-hidden' => true,
                'class'       => true,
                'fill'        => true,
                'height'      => true,
                'viewbox'     => true,
                'width'       => true,
                'xmlns'       => true,
            ),
        );
    }
}

if ( ! function_exists( 'invizo_plan_detail_icon_devices' ) ) {
    /**
     * @return string
     */
    function invizo_plan_detail_icon_devices() {
        return '<svg class="invizo-plan-page__svg" width="28" height="28" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true"><path d="M4 6h16v10H4V6zm2 12h12v2H6v-2z" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>';
    }
}

if ( ! function_exists( 'invizo_plan_detail_icon_shield' ) ) {
    /**
     * @return string
     */
    function invizo_plan_detail_icon_shield() {
        return '<svg class="invizo-plan-page__svg" width="28" height="28" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true"><path d="M12 3l8 4v6c0 5-3.5 9-8 10-4.5-1-8-5-8-10V7l8-4z" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>';
    }
}

if ( ! function_exists( 'invizo_plan_detail_icon_book' ) ) {
    /**
     * @return string
     */
    function invizo_plan_detail_icon_book() {
        return '<svg class="invizo-plan-page__svg" width="28" height="28" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true"><path d="M4 5a2 2 0 012-2h12a2 2 0 012 2v14l-8-3-8 3V5z" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>';
    }
}
