<?php

namespace App\Http\Controllers;

use App\Events\AssessmentInitEvent;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Illuminate\Support\Facades\Event;
use Illuminate\Support\Facades\Storage;
use Mtc\Modules\Members\Classes\Auth;
use Mtc\Shop\Assessment\Assessment;
use Mtc\Shop\Assessment\BmiEthnicity;
use Mtc\Shop\Assessment\Form;
use Mtc\Shop\Assessment\Question;
use Mtc\Shop\MedicalCondition;
use Mtc\Shop\Medication;

class AssessmentDisplayController extends Controller
{
    private $form;
    private $member;
    private $prev_assessment;

    /** * Entry Points ** */

    public function index($form_id, Request $request)
    {
        Event::dispatch(AssessmentInitEvent::class, new AssessmentInitEvent($request));

        if (session()->has(Assessment::ASSESSMENT_INIT_REDIRECT)) {
            return redirect(session(Assessment::ASSESSMENT_INIT_REDIRECT));
        }

        $this->form = Form::query()
            ->findOrFail($form_id);
        $this->form->previously_complete = false;
        $this->member = Auth::getLoggedInMember();

        if (! empty($this->member->id)) {
            $this->prev_assessment = $this->form->getMemberAssessment($this->member);
            $this->form->previously_complete = true;
        }

        $form_image_path = ''; //DEFAULT_THEME_PATH . '/images/svgs/blank.svg';
        if ($this->form->icon) {
            $form_image_path = $this->form->icon->getFileUrl();
        }

        $this->form->form_image = [
            'src' => $form_image_path,
            'alt' => $this->form->name,
        ];
        $this->form->form_title = $this->form->name;

        //Added this to use with a back button on the assessments page
        // Should really get the category or product link and return to those pages instead
        $return_link = $request->headers->get('referer');

        if (empty($return_link)) {
            $return_link = '/online-doctor/';
        }

        $assessment_form_data = [
            'form' => $this->form,
            'question_sections' => $this->get_form_sections(),
            'doctor_surgery' => $this->get_doctor_surgery(),
            'health_profile' => $this->get_health_profile(),
            'all_medications' => Medication::query()->pluck('name')->toArray(),
            'all_medical_conditions' => MedicalCondition::query()->pluck('name')->toArray(),
            'category_id' => $request->input('c', 0),
            'product_id' => $request->input('p', 0),
            'size_id' => $request->input('s', 0),
            'review_hash' => $request->input('review', ''),
            'quantity' => $request->input('q', 1),
            'return_link' => $return_link,
            'routes' => [
                'assessment-submit' => route(
                    'assessment-submit',
                    [
                        'form_id' => $this->form->id,
                    ],
                    false,
                ),
                'shop-basket-allowed-products' => route('shop-basket-allowed-products', [], false),
                'add-to-basket' => '/shop/addtobasket.php',
            ],
        ];

        return template('shop/assessment/assessment.twig', $assessment_form_data);
    }

    /** * Helpers ** */

    private function get_form_sections()
    {
        $sections = [];

        $question_sections = $this->build_question_sections(count($sections) + 1);

        //Set which section submits the for before getting products
        foreach ($question_sections as $key => $section) {
            $question_sections[$key]['submit_assessment'] = false;
        }

        $question_sections[count($question_sections) - 1]['submit_assessment'] = true;

        $sections = array_merge($sections, $question_sections);

        //Add product selection section
        $sections[] = [
            'id' => 998,
            'order' => 98,
            'title' => 'Our Recommendations',
            'product_recommendations' => true,
            'content' => false,
            'can_proceed' => false,
            'questions' => [],
            'section_number' => count($sections) + 1,
            'visible' => false,
            'product_selection' => true,
            'product_confirmation' => false,
            'submit_assessment' => false,
            'loading' => false,
        ];

        //Product confirmation and pay
        $sections[] = [
            'id' => 999,
            'order' => 99,
            'title' => 'Confirm & Pay',
            'product_recommendations' => false,
            'content' => false,
            'can_proceed' => false,
            'questions' => [],
            'section_number' => count($sections) + 1,
            'visible' => false,
            'product_selection' => false,
            'product_confirmation' => true,
            'submit_assessment' => false,
            'loading' => false,
        ];

        return $sections;
    }

    private function get_doctor_surgery()
    {
        return ! empty($this->member->doctor_surgery)
            ? json_decode((string) $this->member->doctor_surgery)
            : (object) [
                'manual_doctor_surgery' => 0,
                'id' => 0,
                'practice_name' => '',
                'city' => '',
                'address_1' => '',
                'address_2' => '',
                'postcode' => '',
                'phone' => '',
            ];
    }

    private function get_health_profile()
    {
        return [
            'medications' => empty($this->member->medications)
                ? ''
                : implode(',', json_decode((string) $this->member->medications)),
            'allergies' => empty($this->member->allergies) ? '' : implode(',', json_decode((string) $this->member->allergies)),
            'conditions' => empty($this->member->conditions)
                ? ''
                : implode(',', json_decode((string) $this->member->conditions)),
        ];
    }

