<?php
/**
 * Copyright (C) 2026 Plugixa (https://plugixa.com)
 * License: GNU General Public License v2 or later
 * License URI: http://www.gnu.org/licenses/gpl-2.0.txt
 */

/**
 * Review Form Template
 *
 * Star rating selector, author fields, review textarea, and AJAX submission.
 * Optionally includes reCAPTCHA v3 verification.
 *
 * Available variables:
 * @var int    $recipe_id       Recipe ID being reviewed
 * @var array  $view_config     Decoded JSON view configuration
 * @var string $unique_id       Unique instance ID
 *
 * @package PlugixaRecipe
 * @since   1.0.0
 */

defined( 'ABSPATH' ) || exit;

// phpcs:disable WordPress.NamingConventions.PrefixAllGlobals -- template-scope render variables, not global-namespace pollution.

$recipe_id          = isset( $recipe_id ) ? absint( $recipe_id ) : ( isset( $recipe->id ) ? absint( $recipe->id ) : 0 );
$pxr_settings       = get_option( 'plugixarecipe_settings', [] );
$recaptcha_enabled  = ! empty( $pxr_settings['recaptcha_reviews_enabled'] );
$recaptcha_site_key = ! empty( $pxr_settings['recaptcha_site_key'] ) ? esc_attr( $pxr_settings['recaptcha_site_key'] ) : '';
$allow_guests       = ! empty( $pxr_settings['allow_guest_reviews'] );
$require_rating        = $pxr_settings['require_rating'] ?? true;
$review_enable_images  = ! empty( $pxr_settings['review_enable_images'] );
$review_max_images     = (int) ( $pxr_settings['review_max_images'] ?? 3 );
$form_unique_id        = isset( $unique_id ) ? $unique_id : 'pxr-' . wp_rand( 1000, 9999 );
$form_id            = 'pxr-review-form-' . $form_unique_id;
$nonce              = wp_create_nonce( 'wp_rest' );
$rest_url           = esc_url( rest_url( 'plugixarecipe/v1/frontend/reviews' ) );

// Check if user is logged in for pre-filling.
$current_user = wp_get_current_user();
$is_logged_in = is_user_logged_in();
$user_name    = $is_logged_in ? $current_user->display_name : '';
$user_email   = $is_logged_in ? $current_user->user_email : '';

// Guest review gate: if guests not allowed and user not logged in, show login prompt.
if ( ! $allow_guests && ! $is_logged_in ) {
    echo '<div class="pxr-custom-review-form-wrapper pxr:mt-6">';
    echo '<p class="pxr:text-sm pxr:text-center pxr:py-4 pxr:opacity-70">';
    printf(
        /* translators: 1: opening anchor tag for the login link, 2: closing anchor tag. */
        esc_html__( 'Please %1$slog in%2$s to leave a review.', 'plugixarecipe' ),
        '<a href="' . esc_url( wp_login_url( get_permalink() ) ) . '" class="pxr:underline pxr:font-medium">',
        '</a>'
    );
    echo '</p></div>';
    return;
}
?>

