<?php
/**
 * Business logic service for Team Survey workflow
 *
 * Handles survey configuration, response management, and moderation.
 * Responses are stored in wp_bw_schema_survey_responses custom table.
 *
 * @package BW_Babel
 * @since 3.0.0-babel
 */

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

class BW_Babel_Service_Survey {

	/**
	 * Prefix for all options (will be bw_babel_* in v3.0.0+)
	 * For now, keeps backward compatibility with bw_schema_*
	 *
	 * @var string
	 */
	const PREFIX = 'bw_schema_'; // TODO: Switch to 'bw_babel_' at v3.0.0-babel release

	// ====== SURVEY CONFIGURATION ======

	/**
	 * Check if survey is enabled
	 *
	 * @return bool True if survey feature is enabled
	 */
	public static function is_enabled() {
		return get_option( self::PREFIX . 'survey_enabled', 'no' ) === 'yes';
	}

	/**
	 * Enable or disable survey
	 *
	 * @param bool $enabled True to enable
	 * @return bool Success
	 */
	public static function set_enabled( $enabled ) {
		update_option( self::PREFIX . 'survey_enabled', $enabled ? 'yes' : 'no' );
		return true;
	}

	/**
	 * Get survey settings
	 *
	 * @return array Survey configuration (slug, opens_at, expires_at, notify_email, etc.)
	 */
	public static function get_settings() {
		return array(
			'enabled'        => self::is_enabled(),
			'slug'           => get_option( self::PREFIX . 'survey_slug', 'survey' ),
			'opens_at'       => get_option( self::PREFIX . 'survey_opens_at', '' ),
			'expires_at'     => get_option( self::PREFIX . 'survey_expires_at', '' ),
			'notify_email'   => get_option( self::PREFIX . 'survey_notify_email', get_option( 'admin_email' ) ),
			'notify_enabled' => get_option( self::PREFIX . 'survey_notify_enabled', 'no' ) === 'yes',
			'intro_html'     => get_option( self::PREFIX . 'survey_intro_html', '' ),
			'grant_editors'  => get_option( self::PREFIX . 'survey_grant_editors', 'no' ) === 'yes',
		);
	}

	/**
	 * Update survey settings
	 *
	 * @param array $settings Survey settings to update
	 * @return array|WP_Error Success array or WP_Error
	 */
	public static function save_settings( $settings ) {
		// Validate email
		if ( ! empty( $settings['notify_email'] ) && ! is_email( $settings['notify_email'] ) ) {
			return new WP_Error( 'invalid_email', __( 'Notification email is invalid.', 'bw-babel' ) );
		}

		// Save settings
		update_option( self::PREFIX . 'survey_slug', sanitize_key( $settings['slug'] ?? 'survey' ) );
		update_option( self::PREFIX . 'survey_opens_at', sanitize_text_field( $settings['opens_at'] ?? '' ) );
		update_option( self::PREFIX . 'survey_expires_at', sanitize_text_field( $settings['expires_at'] ?? '' ) );
		update_option( self::PREFIX . 'survey_notify_email', sanitize_email( $settings['notify_email'] ?? '' ) );
		update_option( self::PREFIX . 'survey_notify_enabled', $settings['notify_enabled'] ? 'yes' : 'no' );
		update_option( self::PREFIX . 'survey_intro_html', wp_kses_post( $settings['intro_html'] ?? '' ) );
		update_option( self::PREFIX . 'survey_grant_editors', $settings['grant_editors'] ? 'yes' : 'no' );

		return array( 'success' => true );
	}

	// ====== SURVEY RESPONSES ======

	/**
	 * Get pending survey responses (not yet approved/rejected)
	 *
	 * @param int $limit Limit number of results
	 * @return array Array of response rows
	 */
	public static function get_pending_responses( $limit = 50 ) {
		global $wpdb;

		$table = $wpdb->prefix . 'bw_schema_survey_responses';

		return $wpdb->get_results(
			$wpdb->prepare(
				"SELECT * FROM $table WHERE status = %s ORDER BY created_at DESC LIMIT %d",
				'new',
				$limit
			)
		);
	}

	/**
	 * Get count of pending responses
	 *
	 * @return int Number of pending responses
	 */
	public static function get_pending_count() {
		global $wpdb;

		$table = $wpdb->prefix . 'bw_schema_survey_responses';

		return (int) $wpdb->get_var(
			"SELECT COUNT(*) FROM $table WHERE status = 'new'"
		);
	}

	/**
	 * Get a single survey response
	 *
	 * @param int $response_id Response ID
	 * @return array|null Response data or null if not found
	 */
	public static function get_response( $response_id ) {
		global $wpdb;

		$table = $wpdb->prefix . 'bw_schema_survey_responses';

		return $wpdb->get_row(
			$wpdb->prepare(
				"SELECT * FROM $table WHERE id = %d",
				$response_id
			)
		);
	}

