<?php

namespace App\Http\Controllers;

use App\Facades\UserSurvey;
use App\Http\Requests\QuestionAnswerRequest;
use App\Models\Answer;
use App\Models\Question;
use Illuminate\Http\Request;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Auth;

class SurveyController extends Controller
{
    public function index()
    {
        if (UserSurvey::isOngoing() && !UserSurvey::isCompleted()) {
            return UserSurvey::redirectToNextQuestion();
        }

        UserSurvey::start();

        return UserSurvey::redirectToNextQuestion();
    }

    public function show(Request $request ,$questionId)
    {
        /** @var \App\Models\Question $question */
        $question = UserSurvey::getQuestion($questionId);
        
        if (!$question) {
            abort(404);
        }

        if (!UserSurvey::questionCanBeAnswered($question)) {
            return UserSurvey::redirectToNextQuestion()->with(
                'error', 'Preskanje pitanja nije moguće.'
            );
        }

        $viewData = [
            'question' => $question,
            'answers'  => $this->prepareAnswers($question),
            'questionOrder' => UserSurvey::questionOrder($question),
            'questionCount' => UserSurvey::totalQuestions(),
            'nextQuestion' => UserSurvey::getQuestionAfter($question),
            'previousQuestion' => UserSurvey::getQuestionBefore($question),
            'isFirst' => UserSurvey::questionIsFirst($question),
            'isLast' => UserSurvey::questionIsLast($question),
        ];
       
        if ($question->isTeacher() || $question->isSubject() || $question->isSemesters()) {
            $viewData['subjects'] = Auth::user()
                                        ->department
                                        ->subjects()
                                        ->where('semester', $request->user()->semester)
                                        ->with('teacher', 'assistant')
                                        ->get();
        }

        return view('survey.show', $viewData);
    }

    public function store(QuestionAnswerRequest $request, $questionId)
    {
        $question = UserSurvey::getQuestion($questionId);

        if (!UserSurvey::questionCanBeAnswered($question)) {
            return UserSurvey::redirectToNextQuestion()->with(
                'error', 'Прескакање питања није могуће.'
            );
        }

        UserSurvey::addAnswerToQuestion($question, $this->processAnswers($question, $request->validated()));

        if (UserSurvey::questionIsLast($question) && UserSurvey::canBeCompleted()) {
            return redirect()->route('survey.complete')->with(
                'success', 'Одговори су сачувани.'
            );
        }

        return redirect()->route('survey.show', UserSurvey::getQuestionAfter($question)->id)
            ->with('success', 'Одговори су сачувани.');
    }

    public function complete()
    {
        UserSurvey::complete();
        Auth::logout();
        //Auth::delete();

        return view('survey.complete');
    }

    protected function processAnswers(Question $question, array $questionAnswers)
    {
        $processedAnswers = [];
        //var_dump($questionAnswers);
        //throw Exception("processAnswers",5,5);
        foreach ($questionAnswers as $answerName => $questionAnswer) {
            $processedAnswer = [
                'question_id' => $question->id,
                'mark' => $questionAnswer,
                'teacher_id' => null,
                'subject_id' => null,
                'textanswer' => null,
            ];

            if (!$question->isOther()) {
                $processedAnswer['subject_id'] = $this->parseSubjectIdFromAnswerName($answerName);

                if ($question->isTeacher()) {
                    $processedAnswer['teacher_id'] =
                        $this->parseTeacherIdFromAnswerName($answerName) ??
                        $this->parseAssistantIdFromAnswerName($answerName);
                }
            }

            $processedAnswers[] = $processedAnswer;
        }

        return $processedAnswers;
    }

    /**
     * @param string $answerName
     * @return string|null
     */
    protected function parseSubjectIdFromAnswerName(string $answerName)
    {
        $exploded = explode('-', $answerName);

        foreach ($exploded as $key => $piece) {
            if ($piece === 'subject' || $piece === 'semesters') {
                return $exploded[$key + 1];
            }
        }
    }

    /**
     * @param string $answerName
     * @return string|null
     */
    protected function parseTeacherIdFromAnswerName(string $answerName)
    {
        $exploded = explode('-', $answerName);

        foreach ($exploded as $key => $piece) {
            if ($piece === 'teacher') {
                return $exploded[$key + 1];
            }
        }
    }

    /**
     * @param string $answerName
     * @return string|null
     */
    protected function parseAssistantIdFromAnswerName(string $answerName)
    {
        $exploded = explode('-', $answerName);

        foreach ($exploded as $key => $piece) {
            if ($piece === 'assistant') {
                return $exploded[$key + 1];
            }
        }
    }

    /**
     * @param \App\Models\Question $question
     * @return \Illuminate\Support\Collection
     */
    protected function prepareAnswers(Question $question)
    {
        /** @var \Illuminate\Support\Collection $rawAnswers */
        $rawAnswers = UserSurvey::getAnswerToQuestion($question);

        if ($rawAnswers->isEmpty()) {
            return collect();
        }

        if ($question->isTeacher()) {
            return $rawAnswers->groupBy('subject_id')->map(function (Collection $subjectAnswers) {
                return $subjectAnswers->mapWithKeys(function (array $answer) {
                    return [$answer['teacher_id'] => $answer['mark']];
                })->toArray();
            });
        }

        if ($question->isSubject() || $question->isSemesters()) {
            return $rawAnswers->mapWithKeys(function (array $answer) {
                return [$answer['subject_id'] => $answer['mark']];
            });
        }
       
        return collect($rawAnswers->first());
    }
}
