<?php

use Illuminate\Database\Eloquent\Collection;

class ActivitiesController extends \BaseController
{

    /**
     * Save a new activity
     *
     * @param int $id The id of the parent course
     * @return Response Redirect to the parent course's page
     */
    public function create($id)
    {
        /** Validation rules */

        $validator = Validator::make(
            array(
                'name' => Input::get('name'),
                'description' => Input::get('description')
            ),
            array(
                'name' => 'required|unique:activities,course_id,' . $id,
                'description' => 'required|min:10'
            )
        );


        /** If validation fails */
        if ($validator->fails()) {
            /** Prepare error message */
            $message = 'Error(s) creating a new Activity<ul>';

            foreach ($validator->messages()->all('<li>:message</li>') as $validationError) {
                $message .= $validationError;
            }

            $message .= '</ul>';

            /** Send error message and old data */
            Session::flash('status', 'danger');
            Session::flash('message', $message);
            return Redirect::back()->withInput();
        } else {
            /** Instantiate new activity */
            $activity = new Activity;
            $activity->name = Input::get('name');
            $activity->description = Input::get('description');
            $activity->course_id = $id;

            // Gabriel añadió aquí
            $activity->draft = 1;
            $activity->diagnostic = 0;
            //
            $activity->date = date('Y-m-d');

            /** If activity is saved, send success message */
            if ($activity->save()) {
                Session::flash('status', 'success');
                Session::flash('message', 'Activity created.');
                return Redirect::action('ActivitiesController@show', array($activity->id));
            }

            /** If saving fails, send error message and old data */
            else {
                Session::flash('status', 'warning');
                Session::flash('message', 'Error adding Activity. Please try again later.');
                return Redirect::back()->withInput();
            }
        }
    }

    public function newCreate($course_id = null)
    {
        $title = 'Create Activity';
        $activity_types = [];
        $instruments = Rubric::all();
        $courses = Course::where('user_id', Auth::user()->id)->get();
        $outcomes = Outcome::with('objectives')->get();
        //        var_dump($outcomes[0]->objectives);
        $objectives_by_outcome = Collection::make([]);
        $outcomes->each(function ($outcome) use (&$objectives_by_outcome) {
            //            var_dump($outcome->objectives);
            $objectives_by_outcome->put($outcome->id, $outcome->objectives);
            //            var_dump($objectives);
        });
        $criteria_by_objective = Collection::make([]);
        $objectives_by_outcome->each(function ($objectives) use (&$criteria_by_objective) {
            $objectives->each(function ($objective) use (&$criteria_by_objective) {
                $criteria_by_objective->put($objective->id, $objective->criteria);
            });
        });
        $transforming_actions = [];
        $course = Course::find($course_id);
        //        var_dump($criteria_by_objective);
        //        return $objectives->toJson();
        return View::make(
            'local.managers.admins.new-activity-create',
            compact(
                'title',
                'course',
                'activity_types',
                'instruments',
                'courses',
                'outcomes',
                'objectives_by_outcome',
                'criteria_by_objective',
                'transforming_actions'
            )
        );
    }