	/**
	 * Create a new survey response
	 *
	 * Stores a response from the public survey form.
	 *
	 * @param array $response_data Response data (submitter_name, submitter_email, payload, etc.)
	 * @return array|WP_Error Array with response ID or WP_Error
	 */
	public static function create_response( $response_data ) {
		// Validate
		if ( empty( $response_data['submitter_name'] ) ) {
			return new WP_Error( 'missing_name', __( 'Submitter name is required.', 'bw-babel' ) );
		}

		global $wpdb;

		$table = $wpdb->prefix . 'bw_schema_survey_responses';

		$data = array(
			'target_post_id'      => isset( $response_data['target_post_id'] ) ? absint( $response_data['target_post_id'] ) : null,
			'submitter_name'      => sanitize_text_field( $response_data['submitter_name'] ),
			'submitter_email'     => sanitize_email( $response_data['submitter_email'] ?? '' ),
			'submitter_ip'        => sanitize_text_field( $_SERVER['REMOTE_ADDR'] ?? '' ),
			'status'              => 'new',
			'raw_payload'         => wp_json_encode( $response_data['payload'] ?? array() ),
			'structured_payload'  => null,
			'moderator_notes'     => '',
			'created_at'          => current_time( 'mysql' ),
			'updated_at'          => current_time( 'mysql' ),
			'published_at'        => null,
		);

		$formats = array( '%d', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s' );

		$result = $wpdb->insert( $table, $data, $formats );

		if ( ! $result ) {
			return new WP_Error( 'db_error', __( 'Failed to save response.', 'bw-babel' ) );
		}

		// Send notification if enabled
		self::maybe_send_notification( $wpdb->insert_id, $response_data );

		return array( 'id' => $wpdb->insert_id, 'success' => true );
	}

	/**
	 * Approve a survey response
	 *
	 * Marks response as approved and optionally publishes it.
	 *
	 * @param int  $response_id Response ID
	 * @param bool $publish True to publish immediately
	 * @return array|WP_Error Success array or WP_Error
	 */
	public static function approve_response( $response_id, $publish = false ) {
		global $wpdb;

		$table = $wpdb->prefix . 'bw_schema_survey_responses';

		$data = array(
			'status'     => 'approved',
			'updated_at' => current_time( 'mysql' ),
		);

		if ( $publish ) {
			$data['published_at'] = current_time( 'mysql' );
		}

		$result = $wpdb->update( $table, $data, array( 'id' => $response_id ) );

		if ( false === $result ) {
			return new WP_Error( 'db_error', __( 'Failed to approve response.', 'bw-babel' ) );
		}

		return array( 'success' => true );
	}

	/**
	 * Reject a survey response
	 *
	 * @param int    $response_id Response ID
	 * @param string $reason Reason for rejection (spam, duplicate, etc.)
	 * @return array|WP_Error Success array or WP_Error
	 */
	public static function reject_response( $response_id, $reason = '' ) {
		global $wpdb;

		$table = $wpdb->prefix . 'bw_schema_survey_responses';

		$data = array(
			'status'              => 'rejected',
			'updated_at'          => current_time( 'mysql' ),
			'moderator_notes'     => $reason ? sanitize_text_field( $reason ) : '',
		);

		$result = $wpdb->update( $table, $data, array( 'id' => $response_id ) );

		if ( false === $result ) {
			return new WP_Error( 'db_error', __( 'Failed to reject response.', 'bw-babel' ) );
		}

		return array( 'success' => true );
	}

	/**
	 * Add moderator notes to a response
	 *
	 * @param int    $response_id Response ID
	 * @param string $notes Notes to add
	 * @return bool Success
	 */
	public static function add_notes( $response_id, $notes ) {
		global $wpdb;

		$table = $wpdb->prefix . 'bw_schema_survey_responses';

		$wpdb->update(
			$table,
			array(
				'moderator_notes' => sanitize_textarea_field( $notes ),
				'updated_at'      => current_time( 'mysql' ),
			),
			array( 'id' => $response_id )
		);

		return true;
	}

	/**
	 * Delete a survey response
	 *
	 * @param int $response_id Response ID
	 * @return bool Success
	 */
	public static function delete_response( $response_id ) {
		global $wpdb;

		$table = $wpdb->prefix . 'bw_schema_survey_responses';

		$wpdb->delete( $table, array( 'id' => $response_id ) );

		return true;
	}

	// ====== HELPERS ======

	/**
	 * Send notification email about new response
	 *
	 * @param int   $response_id Response ID
	 * @param array $response_data Response data
	 * @return bool Success
	 */
	private static function maybe_send_notification( $response_id, $response_data ) {
		$settings = self::get_settings();

		if ( ! $settings['notify_enabled'] ) {
			return false;
		}

		$to = $settings['notify_email'];
		if ( ! is_email( $to ) ) {
			return false;
		}

		$subject = sprintf(
			__( '[%s] New survey response from %s', 'bw-babel' ),
			get_bloginfo( 'name' ),
			$response_data['submitter_name']
		);

		$message = sprintf(
			__( "New survey response received from %s (%s)\n\nReview it here: %s\n\nSubmitter email: %s", 'bw-babel' ),
			$response_data['submitter_name'],
			current_time( 'mysql' ),
			admin_url( "admin.php?page=bw-ai-schema-survey-queue&response=$response_id" ),
			$response_data['submitter_email'] ?? '(none)'
		);

		return wp_mail( $to, $subject, $message );
	}

	/**
	 * Get survey URL
	 *
	 * @return string Survey form URL
	 */
	public static function get_survey_url() {
		$settings = self::get_settings();
		return home_url( '/survey/' . $settings['slug'] . '/' );
	}

	/**
	 * Check if survey is currently active (open)
	 *
	 * Takes into account opens_at and expires_at times.
	 *
	 * @return bool True if survey is open
	 */
	public static function is_survey_active() {
		if ( ! self::is_enabled() ) {
			return false;
		}

		$settings = self::get_settings();
		$now = current_time( 'mysql' );

		if ( ! empty( $settings['opens_at'] ) && $now < $settings['opens_at'] ) {
			return false; // Survey hasn't opened yet
		}

		if ( ! empty( $settings['expires_at'] ) && $now > $settings['expires_at'] ) {
			return false; // Survey has expired
		}

		return true;
	}
}
