<?php

class RubricsController extends \BaseController
{

    /**
     * Show the form for creating a new rubric
     *
     * @return Response
     */
    public function newRubric($activity_id)
    {
        $activity = Activity::find($activity_id);

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

        $title = 'Rubric for <em>' . $activity->name . '</em>';

        // Select templates that belong to everyone or belong to the activity's course's school
        $templates = Template::where('is_visible', '=', 1)
            ->where(function ($query) use ($activity) {
                if (Auth::user()->role != 1) {
                    $query
                        ->where('school_id', $activity->course->program->school->id)
                        ->orWhere('school_id', '=', NULL);
                }
            })
            ->orderBy('name', 'ASC')->get();

        $rubrics = Auth::user()->rubrics;
        $outcomes = Outcome::orderBy('name', 'ASC')->get();
        $criteria = Criterion::orderBy('name', 'ASC')->get();
        $rubric = $activity->rubric;

        return View::make('local.professors.rubrics', compact('title', 'templates', 'outcomes', 'criteria', 'rubrics', 'activity', 'rubric'));
    }

    /**
     * Save a new rubric
     *
     * @return Response
     */
    public function create()
    {

        DB::beginTransaction();

        try {
            // Get rubric contents
            $rubric_contents = json_decode(Input::get('contents'));

            // Process rubric
            $rubric = new Rubric;
            $rubric->name = Input::get('name');
            $rubric->contents = json_encode($rubric_contents);
            $rubric->expected_percentage = Input::get('expected_percentage');
            $rubric->expected_points = Input::get('expected_points');
            $rubric->user_id = Auth::id();
            $rubric->save();

            // Process activity
            $activity = Activity::find(Input::get('activity_id'));
            $activity->rubric_id = $rubric->id;
            $activity->save();

            DB::commit();

            Session::flash('status', 'success');
            Session::flash('message', 'Rubric assigned.');

            return action('ActivitiesController@show', array($activity->id));
        } catch (Exception $e) {

            DB::rollBack();
            echo $e->getMessage();
            //Session::flash('status', 'danger');
            //Session::flash('message', 'Error creating Rubric. Try again later.');
        }
    }

    /**
     * Return a specific template
     *
     * @return Template
     */
    public function fetch()
    {
        return Rubric::find(Input::get('id'));
    }

    /**
     * Update a rubric
     *
     * @return Response
     */
    public function update()
    {
        $rubric = Rubric::find(Input::get('id'));
        $rubric->name = Input::get('name');
        $rubric->contents = Input::get('contents');
        $rubric->expected_percentage = Input::get('expected_percentage');
        $rubric->expected_points = Input::get('expected_points');

        DB::beginTransaction();

        try {
            // Get associated activity
            $activity = Activity::where('rubric_id', '=', $rubric->id)->first();

            // If the associated activity has been assessed, delete the records
            if ($activity->outcomes_attempted != NULL) {
                DB::table('assessments')->where('activity_id', '=', $activity->id)->delete();
                $activity->criteria_achieved_percentage = NULL;
                $activity->criteria_achieved = NULL;
                $activity->outcomes_achieved = NULL;
                $activity->outcomes_attempted = NULL;
            }

            $rubric->save();
            $activity->save();

            // Get all the course's activities
            $course = Course::find($activity->course->id);
            $activities = $course->activities;

            // Check if any assessed activities 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 (!$activities->isEmpty() && $remainingAssessed) {
                // Variables to hold recalculated outcomes for the course
                $course_outcomes_attempted = array_fill(1, Outcome::all()->count(), 0);
                $course_outcomes_achieved = array_fill(1, Outcome::all()->count(), 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::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 {
                // Update course
                $course->outcomes_achieved = NULL;
                $course->outcomes_attempted = NULL;
            }

            $course->save();
            DB::commit();

            Session::flash('status', 'success');
            Session::flash('message', 'Rubric updated.');

            return action('ActivitiesController@show', array($activity->id));
        } catch (Exception $e) {
            DB::rollBack();
            Session::flash('status', 'danger');
            Session::flash('message', 'Error: The rubric could not be updated. Try again later.');
        }
    }

    /**
     * Remove the specified resource from storage.
     *
     * @return Response
     */
    public function destroy()
    {
        $rubric = Rubric::find(Input::get('id'));

        if ($rubric->delete()) {
            Session::flash('status', 'success');
            Session::flash('message', 'Rubric deleted.');
        } else {
            Session::flash('status', 'danger');
            Session::flash('message', 'Error: The rubric could not be deleted. Try again later.');
        }

        return;
    }

    /**
     * Show a specific rubric
     *
     * @return Response
     */
    public function show($activity_id)
    {
        $activity = Activity::find($activity_id);
        // 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');

        $rubric = Rubric::where('id', '=', $activity->rubric_id)->firstOrFail();
        $title = $activity->name . ': ' . $rubric->name;
        return View::make('local.professors.viewrubric', compact('rubric', 'activity', 'title', 'course'));
    }

    /**
     * Show a specific rubric without some course and user information
     *
     * @return Response
     */
    public function show_limited($rubric_id)
    {
        // If user is a professor, display 403.
        if (Auth::user()->role == 4)
            App::abort('403', 'Access Forbidden');

        $rubric = Rubric::where('id', '=', $rubric_id)->firstOrFail();
        $title = $rubric->name;
        $role = Auth::user()->role;
        return View::make('local.managers.shared.view_rubric_limited', compact('rubric', 'title', 'role'));
    }

    public function download($activity_id, $rubric_id)
    {
        $activity = Activity::find($activity_id);
        // 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');

        $rubric = Rubric::where('id', '=', $activity->rubric_id)->firstOrFail();
        $title = $activity->name . ': ' . $rubric->name;
        return View::make('local.professors.downloadrubric', compact('rubric', 'activity', 'title', 'course'));
    }

    public function printview($activity_id, $rubric_id)
    {
        $activity = Activity::find($activity_id);
        // 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');

        $rubric = Rubric::where('id', '=', $activity->rubric_id)->firstOrFail();
        $title = $activity->name . ': ' . $rubric->name;
        return View::make('local.professors.printrubric', compact('rubric', 'activity', 'title', 'course'));
    }

    public function fetchRubricCriterion()
    {
        $rubric = Rubric::findOrFail(Input::get('rubric_id'));
        $criterion_id = Input::get('criterion_id');

        $rubric_contents = json_decode($rubric->contents);

        foreach ($rubric_contents as $key => $criterion) {
            if ($criterion->id == $criterion_id) {
                return json_encode($criterion);
            }
        }
    }
}