    /**
     *
     */
    public function show($id)
    {
        $activity = Activity::find($id);


        // If activity does not exist, display 404
        if (!$activity)
            App::abort('404');

        // Get activity's course
        $course = Course::where('id', '=', $activity->course_id)->firstOrFail();

        // If activity does not belong to the requesting user, display 403
        if ($course->user_id != Auth::id() and Auth::user()->role == 4)
            App::abort('403', 'Access Forbidden');

        // Get active semesters
        $active_semesters = array();
        $active_semesters_collection = Semester::select('id')->where('is_visible', 1)->where('start', '<=', date('Y-m-d H:i:s'))->where('end', '>=', date('Y-m-d H:i:s'))->get();
        foreach ($active_semesters_collection as $active_semester) {
            $active_semesters[] = $active_semester->id;
        }

        Log::info($active_semesters);
        // Added the function htmlspecialchars to activity name string because it was corrupting Jquery code while using quotes on page rendering. - Carlos R Caraballo 1/18/2019
        $title = $course->code . $course->number . '-' . $course->section . ': ' . htmlspecialchars($activity->name, ENT_QUOTES) . ' <span class="small attention">(' . $course->semester->code . ')</span>';

        $semesters = DB::table('semesters')->where('id', $course->semester_id)->orderBy('start', 'ASC')->first();
        /*$outcomes = Outcome::select(array('id', 'name', 'expected_outcome'))
            ->whereNull('deleted_at')
            ->whereRaw("(deactivation_date IS NULL or deactivation_date >= '{$semesters->start}')")
            ->orderBy('name', 'ASC')->get();*/

        //         $outcomes = Outcome::orderBy('name', 'asc')->get();
        $level = DB::table('courses')
            ->join('programs', 'programs.id', '=', 'courses.program_id')
            ->where('courses.id', $activity->course_id)
            //             ->where('courses.number', $number)
            //             ->where('courses.semester_id', $semester->id)
            ->select('programs.is_graduate')
            ->first();
        $outcomes = Outcome::active_by_semesters(array($course->semester), $level->is_graduate);
        //$outcomes = $activity->getOutcomeReport();

        $assessment = DB::table('assessments')
            ->join('activity_criterion', 'assessments.activity_criterion_id', '=', 'activity_criterion.id')
            ->join('activities', 'activities.id', '=', 'activity_criterion.activity_id')
            ->where('activity_id', $activity->id)
            ->get();
        //if ($assessment) {
        //    $outcomes_achieved = $activity->o_ach_array;
        //    $outcomes_attempted = $activity->o_att_array;
        //} else {
        //   $outcomes_achieved = [];
        //   $outcomes_attempted = [];
        //}

        //Log::info($outcomes_achieved);
        //Log::info($outcomes_achieved);

        $outcomes_activity = $activity->getOutcomeReport();



        $activity_criterion = DB::table('criteria')
            ->join('activity_criterion', 'criteria.id', '=', 'activity_criterion.criterion_id')
            ->where('activity_id', $activity->id)
            ->select('activity_criterion.id', 'activity_criterion.criterion_id')
            ->addSelect('criteria.name')
            ->get();


        $transformative_actions = DB::table('transformative_activity_criterion')
            ->join('activity_criterion', 'transformative_activity_criterion.activity_criterion_id', '=', 'activity_criterion.id')
            ->join('transformative_actions', 'transformative_activity_criterion.trans_action_id', '=', 'transformative_actions.id')
            ->where('activity_criterion.activity_id', $id)
            ->get();
        return View::make('local.professors.activity', compact('activity', 'outcomes_activity', 'transformative_actions', 'activity_criterion', 'title', 'outcomes', 'outcomes_achieved', 'outcomes_attempted', 'course', 'student_count', 'active_semesters'));
    }


    public function assess($id)
    {
        $activity = Activity::find($id);

        // If activity does not exist, display 404
        if (!$activity)
            App::abort('404');

        // Get activity's course
        $course = Course::where('id', '=', $activity->course_id)->firstOrFail();

        // If activity does not belong to the requesting user, display 403
        if ($course->user_id != Auth::id())
            App::abort('403', 'Access Forbidden');

        $title = 'Assessment Sheet';
        $students = $course->students;

        // Get rubric contents
        $rubric = Rubric::find($activity->rubric[0]->id);
        $rubric->titles = DB::table('titles')
            ->join('rubric_title', 'rubric_title.title_id', '=', 'titles.id')
            ->where('rubric_title.rubric_id', '=', $rubric->id)
            ->lists('text');

        $rubric_criterion = DB::table('criteria')
            ->join("rubric_criterion", "rubric_criterion.criterion_id", "=", "criteria.id")
            ->join("activity_criterion", "criteria.id", '=', 'activity_criterion.criterion_id')
            ->where("activity_criterion.activity_id", '=', $activity->id)
            ->where('rubric_criterion.rubric_id', '=', $rubric->id)
            ->select('criteria.name', 'criteria.id as criterion_id', 'criteria.subcriteria')
            ->addSelect('activity_criterion.activity_id', 'activity_criterion.weight', 'activity_criterion.id as activity_criterion_id')
            ->addSelect('rubric_criterion.rubric_id', 'rubric_criterion.id as rubric_criterion_id')
            ->get();
        $total_weights = 0;
        foreach ($rubric_criterion as $index => $singleCR) {
            $singleCR->scales = json_encode(DB::table('scales')
                ->join('criterion_scale', 'criterion_scale.scale_id', '=', 'scales.id')
                ->where('criterion_scale.criterion_id', '=', $singleCR->criterion_id)
                ->orderBy('position')
                ->lists('description'));
            $total_weights += $singleCR->weight;
        }
        $rubric_criterion_ids = DB::table('rubric_criterion')->where('rubric_id', '=', $rubric->id)->lists('id');






        // Get results
        $activity_criterion_ids = DB::table('activity_criterion')->where("activity_id", '=', $activity->id)->lists('id');

        $assessments = DB::table('assessments')
            ->join('students', 'assessments.student_id', '=', 'students.id')
            ->whereIn('activity_criterion_id', $activity_criterion_ids)
            ->orderBy('assessments.id', 'asc')->get();

        // Decode the scores (blade workaround)
        $scores_array = array();

        foreach ($assessments as $index => $assessment) {
            $scores_array[$assessment->student_id][$assessment->activity_criterion_id] = $assessment->score;
            $scores_array[$assessment->student_id]['comments'] = DB::table('activity_student')->where('student_id', '=', $assessment->student_id)
                ->where("activity_id", '=', $activity->id)
                ->select('comments')->first()->comments;
        }


        return View::make('local.professors.assessment', compact('total_weights', 'activity', 'title', 'students', 'course', 'rubric_criterion', 'assessments', 'scores_array', 'rubric'));
    }