<div class="pxr-custom-review-form-wrapper pxr:mt-6" id="<?php echo esc_attr( $form_id . '-wrapper' ); ?>">

    <h3 class="pxr-custom-review-form__title pxr:text-lg pxr:font-semibold pxr:mb-4">
        <?php esc_html_e( 'Leave a Review', 'plugixarecipe' ); ?>
    </h3>

    <!-- Success / Error Messages -->
    <div class="pxr-custom-review-form__messages pxr:hidden pxr:mb-4"
         data-pxr-review-messages
         role="alert"
         aria-live="polite">
        <div class="pxr-custom-review-form__success pxr:hidden pxr:p-4 pxr:rounded-lg pxr:text-sm pxr:font-medium"
             data-pxr-review-success>
            <?php esc_html_e( 'Thank you! Your review has been submitted successfully.', 'plugixarecipe' ); ?>
        </div>
        <div class="pxr-custom-review-form__error pxr:hidden pxr:p-4 pxr:rounded-lg pxr:text-sm pxr:font-medium"
             data-pxr-review-error>
        </div>
    </div>

    <form id="<?php echo esc_attr( $form_id ); ?>"
          class="pxr-custom-review-form pxr:space-y-4"
          data-pxr-review-form
          data-pxr-recipe-id="<?php echo esc_attr( $recipe_id ); ?>"
          data-pxr-rest-url="<?php echo esc_attr( $rest_url ); ?>"
          data-pxr-nonce="<?php echo esc_attr( $nonce ); ?>"
          <?php echo $require_rating ? 'data-pxr-rating-required' : ''; ?>
          novalidate>

        <!-- Star Rating Selector -->
        <fieldset class="pxr-custom-review-form__rating-field pxr:border-0 pxr:p-0 pxr:m-0">
            <legend class="pxr-custom-review-form__label pxr:block pxr:text-sm pxr:font-medium pxr:mb-2">
                <?php esc_html_e( 'Your Rating', 'plugixarecipe' ); ?>
                <?php if ( $require_rating ) : ?>
                    <span class="pxr:text-red-500" aria-hidden="true">*</span>
                <?php endif; ?>
            </legend>
            <div class="pxr-custom-review-form__stars pxr:flex pxr:gap-1"
                 data-pxr-rating-selector
                 role="radiogroup"
                 aria-label="<?php esc_attr_e( 'Select rating', 'plugixarecipe' ); ?>">
                <?php for ( $i = 1; $i <= 5; $i++ ) : ?>
                    <button type="button"
                            class="pxr-custom-review-star pxr:w-8 pxr:h-8 pxr:border-0 pxr:bg-transparent pxr:cursor-pointer pxr:p-0 pxr:transition-transform pxr:duration-100 hover:pxr:scale-110"
                            data-pxr-star-value="<?php echo esc_attr( $i ); ?>"
                            role="radio"
                            aria-checked="false"
                            aria-label="<?php
                                /* translators: %d: number of stars */
                                echo esc_attr( sprintf( _n( '%d star', '%d stars', $i, 'plugixarecipe' ), $i ) );
                            ?>">
                        <svg class="pxr-custom-star pxr-custom-star--empty pxr:w-8 pxr:h-8"
                             viewBox="0 0 20 20"
                             fill="currentColor"
                             aria-hidden="true">
                            <path d="M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z"/>
                        </svg>
                    </button>
                <?php endfor; ?>
            </div>
            <input type="hidden"
                   name="rating"
                   value=""
                   data-pxr-rating-value
                   required />
        </fieldset>

        <!-- Author Name -->
        <div class="pxr-custom-review-form__field">
            <label for="<?php echo esc_attr( $form_id . '-name' ); ?>"
                   class="pxr-custom-review-form__label pxr:block pxr:text-sm pxr:font-medium pxr:mb-1">
                <?php esc_html_e( 'Your Name', 'plugixarecipe' ); ?>
                <span class="pxr:text-red-500" aria-hidden="true">*</span>
            </label>
            <input type="text"
                   id="<?php echo esc_attr( $form_id . '-name' ); ?>"
                   name="author_name"
                   value="<?php echo esc_attr( $user_name ); ?>"
                   class="pxr-custom-input pxr:w-full pxr:px-3 pxr:py-2 pxr:border pxr:rounded-lg pxr:text-sm pxr:transition-colors pxr:duration-200"
                   placeholder="<?php esc_attr_e( 'John Doe', 'plugixarecipe' ); ?>"
                   required
                   autocomplete="name"
                   <?php echo $is_logged_in ? 'readonly' : ''; ?> />
        </div>

        <!-- Author Email -->
        <div class="pxr-custom-review-form__field">
            <label for="<?php echo esc_attr( $form_id . '-email' ); ?>"
                   class="pxr-custom-review-form__label pxr:block pxr:text-sm pxr:font-medium pxr:mb-1">
                <?php esc_html_e( 'Your Email', 'plugixarecipe' ); ?>
                <span class="pxr:text-red-500" aria-hidden="true">*</span>
            </label>
            <input type="email"
                   id="<?php echo esc_attr( $form_id . '-email' ); ?>"
                   name="author_email"
                   value="<?php echo esc_attr( $user_email ); ?>"
                   class="pxr-custom-input pxr:w-full pxr:px-3 pxr:py-2 pxr:border pxr:rounded-lg pxr:text-sm pxr:transition-colors pxr:duration-200"
                   placeholder="<?php esc_attr_e( 'john@example.com', 'plugixarecipe' ); ?>"
                   required
                   autocomplete="email"
                   <?php echo $is_logged_in ? 'readonly' : ''; ?> />
            <p class="pxr-custom-review-form__hint pxr:text-xs pxr:opacity-60 pxr:mt-1">
                <?php esc_html_e( 'Your email will not be published.', 'plugixarecipe' ); ?>
            </p>
        </div>

        <!-- Review Text -->
        <div class="pxr-custom-review-form__field">
            <label for="<?php echo esc_attr( $form_id . '-text' ); ?>"
                   class="pxr-custom-review-form__label pxr:block pxr:text-sm pxr:font-medium pxr:mb-1">
                <?php esc_html_e( 'Your Review', 'plugixarecipe' ); ?>
                <span class="pxr:text-red-500" aria-hidden="true">*</span>
            </label>
            <textarea id="<?php echo esc_attr( $form_id . '-text' ); ?>"
                      name="review_text"
                      class="pxr-custom-textarea pxr:w-full pxr:px-3 pxr:py-2 pxr:border pxr:rounded-lg pxr:text-sm pxr:transition-colors pxr:duration-200 pxr:resize-y"
                      rows="4"
                      placeholder="<?php esc_attr_e( 'Share your experience with this recipe...', 'plugixarecipe' ); ?>"
                      required
                      minlength="10"
                      maxlength="2000"></textarea>
        </div>

        <?php if ( $review_enable_images ) : ?>
            <!-- Image Upload -->
            <div class="pxr-custom-review-form__field">
                <label class="pxr-custom-review-form__label pxr:block pxr:text-sm pxr:font-medium pxr:mb-1">
                    <?php esc_html_e( 'Photos', 'plugixarecipe' ); ?>
                    <span class="pxr:text-xs pxr:opacity-60 pxr:font-normal">
                        (<?php
                        /* translators: %d: maximum number of images allowed. */
                        printf( esc_html__( 'max %d', 'plugixarecipe' ), absint( $review_max_images ) );
                        ?>)
                    </span>
                </label>
                <div class="pxr-review-images-preview pxr:flex pxr:flex-wrap pxr:gap-2 pxr:mb-2" data-pxr-review-images-preview></div>
                <label class="pxr-review-images-trigger pxr:inline-flex pxr:items-center pxr:gap-2 pxr:px-4 pxr:py-2 pxr:border pxr:border-dashed pxr:rounded-lg pxr:text-sm pxr:cursor-pointer pxr:transition-colors pxr:duration-200 hover:pxr:border-current"
                       data-pxr-review-images-trigger>
                    <svg class="pxr:w-4 pxr:h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2" aria-hidden="true">
                        <path stroke-linecap="round" stroke-linejoin="round" d="M12 4v16m8-8H4" />
                    </svg>
                    <?php esc_html_e( 'Add Photos', 'plugixarecipe' ); ?>
                    <input type="file"
                           name="review_images[]"
                           accept="image/jpeg,image/png,image/webp"
                           multiple
                           class="pxr:hidden"
                           data-pxr-review-images-input
                           data-max-files="<?php echo esc_attr( $review_max_images ); ?>"
                           data-max-size="<?php echo esc_attr( (int) ( $pxr_settings['max_upload_size'] ?? 5 ) ); ?>" />
                </label>
                <p class="pxr-custom-review-form__hint pxr:text-xs pxr:opacity-60 pxr:mt-1">
                    <?php esc_html_e( 'JPG, PNG or WebP. Max 5 MB each.', 'plugixarecipe' ); ?>
                </p>
            </div>
        <?php endif; ?>

        <?php if ( $recaptcha_enabled && $recaptcha_site_key ) : ?>
            <!-- reCAPTCHA v3 -->
            <input type="hidden" name="recaptcha_token" data-pxr-recaptcha-token />
        <?php endif; ?>

        <!-- Submit Button -->
        <div class="pxr-custom-review-form__actions">
            <button type="submit"
                    class="pxr-custom-btn pxr-custom-btn--primary pxr:inline-flex pxr:items-center pxr:gap-2 pxr:px-6 pxr:py-2.5 pxr:rounded-lg pxr:text-sm pxr:font-semibold pxr:border-0 pxr:cursor-pointer pxr:transition-all pxr:duration-200"
                    data-pxr-review-submit>
                <span class="pxr-custom-btn__text"><?php esc_html_e( 'Submit Review', 'plugixarecipe' ); ?></span>
                <svg class="pxr-custom-btn__spinner pxr:hidden pxr:w-4 pxr:h-4 pxr:animate-spin" viewBox="0 0 24 24" fill="none" aria-hidden="true">
                    <circle class="pxr:opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
                    <path class="pxr:opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"></path>
                </svg>
            </button>
        </div>

    </form>

