<?php
namespace QuizPress\API\Query;

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}
/**
 * Quiz
 *  - get_quiz_answer
 *  - get_quiz_all_answer_title_by_ids
 *  - get_question_answers_by_question_id
 *  - quiz_answer_insert
 *  - get_quiz_total_correct_answer_by_question_id
 *  - get_quiz_total_answer_by_question_id
 *  - get_total_quiz_attempt_correct_answers
 *  - is_quiz_correct_answer
 *  - get_quiz_attempt_answers_earned_marks
 *  - delete_answer
 *  - get_quiz_correct_answers
 */
class Answers {

	public static function get_quiz_answer( $ID ) {
		global $wpdb;
		$answer   = $wpdb->get_results( $wpdb->prepare( "SELECT answer_id, is_correct, question_id, answer_title, answer_points, answer_content, image_id, view_format, answer_order, answer_created_at, answer_updated_at FROM {$wpdb->prefix}quizpress_answers WHERE answer_id=%d", $ID ), OBJECT );
		return current( $answer );
	}

	public static function get_quiz_all_answer_title_by_ids( $IDs ) {
		global $wpdb;
		if ( ! empty( $IDs ) && is_numeric( $IDs ) ) {
			$IDs = array( (int) $IDs );
		}
		$implode_ids_placeholder = implode( ', ', array_fill( 0, count( $IDs ), '%d' ) );
		// phpcs:disable
		$answer   = $wpdb->get_results( $wpdb->prepare( "SELECT answer_title, image_id FROM {$wpdb->prefix}quizpress_answers WHERE answer_id IN($implode_ids_placeholder)", $IDs ), OBJECT );
		// phpcs:enable
		return $answer;
	}

	public static function get_attempt_given_answers( $attempt_id, $question_id ) {
		global $wpdb;
		return $wpdb->get_results( $wpdb->prepare( "SELECT answer as answer_title, answer_id FROM {$wpdb->prefix}quizpress_attempt_answers WHERE attempt_id = %d AND question_id = %d",  $attempt_id, $question_id ), OBJECT );
	}

	public static function get_question_answers_by_question_id( $question_id ) {
		global $wpdb;

		// Ensure the question_id is a valid integer
		$question_id = (int) $question_id;

		// Prepare and execute the query safely
		$table_name = $wpdb->prefix . 'quizpress_answers';
		$answers = $wpdb->get_results(
			$wpdb->prepare(
				"SELECT * FROM {$table_name} WHERE question_id = %d",// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
				$question_id
			)
		);

		// Process results
		if ( ! empty( $answers ) ) {
			foreach ( $answers as &$answer ) {
				// Convert 'is_correct' to integer (ensure numeric consistency)
				$answer->is_correct = (int) $answer->is_correct;

				// Attach image URL if available
				if ( ! empty( $answer->image_id ) ) {
					$answer->image_url = wp_get_attachment_url( (int) $answer->image_id );
				} else {
					$answer->image_url = null;
				}
			}
			unset( $answer ); // Break the reference
		}

		return $answers;
	}


	public static function quiz_answer_insert( $postarr ) {
		if ( ! is_array( $postarr ) ) {
			return null;
		}

		global $wpdb;

		$defaults = array(
			'question_id'        => 0,
			'answer_points'      => 0,
			'answer_title'       => '',
			'answer_content'     => '',
			'is_correct'         => 0,
			'image_id'           => 0,
			'view_format'        => 'text',
			'answer_order'       => 0,
			'answer_created_at'  => current_time( 'mysql' ),
			'answer_updated_at'  => current_time( 'mysql' ),
		);

		$question_arr = wp_parse_args( $postarr, $defaults );
		$question_arr['is_correct'] = ! empty( $question_arr['is_correct'] ) ? 1 : 0;
		$table_name = $wpdb->prefix . 'quizpress_answers';
		$formats    = array( '%d', '%d', '%s', '%s', '%d', '%d', '%s', '%d', '%s', '%s' );

		// Update or Insert logic
		if ( ! empty( $postarr['answer_id'] ) ) {
			$answer_ID = (int) $postarr['answer_id'];
			unset( $question_arr['answer_id'] );
			$question_arr['answer_updated_at'] = current_time( 'mysql' );

			$updated = $wpdb->update(
				$table_name,
				$question_arr,
				array( 'answer_id' => $answer_ID ),
				$formats,
				array( '%d' )
			);

			return $updated !== false ? $answer_ID : new \WP_Error( 'db_update_error', $wpdb->last_error );
		}

		$inserted = $wpdb->insert( $table_name, $question_arr, $formats );
		return $inserted ? $wpdb->insert_id : new \WP_Error( 'db_insert_error', $wpdb->last_error );
	}