    public function saveAssessment()
    {
        try {
            $exception = DB::transaction(function () {
                DB::transaction(function () {
                    // Student assessment data

                    $activity_id = Input::get('activity_id');
                    $student_data = json_decode(Input::get('student_info'));
                    $weights = json_decode(Input::get('weights'));
                    Log::info(json_encode($weights));
                    Log::info(json_encode($student_data));

                    foreach ($student_data as $index => $student_dict) {
                        $student_id = $student_dict->studentId;
                        foreach ($student_dict->activity_crit_id as $act_crit_id => $score) {
                            if (DB::table('assessments')->where('student_id', '=', $student_id)
                                ->where('activity_criterion_id', '=', $act_crit_id)
                                ->first()
                            ) {
                                DB::table('assessments')->where('student_id', '=', $student_id)
                                    ->where('activity_criterion_id', '=', $act_crit_id)
                                    ->update(array('score' => $score));
                            } else {
                                DB::insert("insert into assessments (`activity_criterion_id`, `student_id`, `score`) values ({$act_crit_id}, {$student_id}, {$score})");
                            }
                        }
                        if (DB::table('activity_student')
                            ->where('student_id', '=', $student_id)->where('activity_id', '=', $activity_id)
                            ->first()
                        ) {
                            DB::table('activity_student')
                                ->where('student_id', '=', $student_id)->where('activity_id', '=', $activity_id)
                                ->update(array('comments' => $student_dict->comments));
                        } else {
                            DB::insert("insert into activity_student (`activity_id`, `student_id`, `comments`) values ({$activity_id}, {$student_id}, '{$student_dict->comments}')");
                        }
                    }
                    $activity_draft = Input::get('draft');
                    $activity_diagnostic = Input::get('diagnostic');
                    Log::info(json_encode($weights));
                    foreach ($weights as $act_crit => $weigh) {
                        DB::update("update activity_criterion set weight = {$weigh} where id = {$act_crit}");
                    }
                    DB::update("update activities set draft = {$activity_draft}, diagnostic = {$activity_diagnostic} where id = {$activity_id}");
                    // Outcome count
                    Session::flash('status', 'success');
                    Session::flash('message', 'Assessment Saved. To add Formative actions click "Formative Actions".');
                    return action('ActivitiesController@show', array(Input::get('activity_id')));

                    $outcomeCount = Outcome::all()->count();


                    // Activity
                    $activity = Activity::find(Input::get('activity_id'));


                    // Create or update student scores
                    if ($activity->outcomes_attempted == NULL) {
                        // For each student, save her/his assessment in the db
                        foreach ($student_data as $single_student_data) {
                            // Find student by id
                            $student = Student::find($single_student_data->student_id);

                            $comments = trim($single_student_data->comments);
                            if ($comments == '') {
                                $comments = NULL;
                            }

                            // Add the assessment to the pivot table

                            $student->assessed_activities()->attach($activity->id, array(
                                'scores' => json_encode($single_student_data->scores),
                                'comments' => $single_student_data->comments
                            ));
                        }
                    } else {
                        // For each student, save her/his assessment in the db
                        foreach ($student_data as $single_student_data) {
                            // Find student by id
                            $student = Student::find($single_student_data->student_id);

                            $comments = trim($single_student_data->comments);
                            if ($comments == '') {
                                $comments = NULL;
                            }

                            // Update the assessment in the pivot table
                            $student->assessed_activities()->updateExistingPivot($activity->id, array(
                                'scores' => json_encode($single_student_data->scores),
                                'percentage' => $single_student_data->percentage,
                                'comments' => $single_student_data->comments
                            ));
                        }
                    }


                    // Prepare arrays for criteria achievement for this activity
                    $criteria_achievement = json_decode(Input::get('criteria_achievement'));
                    $outcomes_attempted = array_fill(1, $outcomeCount, 0);
                    $outcomes_achieved = array_fill(1, $outcomeCount, 0);

                    // Fetch parent course's criteria achievement by outcome, if it exists
                    $course = $activity->course;
                    $course_outcomes_attempted = NULL;
                    $course_outcomes_achieved = NULL;

                    if ($course->outcomes_attempted == NULL) {
                        $course_outcomes_attempted = array_fill(1, $outcomeCount, 0);
                        $course_outcomes_achieved = array_fill(1, $outcomeCount, 0);
                    } else {
                        // the second argument is necessary to convert it into an array
                        $course_outcomes_attempted = json_decode($course->outcomes_attempted, true);
                        $course_outcomes_achieved = json_decode($course->outcomes_achieved, true);
                    }


                    foreach ($criteria_achievement as $criterion_id => $criterion_achieved) {
                        // Find corresponding learning outcome
                        $criterion = Criterion::withTrashed()->find($criterion_id);
                        $outcome = Outcome::find($criterion->outcome_id);

                        // If criterion is achieved (1), add 1 to all arrays
                        if ($criterion_achieved === 1) {
                            $outcomes_attempted[$outcome->id] += 1;
                            $outcomes_achieved[$outcome->id] += 1;
                            $course_outcomes_attempted[$outcome->id] += 1;
                            $course_outcomes_achieved[$outcome->id] += 1;
                        }
                        // Else if it's 0, only add to the attempted outcomes arrays
                        elseif ($criterion_achieved === 0) {
                            $outcomes_attempted[$outcome->id] += 1;
                            $course_outcomes_attempted[$outcome->id] += 1;
                        }
                    }

                    // If all values are 0, throw exception
                    if (count(array_unique($outcomes_attempted)) == 1 && $outcomes_attempted[1] == 0)
                        throw new Exception("Error Processing Request", 1);



                    // Set activity fields
                    $activity->criteria_achieved = Input::get('criteria_achievement');
                    $activity->criteria_achieved_percentage = Input::get('criteria_achieved_percentage');
                    $activity->outcomes_attempted = json_encode($outcomes_attempted);
                    $activity->outcomes_achieved = json_encode($outcomes_achieved);


                    // Publish results if not a draft. That is, update the activity's course.
                    if (Input::get('draft') == false) {
                        // Update course
                        $course->outcomes_achieved = json_encode($course_outcomes_achieved);
                        $course->outcomes_attempted = json_encode($course_outcomes_attempted);
                        $course->save();

                        $activity->draft = false;
                    } else {
                        // Set draft to true
                        $activity->draft = true;
                    }

                    // Save activity
                    $activity->save();


                    // Recalculate course outcomes
                    $activities = DB::table('activities')
                        ->where('course_id', $activity->course->id)
                        ->where('draft', 0)
                        ->get();


                    // Check if any assessed activities remain
                    $remainingAssessed = false;
                    foreach ($activities as $activity1) {
                        if ($activity1->outcomes_attempted != NULL) {
                            $remainingAssessed = true;
                            break;
                        }
                    }

                    //If there are still evaluated activities in the course, recalculate course outcomes
                    if (count($activities) && $remainingAssessed) {
                        $outcomeCount = Outcome::all()->count();

                        // Variables to hold recalculated outcomes for the course
                        $course_outcomes_attempted = array_fill(1, $outcomeCount, 0);
                        $course_outcomes_achieved = array_fill(1, $outcomeCount, 0);

                        // For each activity
                        foreach ($activities as $activity2) {
                            // If activity has been assessed
                            if ($activity2->outcomes_attempted != NULL) {
                                // Get the achieved criteria
                                $criteria_achievement = json_decode($activity2->criteria_achieved, true);
                                foreach ($criteria_achievement as $criterion_id => $criterion_achieved) {
                                    // Find corresponding learning outcome;
                                    $criterion = Criterion::withTrashed()->find($criterion_id);
                                    $outcome = Outcome::find($criterion->outcome_id);

                                    // If criterion is achieved (1), add 1 to both arrays
                                    if ($criterion_achieved === 1) {
                                        $course_outcomes_attempted[$outcome->id] += 1;
                                        $course_outcomes_achieved[$outcome->id] += 1;
                                    }
                                    // Else, only add to the attempted outcomes arrays
                                    elseif ($criterion_achieved === 0) {
                                        $course_outcomes_attempted[$outcome->id] += 1;
                                    }
                                }
                            }
                        }

                        // Update course
                        DB::table('courses')
                            ->where('id', $course->id)
                            ->update(array(
                                'outcomes_attempted' => json_encode($course_outcomes_attempted),
                                'outcomes_achieved' => json_encode($course_outcomes_achieved),
                                'updated_at' => date('Y-m-d H:i:s')
                            ));
                    }
                    // Otherwise, set them all to NULL
                    else {
                        DB::table('courses')
                            ->where('id', $course->id)
                            ->update(array(
                                'outcomes_attempted' => NULL,
                                'outcomes_achieved' => NULL,
                                'updated_at' => date('Y-m-d H:i:s')
                            ));
                    }
                });
            });

            if (is_null($exception)) {
                Session::flash('status', 'success');
                Session::flash('message', 'Assessment Saved. To add  Formative actions click "Formative Actions".');
                return action('ActivitiesController@show', array(Input::get('activity_id')));
            }
        } catch (Exception $e) {
            Log::info('e:' . $e);
            echo $e->getMessage();
            Session::flash('status', 'danger');
            Session::flash('message', 'Error saving assessment. Try again later.');

            return action('ActivitiesController@show', array(Input::get('activity_id')));
        }
    }

