<?php
/**
 * File Path: includes/metaboxes/book-header/class-mbs-book-header-publication.php
 *
 * Book Header Child Section - Publication
 *
 * Handles Publication Date + Coming Soon checkbox + Preorder Link.
 * Includes tier-aware behavior.
 *
 * Postmeta keys read/written (all follow the mbs_* convention shared with
 * other MBS postmeta and with CSV import/export):
 *   mbs_pub_date
 *   mbs_copyright_year   — VARCHAR(4), e.g. "2024"
 *   mbs_coming_soon      — TINYINT(1) '0' | '1'
 *   mbs_preorder_link    — URL string, PRO only
 *   mbs_lifecycle_state  — enum string: '' | 'preorder' | 'out_of_print' | 'out_of_stock' | 'coming_soon' (PRO)
 *
 * CSS classes introduced (all defined in mbs-admin-settings.css):
 *   .mbs-pub-coming-soon-wrap   — margin-left:30px; vertical-align:middle on the span
 *   .mbs-pub-pro-description    — color:#d63638; margin-top:4px on the PRO description <p>
 *
 * Note: inline style attributes with conditional values use esc_attr() per
 * SECURITY.md Rule 4 — specifically the Coming Soon checkbox label opacity
 * on FREE tier and the preorder row's initial display state.
 *
 * @package    My_Book_Showroom
 * @since      1.0.0
 */

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

/** Class MBS_Book_Header_Publication */
// phpcs:disable WordPress.Security.NonceVerification -- nonce verified in parent class verify_save() / check_admin_referer() before $_POST access; PHPCS cannot trace cross-method nonce verification
// phpcs:disable WordPress.Security.ValidatedSanitizedInput -- input sanitized at point of use (sanitize_text_field, absint, wp_kses_post, etc.); false positives from PHPCS not tracing sanitization helpers called before this method
class MBS_Book_Header_Publication { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedClassFound -- mbs_/MBS_ prefix is correct; scanner not configured with plugin prefix

    public function __construct() {
        add_action( 'mbs_book_header_render_publication', array( $this, 'render' ) );
        add_action( 'mbs_book_header_save_publication', array( $this, 'save' ), 10, 2 );
    }