    private function build_question_sections($section_number = 1)
    {
        $form = $this->form;

        if (empty($form))
            return [];

        $questions = $form->getActiveQuestions();

        $section_id = 0;

        // Group questions by section
        $conditionals = [];
        $blockers = [];
        $q_number = 0;

        foreach ($questions as $key => $question) {
            $question->answer_change_count = -1;

            if ($question->question_type === 'variations') {
                $variations = json_decode((string) $question->variations);

                foreach ($variations as $x => $variation) {
                    $variations[$x] = [
                        'label' => $variation,
                        'id' => $variation,
                    ];
                }
                $question->variations = $variations;
            } elseif ($question->question_type === 'section') {
                $section_id = $question->id;
            } else {
                $question->section_id = $section_id;
            }

            if (! empty($question->show_if_question) || $question->show_if_question == '0') {
                $question->show_if_question = (int) $question->show_if_question;
            }

            if (! empty($question->sort) || $question->sort == '0') {
                $question->sort = (int) $question->sort;
            }

            if (! empty($question->form_id) || $question->form_id == '0') {
                $question->form_id = (int) $question->form_id;
            }

            if (! empty($question->old_id) || $question->old_id == '0') {
                $question->old_id = (int) $question->old_id;
            }

            if (! empty($question->is_multiple) || $question->is_multiple == '0') {
                $question->is_multiple = (int) $question->is_multiple;
            }

            if (! empty($question->is_required) || $question->is_required == '0') {
                $question->is_required = (int) $question->is_required;
            }

            if ($question->show_if_question) {
                $conditionals[$question->id] = [
                    'question' => $question->show_if_question,
                    'answer' => $question->show_if_answer,
                ];
            }

            if (! empty($question->cant_proceed_if)) {
                $blockers[$question->id] = (array) json_decode((string) $question->cant_proceed_if);
                $question->cant_proceed_if = (array) json_decode((string) $question->cant_proceed_if);
            }

            if (! empty($this->prev_assessment)) {
                $question->answer_change_count = 0;

                $answer = '';
                if (! $question->answer_expires_after_days) {
                    $answer = $this->prev_assessment
                        ->answers()
                        ->where('question_id', $question->id)
                        ->value('answer');
                }

                if ($question->question_type === 'notify_gp') {
                    $doctor_surgery = json_decode((string) $answer);
                    if (! empty($doctor_surgery) && ! empty($doctor_surgery->notify)) {
                        $questions[$key]->answer = $doctor_surgery->notify;
                    }
                } elseif ($question->is_multiple) {
                    $questions[$key]->answer = json_decode((string) $answer, true);
                } elseif ($question->question_type == Question::TYPE_BP_READINGS) {
                    $questions[$key]->answer = $form->is_completed
                        ? ''
                        : json_decode((string) $answer, true);
                } elseif ($question->question_type === 'image') {
                    if (! empty($answer)) {
                        $mimetype = Storage::mimeType(Assessment::UPLOAD_PATH.'/'.$answer);
                        $img =
                            'data:'
                            .$mimetype
                            .';base64,'
                            .base64_encode((string) Storage::get(Assessment::UPLOAD_PATH.'/'.$answer));

                        $questions[$key]->answer = $answer;
                        $questions[$key]->answer_file = $img;
                        $questions[$key]->file_already_set = $answer;
                    } else {
                        $questions[$key]->answer = '';
                        $questions[$key]->answer_file = '';
                        $questions[$key]->file_already_set = false;
                    }
                } else {
                    $questions[$key]->answer = $answer;
                    $questions[$key]->previously_set_answer = $answer;
                }
            }
        }

        //Convert the questions into an array
        $questions_array = $questions->toArray();

        //Break the questions into sections
        $current_questions = ['id' => false, 'number' => false, 'title' => 'generic', 'questions' => []];
        $question_sections = [];
        $question_number = 1;

        //Build required templates that are being used
        $templates = [];

        foreach ($questions_array as $question) {
            //Clean out the stuff that I don't need
            unset($question['created_at']);
            unset($question['updated_at']);
            unset($question['deleted_at']);
            unset($question['is_active']);
            unset($question['okay_if']);
            unset($question['alert_if']);

            //Set default options for vue
            $question['can_proceed'] = true;

            if (empty($question['answer'])) {
                $question['answer'] = '';
            }

            if (empty($question['answers'])) {
                $question['answers'] = []; //Multiple answers
            }

            $question['class'] = [];

            //Set alert names to match standard alert css classes
            if ($question['question_type'] == 'alert') {
                $question['question_type'] = 'error';
            } elseif ($question['question_type'] == 'information') {
                $question['question_type'] = 'alert';
            } elseif ($question['question_type'] == 'information_green') {
                $question['question_type'] = 'success';
            } elseif ($question['question_type'] == 'information_blue') {
                $question['question_type'] = 'info';
            }

            //Change confirmation type name
            if ($question['question_type'] == 'yes') {
                $question['question_type'] = 'confirmation';
            }

            //Add empty file value
            if ($question['question_type'] == 'image') {
                $question['file_error'] = '';

                if (empty($question['answer_file'])) {
                    $question['answer_file'] = '';
                }
            }

            //Mark anything that isn't an actual question
            $non_questions = [
                'html',
                'error',
                'alert',
                'success',
                'info',
                'section',
            ];

            if (! in_array($question['question_type'], $non_questions)) {
                $question['is_a_question'] = true;
            } else {
                $question['is_a_question'] = false;
            }

            //Requires confirmation
            if (! empty($question['cant_proceed_if'])) {
                //$question['block_if'] = trim($question['block_if'], '"');
                $question['requires_confirmation'] = true;
                $question['show_confirmation'] = false;
                $question['answer_confirmed'] = false;
                $question['answer_changed_after_confirmation'] = 0;
            }

            //Used to track changes on text based fields
            if ($question['is_a_question']) {
                if (empty($question['previously_set_answer'])) {
                    $question['previously_set_answer'] = '';
                }

                $question['blocked_by_confirmation'] = false;
            }

            //Set question templates
            $alerts = ['error', 'alert', 'success', 'info'];

            if (in_array($question['question_type'], $alerts)) {
                $template_file = 'alert_message.twig';
            } else {
                $template_file = $question['question_type'].'.twig';
            }

            $question['question_template'] = $template_file;

            //Store all the templates being used so we only need to output the markup of templates that get used
            if (! in_array($template_file, $templates)) {
                $templates[] = $template_file;
            }

            $question['cant_proceed_if'] = str_replace('"', '', $question['cant_proceed_if']);

            //Visibility
            $question['visible'] = true;
            $question['number'] = $q_number;

            $question['conditional'] = false;

            if (! empty($question['show_if_answer'])) {
                $question['visible'] = false;
                $question['conditional'] = true;
                $question['number'] = 0;
            } else {
                $q_number++;
            }

            //Order
            $question['question_number'] = $question_number;
            $question_number++;

            //Health profile values
            if (
                $question['question_type'] === 'allergies'
                && ! empty($health_profile['allergies'])
                && empty($question['answer'])
            ) {
                $question['answer'] = $health_profile['allergies'];
            } elseif (
                $question['question_type'] === 'conditions'
                && ! empty($health_profile['conditions'])
                && empty($question['answer'])
            ) {
                $question['answer'] = $health_profile['conditions'];
            } elseif (
                $question['question_type'] === 'medications'
                && ! empty($health_profile['medications'])
                && empty($question['answer'])
            ) {
                $question['answer'] = $health_profile['medications'];
            } elseif ($question['question_type'] === 'notify_gp' && ! empty($this->member->doctor_surgery)) {
                $question['answer'] = $doctor_surgery->id ?? null;
            }

            //BMI & Ethnicity
            if ($question['question_type'] == 'bmi') {
                $question['is_bmi_value'] = true;
                $question['bmi_field_values'] = [
                    'height_cm' => 0,
                    'weight_kg' => 0,
                    'height_feet' => 0,
                    'height_inches' => 0,
                    'weight_stone' => 0,
                    'weight_pounds' => 0,
                    'type' => 'Metric', // 'Metric' || 'Imperial',
                    'ethnicity' => '',
                    'category' => '',
                ];

                $question['answer'] = '';
                $question['bmi_ethnicities'] = BmiEthnicity::getEthnicityRecords()->toArray();
            } else {
                $question['is_bmi_value'] = false;
            }

            //Weight
            if ($question['question_type'] == 'weight') {
                $question['weight_field_values'] = [
                    'weight_kg' => 0,
                    'weight_stone' => 0,
                    'weight_pounds' => 0,
                    'type' => 'Metric', // 'Metric' || 'Imperial'
                ];
            }

            //Add error tracking
            $question['has_error'] = false;
            $question['error_message'] = '';

            //Build sections and add questions
            if ($question['question_type'] == 'section') {
                if (! empty($current_questions['questions'])) {
                    $question_sections[] = $current_questions;
                }

                $current_questions = [
                    'id' => $question['id'],
                    'order' => $section_number,
                    'title' => trim(strip_tags((string) $question['question_text'])),
                    'product_recommendations' => false,
                    'content' => ! empty($question['question_text_html']) ? $question['question_text_html'] : false,
                    'can_proceed' => false,
                    'questions' => [],
                    'section_number' => $section_number,
                    'visible' => $section_number == 1,
                    'product_selection' => false,
                    'product_confirmation' => false,
                    'loading' => false,
                ];

                $section_number++;
            } else {
                if (! empty($question['question_text'])) {
                    $pattern = "/<p[^>]*>(\&nbsp\;)?<\\/p[^>]*>/";
                    //$pattern = "/<[^\/>]*>([\s]?)*<\/[^>]*>/";  use this pattern to remove any empty tag

                    $question['question_text'] = preg_replace($pattern, '', (string) $question['question_text']);
                }

                $current_questions['questions'][] = $question;
            }
        }

        //Add remaining questions
        $question_sections[] = $current_questions;

        return $question_sections;
    }
}