    public function deleteAssessment()
    {

        try {
            $exception = DB::transaction(function () {
                $activity = DB::table('activities')->where('id', Input::get('id'))->first();

                $course = DB::table('courses')->where('id', $activity->course_id)->first();


                // Reset results in activity
                DB::table('activities')
                    ->where('id', Input::get('id'))
                    ->update(array(
                        'draft' => 1,
                        'assessment_comments' => NULL,



                        'updated_at' => date('Y-m-d H:i:s')
                    ));

                // Delete students score

                DB::table('assessments')
                    ->join('activity_criterion', 'assessments.activity_criterion_id', '=', 'activity_criterion.id')
                    ->where('activity_id', $activity->id)->delete();

                // Recalculate course outcomes
                /*$activities = DB::table('activities')
                    ->where('course_id', $course->id)
                    ->where('draft', 0)
                    ->get();


                // Check if any assessed activties remain
                $remainingAssessed = false;
                foreach ($activities as $activity) {
                    if ($activity->outcomes_attempted != NULL) {
                        $remainingAssessed = true;
                        break;
                    }
                }

                //If there are still evaluated activities in the course, recalculate course outcomes
                if (count($activities) && $remainingAssessed) {
                    $outcomeCount = Outcome::all()->count();

                    // Variables to hold recalculated outcomes for the course
                    $course_outcomes_attempted = array_fill(1, $outcomeCount, 0);
                    $course_outcomes_achieved = array_fill(1, $outcomeCount, 0);

                    // For each activity
                    foreach ($activities as $activity) {
                        // If activity has been assessed
                        if ($activity->outcomes_attempted != NULL) {
                            // Get the achieved criteria
                            $criteria_achievement = json_decode($activity->criteria_achieved, true);
                            foreach ($criteria_achievement as $criterion_id => $criterion_achieved) {
                                // Find corresponding learning outcome;
                                $criterion = Criterion::withTrashed()->find($criterion_id);
                                $outcome = Outcome::find($criterion->outcome_id);

                                // If criterion is achieved (1), add 1 to both arrays
                                if ($criterion_achieved === 1) {
                                    $course_outcomes_attempted[$outcome->id] += 1;
                                    $course_outcomes_achieved[$outcome->id] += 1;
                                }
                                // Else, only add to the attempted outcomes arrays
                                elseif ($criterion_achieved === 0) {
                                    $course_outcomes_attempted[$outcome->id] += 1;
                                }
                            }
                        }
                    }

                    // Update course
                    DB::table('courses')
                        ->where('id', $course->id)
                        ->update(array(
                            'outcomes_attempted' => json_encode($course_outcomes_attempted),
                            'outcomes_achieved' => json_encode($course_outcomes_achieved),
                            'updated_at' => date('Y-m-d H:i:s')
                        ));
                }
                // Otherwise, set them all to NULL
                else {
                    DB::table('courses')
                        ->where('id', $course->id)
                        ->update(array(
                            'outcomes_attempted' => NULL,
                            'outcomes_achieved' => NULL,
                            'updated_at' => date('Y-m-d H:i:s')
                        ));
                }
            });*/
            });

            if (is_null($exception)) {
                Session::flash('status', 'success');
                Session::flash('message', 'Assessment deleted.');
                return Redirect::back();
            }
        } catch (Exception $e) {
            Session::flash('status', 'danger');
            Session::flash('message', 'Error saving  assessment. Try again later.');

            return Redirect::back();
        }
    }

