<?php

namespace App\Http\Controllers;

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


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(),
            'gp_practice' => $this->get_gp_practice(),
            '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;
    }


    /**
     * Get GP practice data in GpAddresses format
     */
    private function get_gp_practice()
    {
        // COMMENTED OUT - Legacy DoctorSurgery format (to be removed after client validation)
        // $doctor_surgery = !empty($this->member->doctor_surgery) ?
        //     json_decode($this->member->doctor_surgery) :
        //     (object) [
        //         'manual_doctor_surgery' => 0,
        //         'id' => 0,
        //         'practice_name' => '',
        //         'city' => '',
        //         'address_1' => '',
        //         'address_2' => '',
        //         'postcode' => '',
        //         'phone' => '',
        //     ];

        $doctor_surgery = !empty($this->member->doctor_surgery)
            ? json_decode($this->member->doctor_surgery)
            : null;

        // Map to GpAddresses format
        return (object) [
            'manual_gp_practice' => $doctor_surgery->manual_doctor_surgery ?? $doctor_surgery->manual_gp_practice ?? 0,
            'id' => $doctor_surgery->id ?? 0,
            'name' => $doctor_surgery->practice_name ?? $doctor_surgery->name ?? '',
            'org_id' => $doctor_surgery->ods_code ?? $doctor_surgery->org_id ?? '',
            'address_line_1' => $doctor_surgery->address_1 ?? $doctor_surgery->address_line_1 ?? '',
            'address_line_2' => $doctor_surgery->address_2 ?? $doctor_surgery->address_line_2 ?? '',
            'town' => $doctor_surgery->city ?? $doctor_surgery->town ?? '',
            'county' => $doctor_surgery->address_3 ?? $doctor_surgery->county ?? '',
            'postcode' => $doctor_surgery->postcode ?? '',
            'telephone_number' => $doctor_surgery->phone ?? $doctor_surgery->telephone_number ?? '',
        ];
    }


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

        return $health_profile;
    }


    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($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($question->cant_proceed_if);
                $question->cant_proceed_if = (array) json_decode($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($answer);
                    if (!empty($doctor_surgery) && !empty($doctor_surgery->notify)) {
                        $questions[$key]->answer = $doctor_surgery->notify;
                    }
                } elseif ($question->is_multiple) {
                    $questions[$key]->answer = json_decode($answer, true);
                } elseif ($question->question_type == Question::TYPE_BP_READINGS) {
                    $questions[$key]->answer = $form->is_completed ?
                        '' :
                        json_decode($answer, true);
                } elseif ($question->question_type === 'image') {

                    if (!empty($answer)) {
                        $mimetype = Storage::mimeType(Assessment::UPLOAD_PATH . '/' . $answer);
                        $img = 'data:'
                            . $mimetype
                            . ';base64,'
                            . base64_encode(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 $key => $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($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, '', $question['question_text']);

                }

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

            }

        }

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

        return $question_sections;
    }
}