	public static function get_quiz_total_correct_answer_by_question_id( $ID ) {
		global $wpdb;
		$answers   = $wpdb->get_results( $wpdb->prepare( "SELECT is_correct FROM {$wpdb->prefix}quizpress_answers WHERE question_id=%d AND is_correct=%d", $ID, 1 ), OBJECT );
		return count( $answers );
	}

	public static function get_quiz_total_answer_by_question_id( $ID ) {
		global $wpdb;
		$total_questions = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(question_id) FROM {$wpdb->prefix}quizpress_answers WHERE question_id=%d", $ID ) );
		return $total_questions;
	}

	public static function get_total_quiz_attempt_correct_answers( $ID ) {
		global $wpdb;
		$correct_answers = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(is_correct) FROM {$wpdb->prefix}quizpress_attempt_answers WHERE attempt_id=%d AND is_correct=%d", $ID, 1 ) );
		return (int) $correct_answers;
	}

	public static function is_image_answer_quiz_correct_answer( $IDs, $question_id = '' ) {
		global $wpdb;
		if ( is_array( $IDs ) ) {
			$correct_answer_count = 0;
			foreach ( $IDs as $ID => $value ) {
				$correct_answer_count  += $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(answer_id) FROM {$wpdb->prefix}quizpress_answers WHERE answer_id=%d AND answer_title=%s", $ID, $value ) );
			}
			$total_correct_answer = (int) self::get_quiz_total_answer_by_question_id( $question_id );
			return ( $total_correct_answer === $correct_answer_count ? true : false );
		}
		return false;
	}

	public static function is_fill_in_the_blanks_quiz_correct_answer( $given_answer_args, $question_id = '' ) {
		global $wpdb;

		if ( is_array( $given_answer_args ) ) {
			// Join the answers with a pipe symbol
			$given_answer = implode( '|', $given_answer_args );

			// Query for a match ignoring any spaces around the pipe symbol in both the database and given answer
			$given_answer_clean = str_replace( ' ', '', $given_answer );
			$search = '%' . $wpdb->esc_like( $given_answer_clean ) . '%';

			$is_correct = $wpdb->get_var(
				$wpdb->prepare(
					"SELECT COUNT(answer_id)
					FROM {$wpdb->prefix}quizpress_answers
					WHERE question_id = %d
					AND REPLACE(answer_content, ' ', '') LIKE %s",
					$question_id,
					$search
				)
			);
			return (bool) $is_correct;
		}

		return false;
	}

	public static function is_quiz_correct_answer( $IDs, $question_id = '' ) {
		global $wpdb;
		if ( is_array( $IDs ) ) {
			$correct_answer_count = 0;
			$has_wrong_answer = false;
			foreach ( $IDs as $ID ) {
				$answers   = $wpdb->get_results( $wpdb->prepare( "SELECT is_correct FROM {$wpdb->prefix}quizpress_answers WHERE answer_id=%d", $ID ), OBJECT );
				if ( (bool) current( $answers )->is_correct === true ) {
					$correct_answer_count++;
				} else {
					$has_wrong_answer = true;
					break;
				}
			}
			if ( $has_wrong_answer ) {
				return false;
			}
			return $correct_answer_count ? true : false;
		}
		$answers   = $wpdb->get_results( $wpdb->prepare( "SELECT is_correct FROM {$wpdb->prefix}quizpress_answers WHERE answer_id=%d", $IDs ), OBJECT );
		return (bool) current( $answers )->is_correct;
	}