    public function destroy($id)
    {
        $course = Activity::find($id)->course;

        if (Activity::destroy($id)) {
            // Recalculate course outcomes
            /*$activities = $course->activities;

            // Check if any assessed activties remain
            $remainingAssessed = false;
            foreach ($course->activities as $activity) {
                if ($activity->outcomes_attempted != NULL) {
                    $remainingAssessed = true;
                    break;
                }
            }

            //If there are still evaluated activities in the course, recalculate course outcomes
            if (!$course->activities->isEmpty() && $remainingAssessed) {
                $outcomeCount = Outcome::all()->count();

                // Variables to hold recalculated outcomes for the course
                $course_outcomes_attempted = array_fill(1, $outcomeCount, 0);
                $course_outcomes_achieved = array_fill(1, $outcomeCount, 0);

                // For each activity
                foreach ($activities as $activity) {
                    // If activity has been assessed
                    if ($activity->outcomes_attempted != NULL) {
                        // Get the achieved criteria
                        $criteria_achievement = json_decode($activity->criteria_achieved, true);
                        foreach ($criteria_achievement as $criterion_id => $criterion_achieved) {
                            // Find corresponding learning outcome;
                            $criterion = Criterion::withTrashed()->find($criterion_id);
                            $outcome = Outcome::find($criterion->outcome_id);

                            // If criterion is achieved (1), add 1 to both arrays
                            if ($criterion_achieved === 1) {
                                $course_outcomes_attempted[$outcome->id] += 1;
                                $course_outcomes_achieved[$outcome->id] += 1;
                            }
                            // Else, only add to the attempted outcomes arrays
                            elseif ($criterion_achieved === 0) {
                                $course_outcomes_attempted[$outcome->id] += 1;
                            }
                        }
                    }
                }

                // Update course
                $course->outcomes_achieved = json_encode($course_outcomes_achieved);
                $course->outcomes_attempted = json_encode($course_outcomes_attempted);
            } else {
                $course->outcomes_achieved = NULL;
                $course->outcomes_attempted = NULL;
            } */

            /*if ($course->save()) {
                Session::flash('status', 'success');
                Session::flash('message', 'Activity deleted.');
            } else {
                Session::flash('status', 'danger');
                Session::flash('message', 'Error deleting activity. Try again later.');
                return Redirect::back();
            }*/
            Session::flash('status', 'success');
            Session::flash('message', 'Activity deleted.');
            return Redirect::action('CoursesController@show', array($course->id));
        } else {
            Session::flash('status', 'danger');
            Session::flash('message', 'Error deleting activity. Try again later.');
            return Redirect::back();
        }
    }