    public function render( $post ) {
        $publication_date = get_post_meta( $post->ID, 'mbs_pub_date', true );
        $publication_time = get_post_meta( $post->ID, 'mbs_publication_time', true );
        $copyright_year   = get_post_meta( $post->ID, 'mbs_copyright_year', true );
        $coming_soon      = (string) MBS_Book_Meta_DAO::get( $post->ID, 'mbs_coming_soon', '' );
        $preorder_link    = get_post_meta( $post->ID, 'mbs_preorder_link', true );
        $lifecycle_state  = (string) MBS_Book_Meta_DAO::get( $post->ID, 'mbs_lifecycle_state', '' );

        // Tier detection — canonical PRO check
        $is_pro_dev = mbs_is_pro();

        // F-024: Build lifecycle state options. 'coming_soon' is PRO-only.
        // 'draft' and 'discontinued' are FREE (Session 98 consolidation).
        $lifecycle_options = array(
            ''              => __( 'Published', 'my-book-showroom' ),
            'draft'         => __( 'Draft', 'my-book-showroom' ),
            'preorder'      => __( 'Preorder', 'my-book-showroom' ),
            'out_of_print'  => __( 'Out of Print', 'my-book-showroom' ),
            'out_of_stock'  => __( 'Out of Stock', 'my-book-showroom' ),
            'discontinued'  => __( 'Discontinued', 'my-book-showroom' ),
        );
        if ( $is_pro_dev ) {
            $lifecycle_options['coming_soon'] = __( 'Coming Soon', 'my-book-showroom' );
        }

        // Copyright year auto-population from pub date year.
        // Only accepts years >= 1000 to guard against Chrome date inputs firing
        // change while the user is still typing the four-digit year (e.g. "0002").
        // Coming Soon logic is handled entirely by admin-coming-soon.js.
        wp_add_inline_script( 'mbs-book-editor', <<<'JS'
(function($){
    function updateCopyrightYear(dateStr) {
        var $year = $('#mbs_copyright_year');
        if (!dateStr || $year.val()) return;
        var year = parseInt(dateStr.substring(0, 4), 10);
        if (year >= 1000) {
            $year.val(year);
        }
    }
    $('#mbs_pub_date').on('change', function(){
        updateCopyrightYear($(this).val());
    });
})(jQuery);
JS
        );

        ?>
        <!-- Publication Date + Coming Soon (side-by-side per spec) -->
        <tr>
            <th scope="row">
                <label for="mbs_pub_date"><?php esc_html_e( 'Publication Date', 'my-book-showroom' ); ?></label>
            </th>
            <td>
                <input type="date" id="mbs_pub_date" name="mbs_pub_date" value="<?php echo esc_attr( $publication_date ); ?>" />

                <?php if ( mbs_is_pro() ) : ?>
                <label for="mbs_publication_time">
                    <?php esc_html_e( 'Release Time (HH:MM, 24h)', 'my-book-showroom' ); ?>
                </label>
                <input type="time"
                       id="mbs_publication_time"
                       name="mbs_publication_time"
                       value="<?php echo esc_attr( $publication_time ); ?>"
                       step="60">
                <?php else : ?>
                <!-- MBS: Release time field requires PRO license -->
                <?php endif; ?>

                <!-- Coming Soon Checkbox to the right -->
                <span class="mbs-pub-coming-soon-wrap">
                    <input type="checkbox" id="mbs_coming_soon" name="mbs_coming_soon" value="1"
                           <?php checked( $coming_soon, '1' ); ?>
                           <?php echo $is_pro_dev ? '' : 'disabled'; ?>>
                    <label for="mbs_coming_soon" style="<?php echo esc_attr( $is_pro_dev ? '' : 'opacity:0.6;' ); ?>">
                        <?php esc_html_e( 'Coming Soon', 'my-book-showroom' ); ?>
                    </label>
                    <?php mbs_help_tip( __( 'For this checkbox to take effect, the publication date must be set to a future date. If the publication date is in the past or not set, the Coming Soon badge will not display.', 'my-book-showroom' ), __( 'Coming Soon', 'my-book-showroom' ) ); ?>
                </span>
            </td>
        </tr>

        <tr>
            <th scope="row">
                <label for="mbs_copyright_year"><?php esc_html_e( 'Copyright Year', 'my-book-showroom' ); ?></label>
            </th>
            <td>
                <input type="text" id="mbs_copyright_year" name="mbs_copyright_year" class="small-text"
                       value="<?php echo esc_attr( $copyright_year ); ?>"
                       maxlength="4" placeholder="<?php echo esc_attr( gmdate( 'Y' ) ); ?>" />
                <p class="description"><?php esc_html_e( 'Four-digit copyright year (e.g. 2024). Used in front-end copyright notices.', 'my-book-showroom' ); ?></p>
            </td>
        </tr>

        <!-- Preorder Link — shown/hidden by admin-coming-soon.js immediately
             below the Publication Date row so it appears under the Coming Soon checkbox. -->
        <tr id="mbs_preorder_row" style="display: none;">
            <th scope="row">
                <label for="mbs_preorder_link"><?php esc_html_e( 'Preorder Link:', 'my-book-showroom' ); ?></label>
            </th>
            <td>
                <input type="url" id="mbs_preorder_link" name="mbs_preorder_link"
                       value="<?php echo esc_attr( $preorder_link ); ?>"
                       class="large-text" placeholder="https://example.com/preorder"
                       <?php echo $is_pro_dev ? '' : 'disabled'; ?>>
                <?php if ( $is_pro_dev ) : ?>
                    <p class="description" style="margin-top:4px;">
                        <?php esc_html_e( 'Optional. Leave blank and the badge will show the publication date (or just "Coming Soon!" if no date is set). Add a valid URL here and the badge will also display a "Click here to preorder today!" link.', 'my-book-showroom' ); ?>
                    </p>
                <?php else : ?>
                    <p class="description" style="margin-top:4px;">
                        <?php esc_html_e( 'PRO gets preorder links and "Coming Soon" badge.', 'my-book-showroom' ); ?>
                    </p>
                <?php endif; ?>
            </td>
        </tr>

        <!-- F-024: Book lifecycle state — 'coming_soon' is PRO-only -->
        <tr>
            <th scope="row">
                <span class="mbs-label-tip-pair"><label for="mbs_lifecycle_state"><?php esc_html_e( 'Book Status', 'my-book-showroom' ); ?></label><?php mbs_help_tip(
                    __( 'This is an MBS display label — it is separate from the WordPress publish status. \'Published\' means the book is live and available. \'Preorder\' shows a preorder badge and can link to a preorder URL. \'Out of Print\' and \'Out of Stock\' display a notice without hiding the book. \'Draft\' here is a metadata label only — it does not hide the book from the front end. To hide a book entirely, set the WordPress post status to Draft using the Publish panel at the top of the page.', 'my-book-showroom' ),
                    __( 'About Book Status', 'my-book-showroom' ),
                    'mbs-help-tip--wide'
                ); ?></span>
            </th>
            <td>
                <select id="mbs_lifecycle_state" name="mbs_lifecycle_state">
                    <?php foreach ( $lifecycle_options as $value => $label ) : ?>
                        <option value="<?php echo esc_attr( $value ); ?>"
                                <?php selected( $lifecycle_state, $value ); ?>>
                            <?php echo esc_html( $label ); ?>
                        </option>
                    <?php endforeach; ?>
                </select>
                <p class="description">
                    <?php esc_html_e( 'Displays a subtle status label on the book page. "Coming Soon" requires PRO.', 'my-book-showroom' ); ?>
                </p>
            </td>
        </tr>
        <?php
    }