</div>

<script>
(function() {
    'use strict';

    var formWrapper = document.getElementById('<?php echo esc_js( $form_id . '-wrapper' ); ?>');
    if (!formWrapper) return;

    var form = formWrapper.querySelector('[data-pxr-review-form]');
    if (!form) return;

    var recipeId     = form.getAttribute('data-pxr-recipe-id');
    var restUrl      = form.getAttribute('data-pxr-rest-url');
    var nonce        = form.getAttribute('data-pxr-nonce');
    var ratingInput  = form.querySelector('[data-pxr-rating-value]');
    var starButtons  = form.querySelectorAll('[data-pxr-star-value]');
    var submitBtn    = form.querySelector('[data-pxr-review-submit]');
    var btnText      = submitBtn ? submitBtn.querySelector('.pxr-custom-btn__text') : null;
    var btnSpinner   = submitBtn ? submitBtn.querySelector('.pxr-custom-btn__spinner') : null;
    var messagesEl   = formWrapper.querySelector('[data-pxr-review-messages]');
    var successEl    = formWrapper.querySelector('[data-pxr-review-success]');
    var errorEl      = formWrapper.querySelector('[data-pxr-review-error]');

    var currentRating = 0;
    var selectedFiles = [];

    // Image upload handling
    var imageInput   = form.querySelector('[data-pxr-review-images-input]');
    var imagePreview = formWrapper.querySelector('[data-pxr-review-images-preview]');
    var imageTrigger = formWrapper.querySelector('[data-pxr-review-images-trigger]');

    if (imageInput) {
        var maxFiles = parseInt(imageInput.getAttribute('data-max-files'), 10) || 3;
        var maxSize  = (parseInt(imageInput.getAttribute('data-max-size'), 10) || 5) * 1024 * 1024;

        imageInput.addEventListener('change', function() {
            var newFiles = Array.from(this.files);
            var remaining = maxFiles - selectedFiles.length;
            if (remaining <= 0) {
                showMessage('error', '<?php echo esc_js( __( 'Maximum number of images reached.', 'plugixarecipe' ) ); ?>');
                this.value = '';
                return;
            }

            newFiles.slice(0, remaining).forEach(function(file) {
                if (file.size > maxSize) return;
                if (!['image/jpeg', 'image/png', 'image/webp'].includes(file.type)) return;
                selectedFiles.push(file);
                addImagePreview(file, selectedFiles.length - 1);
            });

            this.value = '';
            updateTriggerVisibility();
        });
    }

    function addImagePreview(file, index) {
        if (!imagePreview) return;
        var reader = new FileReader();
        reader.onload = function(e) {
            var wrapper = document.createElement('div');
            wrapper.className = 'pxr-review-image-thumb pxr:relative pxr:w-20 pxr:h-20 pxr:rounded-lg pxr:overflow-hidden pxr:border';
            wrapper.setAttribute('data-pxr-image-index', index);
            wrapper.innerHTML =
                '<img src="' + e.target.result + '" alt="" class="pxr:w-full pxr:h-full pxr:object-cover" />'
                + '<button type="button" class="pxr-review-image-remove pxr:absolute pxr:top-0.5 pxr:right-0.5 pxr:w-5 pxr:h-5 pxr:rounded-full pxr:border-0 pxr:cursor-pointer pxr:flex pxr:items-center pxr:justify-center pxr:text-xs pxr:leading-none" style="background:rgba(0,0,0,.6);color:#fff;" aria-label="<?php echo esc_attr__( 'Remove', 'plugixarecipe' ); ?>">&times;</button>';

            wrapper.querySelector('.pxr-review-image-remove').addEventListener('click', function() {
                var idx = parseInt(wrapper.getAttribute('data-pxr-image-index'), 10);
                selectedFiles[idx] = null;
                wrapper.remove();
                updateTriggerVisibility();
            });

            imagePreview.appendChild(wrapper);
        };
        reader.readAsDataURL(file);
    }

    function updateTriggerVisibility() {
        if (!imageTrigger) return;
        var activeCount = selectedFiles.filter(function(f) { return f !== null; }).length;
        imageTrigger.style.display = activeCount >= maxFiles ? 'none' : '';
    }

    // Star rating interaction
    starButtons.forEach(function(btn) {
        btn.addEventListener('click', function() {
            currentRating = parseInt(this.getAttribute('data-pxr-star-value'), 10);
            ratingInput.value = currentRating;
            updateStars(currentRating);
        });

        btn.addEventListener('mouseenter', function() {
            var hoverValue = parseInt(this.getAttribute('data-pxr-star-value'), 10);
            highlightStars(hoverValue);
        });

        btn.addEventListener('mouseleave', function() {
            highlightStars(currentRating);
        });
    });

    function updateStars(value) {
        starButtons.forEach(function(btn) {
            var starValue = parseInt(btn.getAttribute('data-pxr-star-value'), 10);
            var svg = btn.querySelector('svg');
            var isSelected = starValue <= value;
            btn.setAttribute('aria-checked', isSelected ? 'true' : 'false');
            svg.classList.toggle('pxr-custom-star--full', isSelected);
            svg.classList.toggle('pxr-custom-star--empty', !isSelected);
        });
    }

    function highlightStars(value) {
        starButtons.forEach(function(btn) {
            var starValue = parseInt(btn.getAttribute('data-pxr-star-value'), 10);
            var svg = btn.querySelector('svg');
            svg.classList.toggle('pxr-custom-star--full', starValue <= value);
            svg.classList.toggle('pxr-custom-star--empty', starValue > value);
        });
    }

    function showMessage(type, text) {
        messagesEl.classList.remove('pxr:hidden');
        if (type === 'success') {
            successEl.classList.remove('pxr:hidden');
            errorEl.classList.add('pxr:hidden');
        } else {
            errorEl.textContent = text;
            errorEl.classList.remove('pxr:hidden');
            successEl.classList.add('pxr:hidden');
        }
    }

    function setLoading(loading) {
        if (submitBtn) submitBtn.disabled = loading;
        if (btnText) btnText.textContent = loading
            ? '<?php echo esc_js( __( 'Submitting...', 'plugixarecipe' ) ); ?>'
            : '<?php echo esc_js( __( 'Submit Review', 'plugixarecipe' ) ); ?>';
        if (btnSpinner) btnSpinner.classList.toggle('pxr:hidden', !loading);
    }

    // Form submission
    form.addEventListener('submit', function(e) {
        e.preventDefault();

        // Client-side validation
        var ratingRequired = form.hasAttribute('data-pxr-rating-required');
        if (ratingRequired && !currentRating) {
            showMessage('error', '<?php echo esc_js( __( 'Please select a rating.', 'plugixarecipe' ) ); ?>');
            return;
        }

        var authorName = form.querySelector('[name="author_name"]').value.trim();
        if (!authorName) {
            showMessage('error', '<?php echo esc_js( __( 'Name is required.', 'plugixarecipe' ) ); ?>');
            return;
        }

        var authorEmail = form.querySelector('[name="author_email"]').value.trim();
        if (!authorEmail || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(authorEmail)) {
            showMessage('error', '<?php echo esc_js( __( 'Please enter a valid email address.', 'plugixarecipe' ) ); ?>');
            return;
        }

        var reviewText = form.querySelector('[name="review_text"]').value.trim();
        if (!reviewText || reviewText.length < 10) {
            showMessage('error', '<?php echo esc_js( __( 'Review must be at least 10 characters.', 'plugixarecipe' ) ); ?>');
            return;
        }

        // Build FormData to support image uploads.
        var submitData = new FormData();
        submitData.append('recipe_id', recipeId);
        submitData.append('rating', currentRating);
        submitData.append('author_name', form.querySelector('[name="author_name"]').value.trim());
        submitData.append('author_email', form.querySelector('[name="author_email"]').value.trim());
        submitData.append('review_text', form.querySelector('[name="review_text"]').value.trim());
        submitData.append('_wpnonce', nonce);

        // Append selected images.
        selectedFiles.forEach(function(file) {
            if (file) submitData.append('review_images[]', file);
        });

        <?php if ( $recaptcha_enabled && $recaptcha_site_key ) : ?>
        // Get reCAPTCHA v3 token
        if (typeof grecaptcha !== 'undefined') {
            grecaptcha.ready(function() {
                grecaptcha.execute('<?php echo esc_js( $recaptcha_site_key ); ?>', { action: 'pxr_review' }).then(function(token) {
                    submitData.append('recaptcha_token', token);
                    submitReview(submitData);
                });
            });
            return;
        }
        <?php endif; ?>

        submitReview(submitData);
    });

    function submitReview(formPayload) {
        setLoading(true);
        messagesEl.classList.add('pxr:hidden');

        fetch(restUrl, {
            method: 'POST',
            headers: {
                'X-WP-Nonce': nonce
            },
            body: formPayload,
            credentials: 'same-origin'
        })
        .then(function(response) {
            return response.json().then(function(json) {
                return { ok: response.ok, data: json };
            });
        })
        .then(function(result) {
            setLoading(false);
            if (result.ok) {
                showMessage('success');
                form.reset();
                currentRating = 0;
                updateStars(0);
                selectedFiles = [];
                if (imagePreview) imagePreview.innerHTML = '';
                updateTriggerVisibility();
            } else {
                var msg = (result.data && result.data.message)
                    ? result.data.message
                    : '<?php echo esc_js( __( 'An error occurred. Please try again.', 'plugixarecipe' ) ); ?>';
                showMessage('error', msg);
            }
        })
        .catch(function() {
            setLoading(false);
            showMessage('error', '<?php echo esc_js( __( 'Network error. Please check your connection and try again.', 'plugixarecipe' ) ); ?>');
        });
    }
})();
</script>

<?php
// reCAPTCHA is enqueued properly (never printed as a raw <script src>), and only when the
// site owner switched it on and supplied their own key.
\PlugixaRecipe\Frontend\Shortcodes::enqueue_recaptcha( (bool) $recaptcha_enabled, (string) $recaptcha_site_key );
?>