    public function update($id)
    {
        try {
            $activity = Activity::find($id);

            if (Input::has('update_activity_information')) {
                /** Validation rules */
                $validator = Validator::make(
                    array(
                        'name' => Input::get('name'),
                        'description' => Input::get('description'),
                        'date' => Input::get('date'),
                    ),
                    array(
                        'name' => 'required|unique:activities,course_id,' . $id,
                        'description' => 'required|min:10',
                        'date' => 'required|dateFormat:Y-m-d'
                    ),
                    array(
                        'date.dateFormat' => 'The date does not match the correct format: yyyy-mm-dd.'
                    )
                );

                /** If validation fails */
                if ($validator->fails()) {
                    /** Prepare error message */
                    $message = 'Error(s) updating the Activity<ul>';

                    foreach ($validator->messages()->all('<li>:message</li>') as $validationError) {
                        $message .= $validationError;
                    }

                    $message .= '</ul>';

                    /** Send error message and old data */
                    Session::flash('status', 'warning');
                    Session::flash('message', $message);
                    return Redirect::back()->withInput();
                }

                /** Update activity info */
                $activity->name = Input::get('name');
                $activity->description = Input::get('description');
                $activity->date = Input::get('date');
            } /*elseif (Input::has('update_transforming_actions')) {
                if (trim(Input::get('transforming_actions')) != "")
                    $activity->transforming_actions = Input::get('transforming_actions');
                else
                    $activity->transforming_actions = NULL;
            }*/ elseif (Input::has('update_assessment_comments')) {
                if (trim(Input::get('assessment_comments')) != "")
                    $activity->assessment_comments = Input::get('assessment_comments');
                else
                    $activity->assessment_comments = NULL;
            } else {
                Session::flash('status', 'danger');
                Session::flash('message', 'Error updating Activity. Please try again later.');
                return Redirect::action('ActivitiesController@show', array($activity->id));
            }

            $activity->save();

            /** If activity is saved, send success message */
            Session::flash('status', 'success');
            Session::flash('message', 'Activity succesfully updated.');
            return Redirect::action('ActivitiesController@show', array($activity->id));
        } catch (Exception $e) {
            Session::flash('status', 'warning');
            Session::flash('message', 'Error updating Activity. Please try again later.');
            return Redirect::action('ActivitiesController@show', array($activity->id));
        }
    }

    //TODO the code in the next 2 functions is the same as the assess function except for the view returned. try to refactor this to avoid copying code.