    public function save( $post_id, $post ) {
        if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
            return;
        }

        // Publication Date — always allowed (free feature)
        if ( isset( $_POST['mbs_pub_date'] ) ) {
            $date_raw = sanitize_text_field( wp_unslash( $_POST['mbs_pub_date'] ) );
            if ( ! empty( $date_raw ) ) {
                $date = DateTime::createFromFormat( 'Y-m-d', $date_raw );
                if ( $date && $date->format( 'Y-m-d' ) === $date_raw ) {
                    update_post_meta( $post_id, 'mbs_pub_date', $date_raw );
                }
            } else {
                delete_post_meta( $post_id, 'mbs_pub_date' );
            }
        }

        // GC2-4: Publication Time (HH:MM 24h) — PRO only.
        if ( mbs_is_pro() && isset( $_POST['mbs_publication_time'] ) ) {
            $raw_time = sanitize_text_field( wp_unslash( $_POST['mbs_publication_time'] ) );
            if ( preg_match( '/^([01]\d|2[0-3]):[0-5]\d$/', $raw_time ) ) {
                update_post_meta( $post_id, 'mbs_publication_time', $raw_time );
            } else {
                delete_post_meta( $post_id, 'mbs_publication_time' );
            }
        }

        // Copyright Year — always allowed (free feature)
        if ( isset( $_POST['mbs_copyright_year'] ) ) {
            $year_raw = sanitize_text_field( wp_unslash( $_POST['mbs_copyright_year'] ) );
            // Accept only a 4-digit year; silently discard malformed input.
            if ( preg_match( '/^\d{4}$/', $year_raw ) ) {
                update_post_meta( $post_id, 'mbs_copyright_year', $year_raw );
            } else {
                delete_post_meta( $post_id, 'mbs_copyright_year' );
            }
        } else {
            delete_post_meta( $post_id, 'mbs_copyright_year' );
        }

        // F-024: Lifecycle state — 'coming_soon' is PRO-only; all others are FREE.
        $allowed_states = array( '', 'draft', 'preorder', 'out_of_print', 'out_of_stock', 'discontinued' );
        if ( mbs_is_pro() ) {
            $allowed_states[] = 'coming_soon';
        }
        $lifecycle_state = isset( $_POST['mbs_lifecycle_state'] )
            ? sanitize_key( wp_unslash( $_POST['mbs_lifecycle_state'] ) )
            : '';
        if ( ! in_array( $lifecycle_state, $allowed_states, true ) ) {
            $lifecycle_state = '';
        }
        MBS_Book_Meta_DAO::upsert( $post_id, 'mbs_lifecycle_state', $lifecycle_state );

        // Coming Soon + Preorder — gated to PRO only.
        // mbs_coming_soon is canonical: when '1' it overrides mbs_lifecycle_state.
        if ( mbs_is_pro() ) {
            $coming_soon = isset( $_POST['mbs_coming_soon'] ) ? '1' : '0';

            // Server-side guard: cannot be Coming Soon if publication date is today or in the past.
            if ( '1' === $coming_soon ) {
                $pub_date_chk = isset( $_POST['mbs_pub_date'] )
                    ? sanitize_text_field( wp_unslash( $_POST['mbs_pub_date'] ) )
                    : '';
                if ( '' !== $pub_date_chk && wp_date( 'Y-m-d' ) >= $pub_date_chk ) {
                    $coming_soon = '0';
                }
            }
            MBS_Book_Meta_DAO::upsert( $post_id, 'mbs_coming_soon', $coming_soon );

            // Bridge: Coming Soon checkbox is canonical — when '1', force lifecycle state to match.
            if ( '1' === $coming_soon ) {
                MBS_Book_Meta_DAO::upsert( $post_id, 'mbs_lifecycle_state', 'coming_soon' );
            }

            $preorder_link = isset( $_POST['mbs_preorder_link'] )
                ? esc_url_raw( trim( wp_unslash( $_POST['mbs_preorder_link'] ) ) )
                : '';
            if ( $coming_soon === '1' && $preorder_link && ! filter_var( $preorder_link, FILTER_VALIDATE_URL ) ) {
                $preorder_link = '';
            }
            update_post_meta( $post_id, 'mbs_preorder_link', $preorder_link );
        } else {
            // FREE tier: force Coming Soon off and clear preorder link to prevent bypass.
            MBS_Book_Meta_DAO::upsert( $post_id, 'mbs_coming_soon', '0' );
            delete_post_meta( $post_id, 'mbs_preorder_link' );
        }

    }
}
