<?php

namespace Yuvayana\AcadlixImporter\Models;

use Illuminate\Database\Eloquent\Model;

defined('ABSPATH') || exit();

if (!class_exists('WpAdvQuizQuestion')) {
  class WpAdvQuizQuestion extends Model
  {
    protected $table;

    public function __construct($attributes = [])
    {
      parent::__construct($attributes);
      $this->table = acadlix()->helper()->acadlix_wp_prefix("wp_adv_quiz_question");
    }

    public function getAnswerTypeAttribute($value)
    {
      $arr = [
        'single' => 'singleChoice',
        'multiple' => 'multipleChoice',
        'free_answer' => 'freeChoice',
        'sort_answer' => 'sortingChoice',
        'matrix_sort_answer' => 'matrixSortingChoice',
        'cloze_answer' => 'fillInTheBlank',
        'assessment_answer' => '',
      ];
      return $arr[$value] ?? "singleChoice";
    }

    public function getAnswerDataAttribute($value)
    {
      global $wpdb;
      if (class_exists('WpAdvQuiz_Model_QuestionMapper')) {
        $table = esc_sql($this->table);
        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- table name cannot be prepared
        $row = $wpdb->get_row(
          $wpdb->prepare(
            "SELECT * FROM `$table` WHERE id = %d",
            $this->id
          ),
          ARRAY_A
        );

        $question = new \WpAdvQuiz_Model_Question($row);
        // $questionMapper = new \WpAdvQuiz_Model_QuestionMapper();
        // $question = $questionMapper->fetchOld($this->id);
        $answerArray = $question->getAnswerData();
        $data = [];
        $newData = [];
        if (is_array($answerArray) && count($answerArray) > 0) {
          foreach ($answerArray as $key => $answer) {
            $data = [
              'answer' => $answer->getAnswer(),
              'html' => $answer->isHtml(),
              'points' => $answer->getPoints(),
              'negative_points' => $answer->getNegativePoints() ?? 0,
              'correct' => $answer->isCorrect(),
              'sortString' => $answer->getSortString(),
              'sortStringHtml' => $answer->isSortStringHtml(),
            ];
            $newData[] = $this->getAnswerTypeData($this->answer_type, $data, $key, $this->points);
          }
        }
        // return $data;
        return [
          "singleChoice" => $this->answer_type == "singleChoice" ? $newData : [$this->getAnswerData("singleChoice", 0)],
          "multipleChoice" => $this->answer_type == "multipleChoice" ? $newData : [$this->getAnswerData("multipleChoice", 0)],
          "trueFalse" => $this->answer_type == "trueFalse" ? $newData : $this->getAnswerData("trueFalse", 0),
          "freeChoice" => $this->answer_type == "freeChoice" ? $newData[0] : $this->getAnswerData("freeChoice", 0),
          "sortingChoice" => $this->answer_type == "sortingChoice" ? $newData : [$this->getAnswerData("sortingChoice", 0)],
          "matrixSortingChoice" => $this->answer_type == "matrixSortingChoice" ? $newData : [$this->getAnswerData("matrixSortingChoice", 0)],
          "fillInTheBlank" => $this->answer_type == "fillInTheBlank" ? $newData[0] : $this->getAnswerData("fillInTheBlank", 0),
          "numerical" => $this->answer_type == "numerical" ? $newData[0] : $this->getAnswerData("numerical", 0),
          "rangeType" => $this->answer_type == "rangeType" ? $newData[0] : $this->getAnswerData("rangeType", 0),
        ];
      }
      return $value;
    }

    public function getAnswerTypeData($type = 'singleChoice', $data = [], $position = 0, $points = 0)
    {
      $answerData = $this->getAnswerData($type, $position);
      switch ($type) {
        case "singleChoice":
        case "multipleChoice":
          $answerData['option'] = $data['answer'];
          $answerData['points'] = $data['points'];
          $answerData['negative_points'] = $data['negative_points'] ?? 0;
          $answerData['isCorrect'] = $data['correct'];
          break;
        case "freeChoice":
          $answerData['option'] = $data['answer'];
          $answerData['correctOption'] = explode("\r\n", $data['answer']);
          break;
        case "sortingChoice":
          $answerData['option'] = $data['answer'];
          break;
        case "matrixSortingChoice":
          $answerData['criteria'] = $data['answer'];
          $answerData['element'] = $data['sortString'];
          break;
        case "fillInTheBlank":
          $answerData['option'] = $data['answer'];
          $answerData['correctOption'] = $this->extractOptions($data["answer"], $points);
          break;
        default:
          break;

      }
      return $answerData;
    }

    public function getAnswerData($type = 'singleChoice', $position = 0)
    {
      $answerData = [];
      switch ($type) {
        case "singleChoice":
        case "multipleChoice":
          $answerData = [
            "position" => $position,
            "option" => "",
            "points" => 0,
            "negative_points" => 0,
            "isCorrect" => false,
            "isChecked" => false,
          ];
          break;
        case "trueFalse":
          $answerData = [
            ["option" => "True", "isCorrect" => false, "isChecked" => false],
            ["option" => "False", "isCorrect" => false, "isChecked" => false],
          ];
          break;
        case "freeChoice":
          $answerData = [
            "option" => "",
            "correctOption" => [],
            "caseSensitive" => false,
            "yourAnswer" => ""
          ];
          break;
        case "sortingChoice":
          $answerData = [
            "option" => "",
            "position" => $position,
          ];
          break;
        case "matrixSortingChoice":
          $answerData = [
            "criteria" => "",
            "element" => "",
            "correctPosition" => $position,
            "yourPosition" => null,
          ];
          break;
        case "fillInTheBlank":
          $answerData = [
            "option" => "",
            "caseSensitive" => false,
            "correctOption" => [],
          ];
          break;
        case "numerical":
          $answerData = [
            "option" => "",
            "yourAnswer" => "",
          ];
          break;
        case "rangeType":
          $answerData = [
            "from" => "",
            "to" => "",
            "yourAnswer" => "",
          ];
          break;
        default:
          $answerData = [];
          break;
      }

      return $answerData;
    }

    public function extractOptions($input, $points = 0)
    {
      $regex = '/\{(\[?.*?\]?)\|?(\d*)\}/';
      preg_match_all($regex, $input, $matches, PREG_SET_ORDER);

      $correctOption = [];

      foreach ($matches as $match) {
        $options = $match[1]; // Extract the option part
        $point = isset($match[2]) && $match[2] !== '' ? intval($match[2]) : $points; // Extract points (default 0)

        if (strpos($options, '[') !== false) {
          // Handle multiple options like {[play][love][hate]}
          preg_match_all('/\[(.*?)\]/', $options, $optionMatches);
          $options = $optionMatches[1]; // Extract options without brackets
        } else {
          // Single option case
          $options = [$options];
        }

        $correctOption[] = [
          "option" => $options,
          "point" => $point,
          "yourAnswer" => ""
        ];
      }

      return $correctOption;
    }

  }
}