    public function viewAssessment($id)
    {
        $activity = Activity::find($id);

        // If activity does not exist, display 404
        if (!$activity)
            App::abort('404');

        // Get activity's course
        $course = Course::where('id', '=', $activity->course_id)->firstOrFail();

        // If activity does not belong to the requesting user, display 403
        if ($course->user_id != Auth::id())
            App::abort('403', 'Access Forbidden');

        $students = $course->students;

        // Get rubric contents
        $rubric = Rubric::find($activity->rubric[0]->id);


        $rubric->titles = DB::table('titles')
            ->join('rubric_title', 'rubric_title.title_id', '=', 'titles.id')
            ->where('rubric_id', $rubric->id)
            ->orderBy("position", 'ASC')
            ->lists('text');
        //$rubric_contents = Rubric::select('contents')->where('id', '=', $activity->rubric_id)->get();
        //$rubric_contents = json_decode($rubric_contents['0']->contents);


        $rubric_criterion = DB::table('criteria')
            ->join("rubric_criterion", "rubric_criterion.criterion_id", "=", "criteria.id")
            ->join("activity_criterion", "criteria.id", '=', 'activity_criterion.criterion_id')
            ->where("activity_criterion.activity_id", '=', $activity->id)
            ->where('rubric_criterion.rubric_id', '=', $rubric->id)
            ->select('criteria.name', 'criteria.id as criterion_id', 'criteria.subcriteria')
            ->addSelect('activity_criterion.activity_id', 'activity_criterion.weight', 'activity_criterion.id as activity_criterion_id')
            ->addSelect('rubric_criterion.rubric_id', 'rubric_criterion.id as rubric_criterion_id')
            ->get();
        //Log::info("EN mi cuarto o o o");
        //Log::info($rubric_criterion);

        foreach ($rubric_criterion as $index => $crit) {
            $crit->scales = DB::table('scales')
                ->join('criterion_scale', 'scales.id', '=', 'criterion_scale.scale_id')
                ->where('criterion_id', $crit->criterion_id)
                ->get();
        }




        // Get results
        $activity_criterion_ids = DB::table('activity_criterion')->where("activity_id", '=', $activity->id)->lists('id');
        Log::info($activity_criterion_ids);
        $assessments = DB::table('assessments')
            ->join('students', 'assessments.student_id', '=', 'students.id')
            ->whereIn('activity_criterion_id', $activity_criterion_ids)
            ->orderBy('assessments.id', 'asc')->get();
        Log::info($assessments);
        // Decode the scores (blade workaround)
        $scores_array = array();

        foreach ($assessments as $index => $assessment) {
            $scores_array[$assessment->student_id][$assessment->activity_criterion_id] = $assessment->score;
            $scores_array[$assessment->student_id]['comments'] = DB::table('activity_student')->where('student_id', '=', $assessment->student_id)
                ->where("activity_id", '=', $activity->id)
                ->select('comments')->first()->comments;
        }
        $title = 'Assessment Sheet';

        return View::make('local.professors.view_assessment', compact('activity', 'title', 'students', 'course', 'rubric_criterion', 'assessments', 'scores_array', 'rubric'));
    }

    public function printAssessment($id)
    {
        $activity = Activity::find($id);

        // If activity does not exist, display 404
        if (!$activity)
            App::abort('404');

        // Get activity's course
        $course = Course::where('id', '=', $activity->course_id)->firstOrFail();

        // If activity does not belong to the requesting user, display 403
        if ($course->user_id != Auth::id())
            App::abort('403', 'Access Forbidden');

        $title = 'Assessment Sheet';
        $students = $course->students;

        // Get rubric contents
        $rubric = Rubric::find($activity->rubric[0]->id);
        $rubric_contents = DB::table('criteria')
            ->join("rubric_criterion", "rubric_criterion.criterion_id", "=", "criteria.id")
            ->join("activity_criterion", "criteria.id", '=', 'activity_criterion.criterion_id')
            ->where("activity_criterion.activity_id", '=', $activity->id)
            ->where('rubric_criterion.rubric_id', '=', $rubric->id)
            ->select('criteria.name', 'criteria.id as criterion_id', 'criteria.subcriteria')
            ->addSelect('activity_criterion.activity_id', 'activity_criterion.weight', 'activity_criterion.id as activity_criterion_id')
            ->addSelect('rubric_criterion.rubric_id', 'rubric_criterion.id as rubric_criterion_id')
            ->get();
        $rubric->titles = DB::table('titles')
            ->join('rubric_title', 'rubric_title.title_id', '=', 'titles.id')
            ->where('rubric_id', $rubric->id)
            ->orderBy("position", 'ASC')
            ->lists('text');


        foreach ($rubric_contents as $index => $crit) {
            $crit->scales = DB::table('scales')
                ->join('criterion_scale', 'scales.id', '=', 'criterion_scale.scale_id')
                ->where('criterion_id', $crit->criterion_id)
                ->get();
        }




        // Get results
        /*$assessments = DB::table('assessments')->where('activity_id', '=', $activity->id)->orderBy('id', 'asc')->get();

        // Decode the scores (blade workaround)
        $scores_array = array();
        foreach ($assessments as $index => $assessment) {
            $scores_array[$assessment->id] = json_decode($assessment->scores, true);
        }*/
        // Get results
        $activity_criterion_ids = DB::table('activity_criterion')->where("activity_id", '=', $activity->id)->lists('id');
        Log::info($activity_criterion_ids);
        $assessments = DB::table('assessments')
            ->join('students', 'assessments.student_id', '=', 'students.id')
            ->whereIn('activity_criterion_id', $activity_criterion_ids)
            ->orderBy('assessments.id', 'asc')->get();
        Log::info($assessments);
        // Decode the scores (blade workaround)
        $scores_array = array();

        foreach ($assessments as $index => $assessment) {

            $scores_array[$assessment->student_id][$assessment->activity_criterion_id] = $assessment->score;
            $scores_array[$assessment->student_id]['comments'] = DB::table('activity_student')->where('student_id', '=', $assessment->student_id)
                ->where("activity_id", '=', $activity->id)
                ->select('comments')->first()->comments;
        }


        return View::make('local.professors.print_assessment', compact('activity', 'title', 'students', 'course', 'rubric_contents', 'assessments', 'scores_array', 'rubric'));
    }

