<?php
/**
 * Survey Widget for BoostBot
 *
 * Quick satisfaction survey widget.
 *
 * @package BoostBot
 * @since 1.0.0
 */

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

/**
 * Class BoostBot_Survey_Widget
 *
 * Quick satisfaction survey widget.
 */
class BoostBot_Survey_Widget extends BoostBot_Widget_Base {

    /**
     * Widget ID.
     *
     * @var string
     */
    protected $id = 'survey';

    /**
     * Pro only widget.
     *
     * @var bool
     */
    protected $is_free = false;

    /**
     * Get widget name.
     *
     * @since 1.0.0
     * @return string Widget name.
     */
    public function get_name(): string {
        return __( 'Satisfaction Survey', 'boostbot' );
    }

    /**
     * Get widget description.
     *
     * @since 1.0.0
     * @return string Widget description.
     */
    public function get_description(): string {
        return __( 'Quick satisfaction survey', 'boostbot' );
    }

    /**
     * Get widget icon.
     *
     * @since 1.0.0
     * @return string Icon name.
     */
    public function get_icon(): string {
        return 'star';
    }

    /**
     * Get widget schema.
     *
     * @since 1.0.0
     * @return array Widget schema.
     */
    public function get_schema(): array {
        return array(
            'question'        => __( 'How would you rate our service?', 'boostbot' ),
            'type'            => 'stars', // stars, emoji, nps
            'max_rating'      => 5,
            'show_feedback'   => true,
            'feedback_label'  => __( 'Additional feedback (optional)', 'boostbot' ),
            'submit_text'     => __( 'Submit', 'boostbot' ),
            'success_message' => __( 'Thank you for your feedback!', 'boostbot' ),
        );
    }

    /**
     * Get widget configuration.
     *
     * @since 1.0.0
     * @param array $data Widget data.
     * @return array Widget configuration.
     */
    public function get_config( array $data = array() ): array {
        $config = parent::get_config( $data );

        // Allow customizing question
        if ( ! empty( $data['question'] ) ) {
            $config['schema']['question'] = sanitize_text_field( $data['question'] );
        }

        // Allow customizing type
        if ( ! empty( $data['type'] ) ) {
            $config['schema']['type'] = sanitize_key( $data['type'] );
        }

        // Emoji options for emoji type
        $config['emojis'] = array(
            1 => '😡',
            2 => '😕',
            3 => '😐',
            4 => '🙂',
            5 => '😍',
        );

        return $config;
    }

    /**
     * Validate submitted data.
     *
     * @since 1.0.0
     * @param array $data Submitted data.
     * @return array Validation result.
     */
    public function validate( array $data ): array {
        $errors = array();

        if ( empty( $data['rating'] ) ) {
            $errors['rating'] = __( 'Please select a rating', 'boostbot' );
        } else {
            // Bound the rating to the schema's max_rating so it stays consistent
            // with the aggregate distribution buckets (which run 0..max_rating).
            $max_rating = (int) ( $this->get_schema()['max_rating'] ?? 5 );
            $rating     = absint( $data['rating'] );
            if ( $rating < 1 || $rating > $max_rating ) {
                $errors['rating'] = __( 'Invalid rating', 'boostbot' );
            }
        }

        return array(
            'valid'  => empty( $errors ),
            'errors' => $errors,
        );
    }

    /**
     * Process submitted data.
     *
     * @since 1.0.0
     * @param array $data    Submitted data.
     * @param array $context Submission context.
     * @return array Processing result.
     */
    public function process( array $data, array $context = array() ): array {
        $rating = absint( $data['rating'] );
        $feedback = isset( $data['feedback'] ) 
            ? $this->sanitize_field( $data['feedback'], 'textarea' ) 
            : '';

        // Update conversation with satisfaction score
        if ( ! empty( $context['conversation_id'] ) ) {
            $conversation_model = new BoostBot_Conversation_Model();
            $conversation = $conversation_model->get_by_conversation_id( $context['conversation_id'] );

            if ( $conversation ) {
                $conversation_model->update( $conversation->id, array(
                    'satisfaction_score' => $rating,
                ) );
            }
        }

        // Save survey response
        $this->save_survey_response( $rating, $feedback, $context );

        BoostBot_Logger::info( 'Survey submitted', array(
            'rating'          => $rating,
            'has_feedback'    => ! empty( $feedback ),
            'conversation_id' => $context['conversation_id'] ?? '',
        ) );

        // Fire hook
        $this->do_action( 'survey_submitted', $rating, $feedback, $context );

        return array(
            'rating'  => $rating,
            'message' => $this->get_schema()['success_message'],
        );
    }

    /**
     * Save survey response.
     *
     * @since 1.0.0
     * @param int    $rating   Rating value.
     * @param string $feedback Feedback text.
     * @param array  $context  Context data.
     */
    private function save_survey_response( int $rating, string $feedback, array $context ) {
        $responses = get_option( 'boostbot_survey_responses', array() );

        $responses[] = array(
            'rating'          => $rating,
            'feedback'        => $feedback,
            'conversation_id' => $context['conversation_id'] ?? '',
            'visitor_id'      => $context['visitor_id'] ?? '',
            'page_url'        => $context['page_url'] ?? '',
            'created_at'      => current_time( 'mysql' ),
        );

        // Keep last 1000 responses
        if ( count( $responses ) > 1000 ) {
            $responses = array_slice( $responses, -1000 );
        }

        update_option( 'boostbot_survey_responses', $responses );

        // Update aggregate stats
        $this->update_survey_stats( $rating );
    }

    /**
     * Update aggregate survey statistics.
     *
     * @since 1.0.0
     * @param int $rating New rating.
     */
    private function update_survey_stats( int $rating ) {
        // Size the distribution buckets to the full 0..max_rating range so NPS or
        // other >5 scales stay consistent with the total/average.
        $max_rating           = (int) ( $this->get_schema()['max_rating'] ?? 5 );
        $default_distribution = array();
        for ( $i = 0; $i <= $max_rating; $i++ ) {
            $default_distribution[ $i ] = 0;
        }

        $stats = get_option( 'boostbot_survey_stats', array(
            'total_responses' => 0,
            'total_rating'    => 0,
            'average_rating'  => 0,
            'distribution'    => $default_distribution,
        ) );

        $stats['total_responses']++;
        $stats['total_rating'] += $rating;
        $stats['average_rating'] = round( $stats['total_rating'] / $stats['total_responses'], 2 );

        if ( $rating >= 0 && $rating <= $max_rating ) {
            if ( ! isset( $stats['distribution'][ $rating ] ) ) {
                $stats['distribution'][ $rating ] = 0;
            }
            $stats['distribution'][ $rating ]++;
        }

        update_option( 'boostbot_survey_stats', $stats );
    }
}