	public static function get_quiz_attempt_answer( $ID ) {
		global $wpdb;
		$attemp_answer   = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}quizpress_attempt_answers WHERE attempt_answer_id=%d", $ID ), OBJECT );
		return current( $attemp_answer );
	}

	public static function get_quiz_attempt_answers_earned_marks( $user_id, $attempt_id ) {
		global $wpdb;
		$earned_marks = $wpdb->get_results(
			$wpdb->prepare(
				"SELECT sum(achieved_mark) as total_marks FROM {$wpdb->prefix}quizpress_attempt_answers WHERE user_id=%d AND attempt_id=%d;",
				$user_id,
				$attempt_id
			),
			OBJECT
		);
		return (float) current( $earned_marks )->total_marks;
	}

	public static function delete_answer( $answer_id ) {
		global $wpdb;
		return $wpdb->delete( $wpdb->prefix . 'quizpress_answers', array( 'answer_id' => $answer_id ), array( '%d' ) );
	}


	public static function get_quiz_correct_answers( $question_id, $question_type ) {
		global $wpdb;

		$query = $wpdb->prepare("
			SELECT 
				a.answer_id,
				a.answer_title,
				a.answer_points,
				a.image_id,
				a.view_format,
				a.answer_order,
				a.answer_created_at,
				a.answer_updated_at,
				q.question_type
			FROM {$wpdb->prefix}quizpress_answers AS a
			INNER JOIN {$wpdb->prefix}quizpress_questions AS q 
				ON a.question_id = q.question_id
			WHERE a.question_id = %d
			AND q.question_type = %s
			AND a.is_correct = %d
		", $question_id, $question_type, 1 );

	return $wpdb->get_results( $query, OBJECT );// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared 
}

	public static function get_answers( $args ) {
		global $wpdb;
		$defaults = array(
			'limit' => 10,
			'offset' => 0,
		);
		$args = wp_parse_args( $args, $defaults );
		return $wpdb->get_results(
			$wpdb->prepare(
				"SELECT * FROM {$wpdb->prefix}quizpress_answers ORDER BY answer_created_at DESC LIMIT %d, %d;",
				$args['offset'],
				$args['limit']
			),
			OBJECT
		);
	}

	public static function prepare_given_answer( $question_type, $attempt_item ) {
		if ( $question_type === 'fill_in_the_blanks' ) {
			// Decode JSON and extract "value" in one line
			$given = json_decode( $attempt_item->given_answer, true ) ?? [];

			$replacement = array_map(
				'trim',
				array_column( array_filter( $given, fn($a) => isset($a['value']) ), 'value' )
			);

			$i = 0;

			// Replace {dash} tokens
			$answer_title = preg_replace_callback(
				'/\{dash\}/',
				function () use ( &$i, $replacement ) {
					return isset( $replacement[$i] )
						? '{' . $replacement[$i++] . '}'
						: '{}';
				},
				(string) $attempt_item->correct_answers
			);

			return [
				[
					'answer_title' => $answer_title,
				],
			];
		} elseif ( in_array( $question_type, [ 'short_answer', 'number', 'paragraph', 'date' ] ) ) {
			return array(
				array(
					'answer_title' => $attempt_item->given_answer,
				)
			);
		}//end if

		$answers = self::get_attempt_given_answers( $attempt_item->attempt_id, $attempt_item->question_id );

		return $answers;
	}

	public static function prepare_correct_answer( $question_type, $attempt_item ) {
		if ( 'fill_in_the_blanks' === $question_type ) {
			$values = array_map( 'trim', explode( '|', (string) $attempt_item->answer_content ) );

			$i = 0;
			// Replace {dash} placeholders with {value} or {}
			$answer_title = preg_replace_callback(
				'/\{dash\}/',
				function () use ( & $i, $values ) {

					$value = $values[$i] ?? '';
					$i++;

					return $value !== '' ? '{' . $value . '}' : '{}';
				},
				(string) $attempt_item->correct_answers
			);

			return [
				[
					'answer_title' => $answer_title,
				],
			];
		} elseif ( 'short_answer' === $question_type ) {
			return array(
				[ 'answer_title' => __( 'Manually Reviewed Required.', 'quizpress' ) ],
			);
		}//end if

		$answers = self::get_quiz_correct_answers( $attempt_item->question_id, $question_type );

		// convert image id to image url
		foreach ( $answers as $answer ) {
			if ( $answer->image_id ) {
				$image = wp_get_attachment_image_src( $answer->image_id );
				$answer->image_url = $image[0];
			}
			unset( $answer->image_id );
		}

		return $answers;
	}

	public static function get_quiz_answers_by_question_id( $question_id, $question_type ) {
		global $wpdb;
		// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
		return $wpdb->get_results(
			$wpdb->prepare(
				"SELECT answer_id, quiz_id, answer_title, image_id, view_format, answer_order, answer_created_at, answer_updated_at  FROM {$wpdb->prefix}quizpress_answers WHERE question_id=%d AND question_type=%s",
				$question_id,
				$question_type
			),
			OBJECT
		);
	}

}