    public function compareActivities($activity_1, $activity_2)
    {
        $activity_1 = Activity::find($activity_1);
        $activity_2 = Activity::find($activity_2);


        // If activity does not exist, display 404
        if (!$activity_1 || !$activity_2)
            App::abort('404');

        // Get activity's course
        $course = Course::where('id', '=', $activity_1->course_id)->firstOrFail();

        // If activity does not belong to the requesting user, display 403
        if ($course->user_id != Auth::id() and Auth::user()->role == 4)
            App::abort('403', 'Access Forbidden');

        // Get active semesters
        $active_semesters = array();
        $active_semesters_collection = Semester::select('id')->where('is_visible', 1)->where('start', '<=', date('Y-m-d H:i:s'))->where('end', '>=', date('Y-m-d H:i:s'))->get();
        foreach ($active_semesters_collection as $active_semester) {
            $active_semesters[] = $active_semester->id;
        }

        $semesters = DB::table('semesters')->where('id', $course->semester_id)->orderBy('start', 'ASC')->first();

        Log::info($active_semesters);
        // Added the function htmlspecialchars to activity name string because it was corrupting Jquery code while using quotes on page rendering. - Carlos R Caraballo 1/18/2019
        $title = $course->code . $course->number . '-' . $course->section . ': ' . htmlspecialchars($activity_1->name, ENT_QUOTES) . ' <span class="small attention">(' . $course->semester->code . ')</span>';
        $outcomes = Outcome::select(array('id', 'name', 'expected_outcome'))
            ->whereNull('deleted_at')
            ->whereRaw("(deactivation_date IS NULL or deactivation_date >= '{$semesters->start}')")
            ->orderBy('name', 'ASC')->get();
        $assessment_1 = DB::table('assessments')
            ->join('activity_criterion', 'assessments.activity_criterion_id', '=', 'activity_criterion.id')
            ->join('activities', 'activities.id', '=', 'activity_criterion.activity_id')
            ->where('activity_id', $activity_1->id)
            ->get();

        //results

        if ($assessment_1) {
            $results_1 = $activity_1->getOutcomeReport();
            $outcomes_achieved_1 = $activity_1->o_ach_array;
            $outcomes_attempted_1 = $activity_1->o_att_array;
        } else {
            $outcomes_achieved_1 = [];
            $outcomes_attempted_1 = [];
        }

        $assessment_2 = DB::table('assessments')
            ->join('activity_criterion', 'assessments.activity_criterion_id', '=', 'activity_criterion.id')
            ->join('activities', 'activities.id', '=', 'activity_criterion.activity_id')
            ->where('activity_id', $activity_2->id)
            ->get();

        if ($assessment_2) {
            $results_2 = $activity_1->getOutcomeReport();
            $outcomes_achieved_2 = $activity_2->o_ach_array;
            $outcomes_attempted_2 = $activity_2->o_att_array;
        } else {
            $outcomes_achieved_2 = [];
            $outcomes_attempted_2 = [];
        }



        $activity_criterion_2 = DB::table('criteria')
            ->join('activity_criterion', 'criteria.id', '=', 'activity_criterion.criterion_id')
            ->where('activity_id', $activity_2->id)
            ->select('activity_criterion.id', 'activity_criterion.criterion_id')
            ->addSelect('criteria.name')
            ->get();
        Log::info("AAAA");
        Log::info($results_2);




        return View::make('local.professors.compare_activities', compact('results_1', 'results_2', 'activity_1', 'activity_2', 'activity_criterion_1', 'activity_criterion_2', 'title', 'outcomes', 'outcomes_achieved_1', 'outcomes_attempted_1', 'outcomes_achieved_2', 'outcomes_attempted_2', 'course', 'student_count', 'active_semesters'));
    }
}