<?php

use Illuminate\Database\Eloquent\Collection;

class OutcomesController extends \BaseController
{


    /**
     * Show all Learning Outcomes and expected values
     *
     */
    public function index()
    {
        $title = "Learning Outcomes";
        $outcomes = Outcome::withTrashed()->orderBy('id', 'ASC')->get();
//         $outcomes = Outcome::withTrashed()->orderBy('name', 'ASC')->get();
        $schools = School::orderBy('name', 'ASC')->get();
        // $semesters_ids = Session::get('semesters_ids');
        // $semesters = Semester::whereIn('id',$semesters_ids)->get();

        return View::make('local.managers.admins.learning-outcomes', compact('title', 'outcomes', 'schools'));
        //return View::make('local.managers.admins.learning-outcomes', compact('title', 'outcomes', 'schools','semesters'));
    }
    public function adminProgramIndex()
    {
    }
    // TODO: Change to home page
    public function newIndex()
    {
        $title = "Learning Outcomes";
        //        TODO: Check when semester doesnt exist or session is empty
        $selected_semester = Semester::find(Session::get('semesters_ids')[0]);
        $outcomes = Outcome::withTrashed()->where('deactivation_date', '>=', $selected_semester->start)->orWhere('deactivation_date', null)->orderBy('name', 'ASC')->get();
        $schools = School::orderBy('name', 'ASC')->get();

        return View::make('local.managers.admins.new-learning-outcomes', compact('title', 'outcomes', 'schools'));
    }

    public function show($id)
    {
        $outcome = Outcome::find($id);
        $selected_semesters = Semester::find(Session::get('semesters_ids'));
        $programs = $outcome->programs_attempted($selected_semesters);

        $undergradResults = array("names" => array(), "schools" => array(), "achieved" => array(), "attempted" => array(), "successRate" => array());
        $gradResults = array("names" => array(), "schools" => array(), "achieved" => array(), "attempted" => array(), "successRate" => array());
        foreach ($programs as $program_id) {
            //        	var_dump($program_id);
            //         	exit();
            $program = Program::where('id', '=', $program_id->id)->first();
            $school = School::where('id', '=', $program->school_id)->first();
            if ($program->is_graduate) {
                $gradResults['names'][] = $program->name;
                $gradResults['schools'][] = $school->name;
                $attempted = $program->attempted_criteria_by_outcome($id, $selected_semesters);
                $gradResults['attempted'][] = $attempted;
                $achieved = $program->achieved_criteria_by_outcome($id, $selected_semesters);
                $gradResults['achieved'][] = $achieved;
                $gradResults['successRate'][] = sprintf("%.2f", 100 * $achieved / $attempted);
            } else {
                $undergradResults['names'][] = $program->name;
                $undergradResults['schools'][] = $school->name;
                $attempted = $program->attempted_criteria_by_outcome($id, $selected_semesters);
                $undergradResults['attempted'][] = $attempted;
                $achieved = $program->achieved_criteria_by_outcome($id, $selected_semesters);
                $undergradResults['achieved'][] = $achieved;
                $undergradResults['successRate'][] = sprintf("%.2f", 100 * $achieved / $attempted);
            }
        }

        $title = "Outcome Results: " . $outcome->name;


        //  		$undergradResults["successRate"]

        return View::make('local.managers.admins.learning-outcome', compact('title', 'outcome', 'undergradResults', 'gradResults'));
    }

    //     public function showOri($id)
    //     {
    //         DB::disableQueryLog();
    //         $outcome = Outcome::find($id);
    //
    //         $undergradResults=array("names"=>array(), "schools"=>array(), "achieved"=>array(), "attempted"=>array(), "successRate"=>array());
    //         $gradResults = array("names"=>array(), "schools"=>array(), "achieved"=>array(), "attempted"=>array(), "successRate"=>array());
    //
    //         //Calculate performance for this outcome for each undergrad program
    //         $undergradPrograms = Program::where('is_graduate','=', 0)
    //             ->where(function($query)
    //             {
    //                 if(Auth::user()->school_id)
    //                 {
    //                     $query->where('school_id', Auth::user()->school_id);
    //                 }
    //             })
    //             ->with('courses')
    //             ->orderBy('name', 'asc')->get();
    //
    //         foreach($undergradPrograms as $program)
    //         {
    //             $undergradResults["names"][$program->id]=$program->name;
    //             $undergradResults["schools"][$program->id]=$program->school->name;
    //             $programAssessed=false;
    //
    //             $undergradResults["attempted"][$program->id]=0;
    //             $undergradResults["achieved"][$program->id]=0;
    //
    //             foreach($program->courses as $course)
    //             {
    //                 $course_outcomes_achieved = json_decode($course->outcomes_achieved, true);
    //                 $course_outcomes_attempted = json_decode($course->outcomes_attempted, true);
    //
    //                 $attemptedCriteriaCount=0;
    //                 $achievedCriteriaCount=0;
    //
    //                 // If this outcome was evaluated
    //                 if(
    //                     $course_outcomes_attempted
    //                     && array_key_exists($outcome->id, $course_outcomes_attempted)
    //                     && $course_outcomes_attempted[$outcome->id]!=0)
    //                 {
    //                     // Count +1 for attempted and achieved in the program
    //                     $attemptedCriteriaCount+=$course_outcomes_attempted[$outcome->id];
    //                     $achievedCriteriaCount+=$course_outcomes_achieved[$outcome->id];
    //                     $programAssessed=true;
    //
    //                     if($attemptedCriteriaCount>0  &&(float)$achievedCriteriaCount/$attemptedCriteriaCount*100 > $outcome->expected_outcome)
    //                     {
    //                         $undergradResults["achieved"][$program->id]+=1;
    //                     }
    //                     $undergradResults["attempted"][$program->id]+=1;
    //                 }
    //             }
    //
    //             // Calculate success rate for this program
    //             if($programAssessed && $undergradResults["attempted"][$program->id]>0)
    //                 $undergradResults["successRate"][$program->id]= round((float)$undergradResults["achieved"][$program->id]/$undergradResults["attempted"][$program->id]*100, 2).'%';
    //             else
    //                 $undergradResults["successRate"][$program->id]= 'N/M';
    //         }
    //
    //
    //         //Calculate performance for this outcome for each grad program
    //         $gradPrograms = Program::where('is_graduate','=', 1)
    //             ->where(function($query)
    //             {
    //                 if(Auth::user()->school_id)
    //                 {
    //                     $query->where('school_id', Auth::user()->school_id);
    //                 }
    //             })
    //             ->with(array('courses'=>function($query)
    //             {
    //                 $query->whereNotNull('outcomes_attempted');
    //             }))
    //             ->orderBy('name', 'asc')->get();
    //
    //         foreach($gradPrograms as $program)
    //         {
    //             $gradResults["names"][$program->id]=$program->name;
    //             $gradResults["schools"][$program->id]=$program->school->name;
    //
    //             $programAssessed=false;
    //
    //             $gradResults["attempted"][$program->id]=0;
    //             $gradResults["achieved"][$program->id]=0;
    //
    //             foreach($program->courses as $course)
    //             {
    //                 $course_outcomes_achieved = json_decode($course->outcomes_achieved, true);
    //                 $course_outcomes_attempted = json_decode($course->outcomes_attempted, true);
    //
    //                 $attemptedCriteriaCount=0;
    //                 $achievedCriteriaCount=0;
    //
    //                 // If this outcome was evaluated
    //                 if(
    //                     $course_outcomes_attempted
    //                     && array_key_exists($outcome->id, $course_outcomes_attempted)
    //                     && $course_outcomes_attempted[$outcome->id]!=0)
    //                 {
    //                     // Count +1 for attempted and achieved in the program
    //                     $attemptedCriteriaCount+=$course_outcomes_attempted[$outcome->id];
    //                     $achievedCriteriaCount+=$course_outcomes_achieved[$outcome->id];
    //                     $programAssessed=true;
    //
    //                     if($attemptedCriteriaCount>0  &&(float)$achievedCriteriaCount/$attemptedCriteriaCount*100 > $outcome->expected_outcome)
    //                     {
    //                         $gradResults["achieved"][$program->id]+=1;
    //                     }
    //                     $gradResults["attempted"][$program->id]+=1;
    //                 }
    //             }
    //
    //             // Calculate success rate for this program
    //             if($programAssessed && $gradResults["attempted"][$program->id]>0)
    //                 $gradResults["successRate"][$program->id]= round((float)$gradResults["achieved"][$program->id]/$gradResults["attempted"][$program->id]*100, 2).'%';
    //             else
    //                 $gradResults["successRate"][$program->id]= 'N/M';
    //         }
    //
    //         $title = "Outcome Results: ".$outcome->name;
    //
    //         return View::make('local.managers.admins.learning-outcome', compact('title', 'outcome', 'undergradResults', 'gradResults'));
    //     }

    // TODO: Clean up and verify relationships are correct
    public function newShow($id)
    {
        //        DB::disableQueryLog();
        //        $outcome = null;
        if ($id === 'all') {
            $outcome = Outcome::with('objectives.criteria')->get();
            $title = 'All Outcomes';
            $criteria = $outcome->reduce(function ($carry, $outcome) {
                return $carry->merge($outcome->criteria);
            }, Collection::make([]));
            $report_link = URL::action('OutcomesController@newReportAll');
        } else {
            $outcome = Outcome::with(['objectives.criteria'])->find($id);
            $title = $outcome->name;
            $criteria = $outcome->criteria->load('rubrics');
            $report_link = URL::action('OutcomesController@newReport', ['id' => $outcome->id]);
        }

        //        $objectives = $outcome->objectives;
        //        var_dump(get_class_methods($criteria));
        //        var_dump($criteria);
        $rubrics = $criteria->reduce(function ($carry, $crit) {
            return $carry->merge($crit->rubrics);
        }, Collection::make([]))->load('activities');
        $activities = $rubrics->reduce(function ($carry, $rubric) {
            return $carry->merge($rubric->activities);
        }, Collection::make([]));
        $courses = $activities->reduce(function ($carry, $activity) {
            if ($activity->course !== null) {
                $carry->push($activity->course);
            }
            return $carry;
        }, Collection::make([]));
        $activities = $activities->filter(function ($activity) {
            return ($activity->course === null);
        });

        //        var_dump(DB::getQueryLog());
        return View::make('local.managers.admins.new-learning-outcome', compact('title', 'outcome', 'courses', 'activities', 'report_link'));
    }

    public function newReport($id)
    {
        $outcome = Outcome::find($id);
        $objectives = $outcome->objectives;
        $criteria = $outcome->criteria;
        $programs = $objectives->map(function ($objective) {
            return $objective->program;
        })
            ->merge($criteria->map(function ($criteria) {
                return $criteria->program;
            }))
            ->filter(function ($program) {
                return $program->users->contains(Auth::user());
            });
        $title = $outcome->name . ' Report';


        return View::make('local.managers.admins.new-report', compact('title', 'outcome', 'objectives'));
    }

    public function newReportAll()
    {
        $outcomes = Outcome::with('objectives')->get();
        $title = 'All Outcomes Report';

        return View::make('local.managers.admins.new-report-all', compact('title', 'outcomes'));
    }

    public function update()
    {
        $outcomeArray = json_decode(Input::get('outcomeArray'), true);
        Session::flash('status', 'success');
        Session::flash('message', 'Learning Outcomes updated.');

        foreach ($outcomeArray as $outcomeObject) {


            $validator = Validator::make(
                array(
                    'name' => $outcomeObject['name'],
                    'definition' => $outcomeObject['definition'],
                    'expected_outcome' => $outcomeObject['expected_outcome']
                ),
                array(
                    'name' => 'required',
                    'definition' => 'required',
                    'expected_outcome' => 'required|numeric'
                )
            );

            if (!$validator->fails()) {
                try {
                    $outcome = Outcome::withTrashed()
                        ->where('id', '=', $outcomeObject['id'])
                        ->firstOrFail();
                    $outcome->name = $outcomeObject['name'];
                    $outcome->definition = $outcomeObject['definition'];
                    $outcome->expected_outcome = $outcomeObject['expected_outcome'];
                    $outcome->save();

                    // If delete is 1, and outcome isn't already trashed, delete
                    if ($outcomeObject['delete'] == 1 && !$outcome->trashed())
                        $outcome->delete();
                    // If delete is 0, and outcome is already trashed, restore
                    elseif ($outcomeObject['delete'] == 0 && $outcome->trashed())
                        $outcome->restore();
                } catch (Exception $e) {

                    Session::flash('message', $e->getMessage());
                }
            } else {
                /** Prepare error message */
                $message = 'Error(s) updating the Learning Outcomes: <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;
            }
        }

        return;
    }

    /**
     *Copy of update(), but also updates activation_date, deactivation_date and level
     */
    public function delete()
    {
        $outcomeArray = json_decode(Input::get('outcomeArray'), true);
// 		Log::info("delete".json_encode($outcomeArray));
		$outcome = Outcome::withTrashed()
			->where('id', '=', $outcomeArray['id'])
			->firstOrFail();
// 		Log::info("delete2".json_encode($outcome));
		$outcome->forceDelete();
// 		Log::info("sal".json_encode($sal));
// 		if($sal)
		{
			Session::flash('status', 'success');
			Session::flash('message', 'Learning Outcome deleted.');
			
		}

	}
    
    public function updateMore()
    {
        $outcomeArray = json_decode(Input::get('outcomeArray'), true);
        Session::flash('status', 'success');
        Session::flash('message', 'Learning Outcomes updated.');
		Log::info("Ahora1".json_encode($outcomeArray));

        foreach ($outcomeArray as $outcomeObject) {


            $validator = Validator::make(
                array(
                    'name' => $outcomeObject['name'],
                    'definition' => $outcomeObject['definition'],
                    'expected_outcome' => $outcomeObject['expected_outcome'],
                    'activation_date' => $outcomeObject['activation_date'],
//                     'deactivation_date' => (isset($outcomeObject['deactivation_date'])?$outcomeObject['deactivation_date']:NULL),
                    'level' => $outcomeObject['level'],
//                     'new_outcome_id'=>$outcomeObject['new_outcome_id']
                    // TODO- validar los otros 3 valores
                ),
                array(
                    'name' => 'required',
                    'definition' => 'required',
                    'expected_outcome' => 'required|numeric',
                    'activation_date' => 'required|date',
//                     'deactivation_date' => 'sometimes|required|date',
                    'level' => 'required|numeric'
//                     'new_outcome_id' => 'required|numeric'
                    // TODO- los requisitos de los otros 3 valores
                )
            );

            if (!$validator->fails()) {
                try {
                    $outcome = Outcome::withTrashed()
                        ->where('id', '=', $outcomeObject['id'])
                        ->firstOrFail();
                    $outcome->name = $outcomeObject['name'];
                    $outcome->definition = $outcomeObject['definition'];
                    $outcome->expected_outcome = $outcomeObject['expected_outcome'];
                    $outcome->activation_date = $outcomeObject['activation_date'];
                    if($outcomeObject['deactivation_date']!="")
                    {
                    	$outcome->deactivation_date = $outcomeObject['deactivation_date'];
	                    if(isset($outcomeObject['new_outcome_id']))$outcome->new_outcome_id = $outcomeObject['new_outcome_id'];
                    }
                    else 
                    {
                    	$outcome->deactivation_date = NULL;
                    	$outcome->new_outcome_id=NULL;
                    }
                    $outcome->level = $outcomeObject['level'];
		Log::info("Ahora2".json_encode($outcome));

                    $outcome->save();

                    // If delete is 1, and outcome isn't already trashed, delete
                    if ($outcomeObject['delete'] == 1 && !$outcome->trashed())
                        $outcome->delete();
                    // If delete is 0, and outcome is already trashed, restore
                    elseif ($outcomeObject['delete'] == 0 && $outcome->trashed())
                        $outcome->restore();
                } catch (Exception $e) {

                    Session::flash('message', $e->getMessage());
                }
            } else {
                /** Prepare error message */
                $message = 'Error(s) updating the Learning Outcomes: <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;
            }
        }

        return;
    }

    public function fetchCriteria()
    {
        // 		var_dump((Input::get('filter')));
        // 		exit();
        if (Input::get('filter')) {
            switch (Input::get('filter')) {
                case 'all':
                    $criteria = DB::table('criteria')
                        ->join('criterion_objective_outcome', 'criterion_objective_outcome.criterion_id', '=', 'criteria.id')
                        ->where('criterion_objective_outcome.outcome_id', '=', Input::get('outcome_id'))
                        ->where('criterion_objective_outcome.objective_id', '=', Input::get('objective_id'))
                        ->where('criteria.num_scales', '=', Input::get('num_scales'))
                        ->where('criteria.max_score', '=', Input::get('maximum'))
                        ->select('criterion_id as id', 'name')
                        ->orderBy('name', 'ASC')
                        ->get();

                    foreach ($criteria as $criterion) {
                        $criterion->program_ids = json_encode(DB::table('program_criterion')
                            ->where('criterion_id', $criterion->id)
                            ->lists('program_id'));
                        $criterion->objectives = DB::table('criterion_objective_outcome')
                            ->join('objectives', 'objectives.id', '=', 'criterion_objective_outcome.objective_id')
                            ->where('criterion_id', $criterion->id)
                            ->select('objectives.*')
                            ->distinct()
                            ->lists('text');
                    }
                    return $criteria;
                    break;

                case 'school':
                    // If scoord
                    if (Auth::user()->role == '2') {

                        // Fetch all the programs whose school is the user's
                        $program_ids = DB::table('programs')->where('school_id', Auth::user()->school_id)->lists('id');
                        $criteria = DB::table('criteria')
                            ->join('criterion_objective_outcome', 'criterion_objective_outcome.criterion_id', '=', 'criteria.id')
                            ->join('program_criterion', 'program_criterion.criterion_id', '=', 'criteria.id')
                            ->where('criterion_objective_outcome.outcome_id', '=', Input::get('outcome_id'))
                            ->where('criterion_objective_outcome.objective_id', '=', Input::get('objective_id'))
                            ->where('criteria.num_scales', '=', Input::get('num_scales'))
                            ->where('criteria.max_score', '=', Input::get('maximum'))
                            ->whereIn('program_criterion.program_id', $program_ids)
                            ->select('criterion_id as id', 'name')
                            ->orderBy('name', 'ASC')
                            ->get();
                        foreach ($criteria as $criterion) {
                            $criterion->program_ids = json_encode(DB::table('program_criterion')
                                ->where('criterion_id', $criterion->id)
                                ->lists('program_id'));
                            $criterion->objectives = json_encode(DB::table('criterion_objective_outcome')
                                ->join('objectives', 'objectives.id', '=', 'criterion_objective_outcome.objective_id')
                                ->where('criterion_id', $criterion->id)
                                ->select('objectives.*')
                                ->distinct()
                                ->lists('text'));
                        }
                        // Return all criteria belonging to any of those programs
                        return $criteria;
                    }

                    // If pcoord
                    else {

                        // Fetch all the programs from the user's school;
                        // Fetch all the programs from the user's school;
                        $program_ids = DB::table('programs')->where('school_id', Auth::user()->programs[0]->school->id)->lists('id');

                        $criteria = DB::table('criteria')
                            ->join('criterion_objective_outcome', 'criterion_objective_outcome.criterion_id', '=', 'criteria.id')
                            ->join('program_criterion', 'program_criterion.criterion_id', '=', 'criteria.id')
                            ->where('criterion_objective_outcome.outcome_id', '=', Input::get('outcome_id'))
                            ->where('criterion_objective_outcome.objective_id', '=', Input::get('objective_id'))
                            ->where('criteria.num_scales', '=', Input::get('num_scales'))
                            ->where('criteria.max_score', '=', Input::get('maximum'))
                            ->whereIn('program_criterion.program_id', $program_ids)
                            ->select('criterion_id as id', 'name')
                            ->orderBy('name', 'ASC')
                            ->get();

                        foreach ($criteria as $criterion) {
                            $criterion->program_ids = json_encode(DB::table('program_criterion')
                                ->where('criterion_id', $criterion->id)
                                ->lists('program_id'));
                            $criterion->objectives = json_encode(DB::table('criterion_objective_outcome')
                                ->join('objectives', 'objectives.id', '=', 'criterion_objective_outcome.objective_id')
                                ->where('criterion_id', $criterion->id)
                                ->select('objectives.*')
                                ->distinct()
                                ->lists('text'));
                        }
                        return $criteria;
                    }

                    break;

                case 'program':
                    $criteria = DB::table('criteria')
                        ->join('criterion_objective_outcome', 'criterion_objective_outcome.criterion_id', '=', 'criteria.id')
                        ->join('program_criterion', 'program_criterion.criterion_id', '=', 'criteria.id')
                        ->where('criterion_objective_outcome.outcome_id', '=', Input::get('outcome_id'))
                        ->where('criterion_objective_outcome.objective_id', '=', Input::get('objective_id'))
                        ->where('criteria.num_scales', '=', Input::get('num_scales'))
                        ->where('criteria.max_score', '=', Input::get('maximum'))
                        ->whereIn('program_criterion.program_id', Auth::user()->programs->lists('id'))
                        ->select('criterion_id as id', 'name')
                        ->orderBy('name', 'ASC')
                        ->get();
                    foreach ($criteria as $criterion) {
                        $criterion->program_ids = json_encode(DB::table('program_criterion')
                            ->where('criterion_id', $criterion->id)
                            ->lists('program_id'));
                        $criterion->objectives = json_encode(DB::table('criterion_objective_outcome')
                            ->join('objectives', 'objectives.id', '=', 'criterion_objective_outcome.objective_id')
                            ->where('criterion_id', $criterion->id)
                            ->select('objectives.*')
                            ->distinct()
                            ->lists('text'));
                    }
                    return $criteria;
                    break;

                default:
                    $criteria = DB::table('criteria')
                        ->join('criterion_objective_outcome', 'criterion_objective_outcome.criterion_id', '=', 'criteria.id')
                        ->where('criterion_objective_outcome.outcome_id', '=', Input::get('outcome_id'))
                        ->where('criterion_objective_outcome.objective_id', '=', Input::get('objective_id'))
                        ->where('criteria.num_scales', '=', Input::get('num_scales'))
                        ->where('criteria.max_score', '=', Input::get('maximum'))
                        ->select('criterion_id as id', 'name')
                        ->orderBy('name', 'ASC')
                        ->get();

                    foreach ($criteria as $criterion) {
                        $criterion->program_ids = json_encode(DB::table('program_criterion')
                            ->where('criterion_id', $criterion->id)
                            ->lists('program_id'));
                        $criterion->objectives = json_encode(DB::table('criterion_objective_outcome')
                            ->join('objectives', 'objectives.id', '=', 'criterion_objective_outcome.objective_id')
                            ->where('criterion_id', $criterion->id)
                            ->select('objectives.*')
                            ->distinct()
                            ->lists('text'));
                    }
                    return $criteria;
                    break;
            }
        } else {
            $criteria = DB::table('criteria')
                ->join('criterion_objective_outcome', 'criterion_objective_outcome.criterion_id', '=', 'criteria.id')
                ->where('criterion_objective_outcome.outcome_id', '=', Input::get('outcome_id'))
                ->where('criterion_objective_outcome.objective_id', '=', Input::get('objective_id'))
                ->where('criteria.num_scales', '=', Input::get('num_scales'))
                ->where('criteria.max_score', '=', Input::get('maximum'))
                ->select('criterion_id as id', 'name')
                ->orderBy('name', 'ASC')
                ->get();

            foreach ($criteria as $criterion) {
                $criterion->program_ids = json_encode(DB::table('program_criterion')
                    ->where('criterion_id', $criterion->id)
                    ->lists('program_id'));
                $criterion->objectives = json_encode(DB::table('criterion_objective_outcome')
                    ->join('objectives', 'objectives.id', '=', 'criterion_objective_outcome.objective_id')
                    ->where('criterion_id', $criterion->id)
                    ->select('objectives.*')
                    ->distinct()
                    ->lists('text'));
            }
            return $criteria;
        }
    }

    /**
     * Create a new learning outcome.
     */
    public function create()
    {
        /** Validation rules */
        $validator = Validator::make(
            array(
                'name' => Input::get('name'),
                'definition' => Input::get('definition')
            ),
            array(
                'name' => 'required|unique:outcomes',
                'definition' => 'required|min:10'
            )
        );

        /** If validation fails */
        if ($validator->fails()) {
            /** Prepare error message */
            $message = '<p>Error(s) creating a new Learning Outcome</p><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::to('learning-outcomes')->withInput();
        } else {
            /** Instantiate new outcome */
            $outcome = new Outcome;
            $outcome->name = Input::get('name');
            $outcome->definition = Input::get('definition');

            /** If outcome is saved, send success message */
            if ($outcome->save()) {
                Session::flash('status', 'success');
                Session::flash('message', '<p>Learning Outcome added.</p>');
                return Redirect::to('learning-outcomes');
            }

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

    public function fetchOutcome()
    {
        // original code using models
        // TODO: models have to be updated because of the database update

        $id = Input::get('id');

        $outcome_info = DB::table('outcomes')
            ->where('outcomes.id', $id)
            ->get();
        $outcome = $outcome_info[0];



        $criteria_array = array();

        // switch para el query, dependiendo del usuario

        $role = Auth::user()['role'];
        $semesters = Session::get('sesemster_ids');

        switch ($role) {
            case 1:
                $program_ids = DB::table('programs')->lists('id');
                break;
            case 2:
                $school_id = Auth::user()['school_id'];
                $program_ids = DB::table('programs')->where('school_id', $school_id)->lists('id');
                break;
            case 3:
                $program_ids = DB::table('program_user')->where('user_id', Auth::user()['id'])->lists('program_id');
                break;
            case 4:
                $program_ids = DB::table('program_user')->where('user_id', Auth::user()['id'])->lists('program_id');
                break;
        }

        $diferent_levels = DB::table('criterion_objective_outcome')
            ->join('criteria', 'criteria.id', '=', 'criterion_objective_outcome.criterion_id')
            // GASP, añadí programa, para que solo muestre niveles de criterios del programa
            ->join('program_criterion', 'criteria.id', '=', 'program_criterion.criterion_id')
            ->whereIn('program_id', $program_ids)
            ->where('criterion_objective_outcome.outcome_id', $id)
            ->distinct('criteria.num_scales')
            ->select('criteria.num_scales as levels')
            ->orderBy('criteria.num_scales', 'asc')
            ->get();

        $outcome->criteria = array();
        foreach ($diferent_levels as $level) {
            $level = $level->levels;

            // buscar todos los criterios con el level y ponerlos en un array
            //             $outcome_criterias = DB::table('criterion_objective_outcome')
            //                 ->join('new_criteria', 'new_criteria.id', '=', 'criterion_objective_outcome.criterion_id')
            //                 ->join('objectives', 'objectives.id', '=', 'criterion_objective_outcome.objective_id')
            //                 ->where('criterion_objective_outcome.outcome_id', $id)
            //                 ->where('new_criteria.number_of_scales', $level)
            //                 ->whereNull('new_criteria.deleted_at')
            //                 ->select('new_criteria.id', 'new_criteria.name')
            //                 ->orderBy('new_criteria.name', 'asc')
            //                 ->get();
            $outcome_criterias = DB::table('criterion_objective_outcome')
                ->join('criteria', 'criteria.id', '=', 'criterion_objective_outcome.criterion_id')
                ->join('program_criterion', 'program_criterion.criterion_id', '=', 'criteria.id')
                ->whereIn('program_criterion.program_id', $program_ids)
                ->where('criterion_objective_outcome.outcome_id', $id)
                ->where('criteria.num_scales', $level)
                ->select('criteria.id', 'criteria.name', 'criteria.deleted_at')
                ->distinct()
                ->orderBy('criteria.name', 'asc')
                ->get();
            // $outcome_criterias = $outcome_criterias;

            foreach ($outcome_criterias as $criteria_id) {
                $scales = DB::select("select * FROM scales INNER join `criterion_scale` on `criterion_scale`.`scale_id` = `scales`.`id` where criterion_scale.criterion_id ={$criteria_id->id} ORDER BY position");

                $programs = DB::table('programs')
                    ->join('program_criterion', 'program_criterion.program_id', '=', 'programs.id')
                    ->where('criterion_id', $criteria_id->id)
                    ->lists('programs.name');
                Log::info($scales);

                /* $scales =
                    DB::select(
                        DB::raw("
                  SELECT *
                  FROM (
                    SELECT criteria.id as criterion_id,
                      ROW_NUMBER() OVER(PARTITION BY scales.id) rn,
                      scales.position,
                      scales.title, scales.description,
                      criterion_objective_outcome.outcome_id,criterion_objective_outcome.objective_id,
                      criterion_scale.scale_id
                    FROM criteria,criterion_scale,scales, criterion_objective_outcome, objectives
                    where criteria.id=criterion_scale.criterion_id
                      and scales.id = criterion_scale.scale_id
                      and criteria.id = criterion_objective_outcome.criterion_id
                      and objectives.id = criterion_objective_outcome.objective_id
                      and criterion_objective_outcome.outcome_id = $id
                      and criteria.id = $criteria_id->id
                    ORDER BY criteria.name ASC) a
                  WHERE rn = 1
                  ORDER BY `a`.`position` ASC
                      ")
                    );*/
                $criteria_id->programs = $programs;
                // insertar la informacion de los criterios con N niveles en el arreglo de arreglos
                $criteria_id->scales = $scales;
                // $i++;
            } //ends foreach criteria_id
            array_push($outcome->criteria, array($outcome_criterias, 'amount_of_levels' => $level));
        } //ends foreach level

        return array(
            'outcome' => $outcome,
        );
    }

    public function managerAssessmentReports()
    {
        $outcomes = Outcome::select(array('id', 'name', 'expected_outcome'))->orderBy('name', 'ASC')->get();

        switch (Auth::user()->role) {
            case 1:
                $title = "Campus Assessment Reports";
                return View::make('local.managers.admins.assessment_reports', compact('title', 'outcomes'));
                break;
            case 2:
                $title = "School Assessment Reports";
                return View::make('local.managers.sCoords.assessment_reports', compact('title', 'outcomes'));
                break;
            case 3:
                $title = "Program Assessment Reports";
                $programs  = Auth::user()->programs;
                return View::make('local.managers.pCoords.assessment_reports', compact('title', 'outcomes', 'programs'));
                break;
            default:
                App::abort('404');
                break;
        }
    }

    /**
     * Campus Assessment Reports
     */
    public function assessmentReport()
    {
        //$outcome = Outcome::find($outcome_id);
        set_time_limit(0);
        //if (!$outcome)
        //    App::abort('404');
        $title = "Campus Assessment Report "; //. $outcome->name;


        $schools = School::has('courses')
            ->with(array('programs' => function ($query) /*use ($outcome_id)*/ {
                $query
                    ->has('courses')
                    ->with(array('courses' => function ($query2) /*use ($outcome_id)*/ {
                        $query2
                            /*->has('activities')
                            //                             ->whereNotNull('outcomes_attempted')
                            // ->where('outcomes_attempted', 'NOT LIKE', '%"'.$outcome_id.'":0%')
                            ->whereIn('semester_id', Session::get('semesters_ids'))
                            ->groupBy(array('code', 'number'));*/
                            ->has('activities')
                            ->join('activities', 'activities.course_id', '=', 'courses.id')
                            ->join('activity_criterion as ac', 'ac.activity_id', '=', 'activities.id')
                            ->join('assessments', 'assessments.activity_criterion_id', '=', 'ac.id')
                            ->where('activities.draft', 0)
                            ->where('activities.diagnostic', 0)
                            ->select('courses.*')->distinct()
                            //->whereNotNull('outcomes_attempted')

                            ->whereIn('semester_id', Session::get('semesters_ids'))
                            ->groupBy(array('code', 'number'));
                    }));
            }))
            ->get();

        return View::make('local.managers.admins.new_assessment_report', compact('title', 'schools'));
    }

    public function totalAssessmentReport()
    {
        //SELECT sm.name, s.name, p.name, p.code, a.outcomes_attempted, stu.number, ass.scores, c.code, c.number, r.expected_points 
        //     	FROM students stu, schools s, programs p, courses c, activities a, assessments ass, rubrics r, semesters sm 
        //     	where stu.id=ass.student_id and sm.id=c.semester_id and s.id=p.school_id and p.id=c.program_id and a.course_id=c.id and ass.activity_id=a.id and a.rubric_id=r.id 
        //     	and c.semester_id in (12,13) and a.outcomes_attempted is not null
        ini_set('memory_limit', -1);
        ini_set('max_execution_time', 300);
        // 		$total_assessments_temp = DB::table('assessments')
        //          						->join('students', 'students.id', '=', 'assessments.student_id')
        //          						->join('activities', 'activities.id', '=', 'assessments.activity_id')
        //          						->join('rubrics', 'rubrics.id', '=', 'activities.rubric_id')
        //          						->join('courses', 'courses.id', '=', 'activities.course_id')
        //          						->join('programs', 'programs.id', '=', 'courses.program_id')
        //          						->join('schools', 'schools.id', '=', 'programs.school_id')
        //           						->join('semesters', 'semesters.id', '=', 'courses.semester_id')
        //                    			   	->whereIn('courses.semester_id', Session::get('semesters_ids'))
        //                     			->whereRaw('activities.outcomes_attempted is not null')
        //                     			->select('activities.id as activity_id','semesters.name as semester','schools.name as school','programs.name as program','programs.id as program_id','programs.code as program_code','students.number as student_number','students.conc_code as student_conc_code','assessments.scores as results','courses.name as course','courses.code as course_code','courses.number as course_number','rubrics.expected_points as expected_result')
        //                     			->orderBy('semesters.id','school','program','course','student_number')
        // 								->distinct()
        //                     			->get();
        //                     			    
        //         $total_assessments=array();
        // 		foreach($total_assessments_temp as $total_assessment)
        // 		{
        // 			$results=json_decode($total_assessment->results, TRUE);
        // 			$total_assessment->course=$total_assessment->course_code.$total_assessment->course_number." ".$total_assessment->course;
        // 			foreach($results as $criterion_id => $result)
        // 			{	
        // 				if($result and $result!="N/A")
        // 				{
        // 					$trans_temp=clone $total_assessment;
        // 					$criterion=Criterion::find($criterion_id);
        // 					if($criterion)
        // 					{
        // 	// 					var_dump($total_assessment->activity_id);
        // 	// 					var_dump($criterion_id);
        // 						if($criterion_id==1398)var_dump($criterion);
        // 	// 					exit();
        // 						$trans_temp->result=$result;
        // 						$trans_temp->criterion=$criterion->name;
        // 						$trans_temp->outcome=Outcome::find($criterion->outcome_id)->name;
        // 						$total_assessments[]=$trans_temp;
        // 					}
        // 				}
        // 			}
        // 		
        // 		}
        $total_assessments = DB::table('assessments')
            ->join('students', 'students.id', '=', 'assessments.student_id')
            ->join('activity_criterion', 'activity_criterion.id', '=', 'assessments.activity_criterion_id')
            ->join('activities', 'activities.id', '=', 'activity_criterion.activity_id')
            ->join('criteria', 'criteria.id', '=', 'activity_criterion.criterion_id')
            ->join('criterion_objective_outcome', 'criteria.id', '=', 'criterion_objective_outcome.criterion_id')
            ->join('outcomes', 'outcomes.id', '=', 'criterion_objective_outcome.outcome_id')
            ->join('rubric_activity', 'rubric_activity.activity_id', '=', 'activities.id')
            ->join('rubrics', 'rubrics.id', '=', 'rubric_activity.rubric_id')
            ->join('courses', 'courses.id', '=', 'activities.course_id')
            ->join('programs', 'programs.id', '=', 'courses.program_id')
            ->join('schools', 'schools.id', '=', 'programs.school_id')
            ->join('semesters', 'semesters.id', '=', 'courses.semester_id')
            ->whereIn('courses.semester_id', Session::get('semesters_ids'))
            ->select('criteria.name as criterion', 'outcomes.name as outcome', 'activities.id as activity_id', 'semesters.name as semester', 'schools.name as school', 'programs.name as program', 'programs.id as program_id', 'programs.code as program_code', 'students.number as student_number', 'students.conc_code as student_conc_code', 'assessments.score as result', 'courses.name as course', 'courses.code as course_code', 'courses.number as course_number', 'rubrics.expected_points as expected_result')
            ->orderBy('semesters.id', 'school', 'program', 'course', 'student_number')
            ->distinct()
            ->get();


        $title = "Total Assessment Report";

        return View::make('local.managers.admins.total_assessment', compact('title', 'total_assessments'));
    }

    // TODO: Change later
    public function newAssessmentReport($outcome_id)
    {
        $outcome = Outcome::find($outcome_id);

        if (!$outcome)
            App::abort('404');
        $title = "Assessment Report: " . $outcome->name;

        $schools = School::has('courses')
            ->with(array('programs' => function ($query) use ($outcome_id) {
                $query
                    ->has('courses')
                    ->with(array('courses' => function ($query2) use ($outcome_id) {
                        $query2
                            ->has('activities')
                            //                             ->whereNotNull('outcomes_attempted')
                            // ->where('outcomes_attempted', 'NOT LIKE', '%"'.$outcome_id.'":0%')
                            ->join('activities', 'activities.course_id', '=', 'courses.id')
                            ->join('activity_criterion as ac', 'ac.activity_id', '=', 'activities.id')
                            ->join('assessments', 'assessments.activity_criterion_id', '=', 'ac.id')
                            ->where('activities.draft', 0)
                            ->where('activities.diagnostic', 0)
                            ->select('courses.*')->distinct()
                            ->whereIn('semester_id', Session::get('semesters_ids'))
                            ->groupBy(array('code', 'number'));
                    }));
            }))
            ->get();

        return View::make('local.managers.admins.assessment_report', compact('title', 'outcome', 'schools'));
    }

    /**
     * School Assessment Reports
     */
    private function cmp($a, $b)
    {
        return strcmp($a->name, $b->name);
    }
    public function schoolAssessmentReport()
    {

        //$outcome = Outcome::find($outcome_id);

        //if (!$outcome)
        //    App::abort('404');
        $title = "School Assessment Reports";

        set_time_limit(0);
        $school = School::where('id', Auth::user()->school_id)
            ->has('courses')
            ->with(array('programs' => function ($query) {
                $query
                    ->has('courses')
                    ->with(array('courses' => function ($query2) {
                        $query2
                            ->has('activities')
                            ->join('activities', 'activities.course_id', '=', 'courses.id')
                            ->join('activity_criterion as ac', 'ac.activity_id', '=', 'activities.id')
                            ->join('assessments', 'assessments.activity_criterion_id', '=', 'ac.id')
                            ->where('activities.draft', 0)
                            ->where('activities.diagnostic', 0)
                            ->select('courses.*')->distinct()
                            //->whereNotNull('outcomes_attempted')

                            ->whereIn('semester_id', Session::get('semesters_ids'))
                            ->groupBy(array('code', 'number'));
                    }));
            }))
            ->first();

        return View::make('local.managers.sCoords.new_assessment_report', compact('title', 'school'));
    }

    /**
     *    Program Assessment Reports
     */
    public function programAssessmentReport($program_id)
    {
        //$outcome = Outcome::find($outcome_id);

        //if (!$outcome)
        //    App::abort('404');
        $title = "Program Courses Report";

        set_time_limit(0);
        $program = Program::where('id', $program_id)
            ->has('courses')
            ->with(array('courses' => function ($query) {
                $query
                    ->has('activities')
                    //->whereNotNull('outcomes_attempted')
                    ->join('activities', 'activities.course_id', '=', 'courses.id')
                    ->join('activity_criterion as ac', 'ac.activity_id', '=', 'activities.id')
                    ->join('assessments', 'assessments.activity_criterion_id', '=', 'ac.id')
                    ->where('activities.draft', 0)
                    ->where('activities.diagnostic', 0)
                    ->select('courses.*')->distinct()

                    ->whereIn('semester_id', Session::get('semesters_ids'))
                    ->groupBy(array('code', 'number'));
            }))
            ->first();
        Log::info($program);


        return View::make('local.managers.pCoords.new_assessment_report', compact('title', 'program'));
    }


    /*public function professorAssessmentReports()
    {
        $semesters = Session::get('semesters_ids');
        $semesters = DB::table('semesters')->whereIn('id', $semesters)->orderBy('start', 'ASC')->first();
        Log::info($semesters->start);
        $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();

        Log::info($outcomes);
        $title = "My Courses' Assessment Reports";

        return View::make('local.professors.assessment_reports', compact('title', 'outcomes'));
    }*/


    // Report for a single professor //with a single learning outcome
    public function professorAssessmentReport()
    {
        //$outcome = Outcome::find($outcome_id);

        //if (!$outcome)
        set_time_limit(0);
        //    App::abort('404');
        $title = "My Courses' Assessment Report";
        //$activity_criterion = DB::table('assessments')->lists('activity_criterion_id');
        $courses = DB::table("courses")
            ->join('activities', 'activities.course_id', '=', 'courses.id')
            ->join('activity_criterion', 'activity_criterion.activity_id', '=', 'activities.id')
            ->join('assessments', 'assessments.activity_criterion_id', '=', 'activity_criterion.id')
            //->whereIn('activity_criterion.id', $activity_criterion)
            ->where('courses.user_id', '=', Auth::user()->id)
            ->where('activities.draft', '=', 0)
            ->where('activities.diagnostic', 0)
            ->whereIn('courses.semester_id', Session::get('semesters_ids'))
            ->groupBy(array('code', 'number'))
            ->get();
        /*$courses = Course::has('activites')
            ->join('activity_criterion', 'activity_criterion.activity_id', '=', 'activities.id')
            ->where('user_id', Auth::user()->id)
            ->where('activities.draft', '=', 0)
            ->whereIn('semester_id', Semester::get('semester_ids'))
            ->whereIn('activity_criterion.id', $activity_criterion)
            ->groupBy(array('code', 'number'))
            ->get();*/

        /*$courses = Course::where('user_id', Auth::user()->id)
            ->has('activities')
            //->whereNotNull('outcomes_attempted')
            ->whereIn('semester_id', Session::get('semesters_ids'))
            ->groupBy(array('code', 'number'))
            ->get();*/




        return View::make('local.professors.new_assessment_report', compact('title', 'courses'));
    }

    public function annualReport($program_id)
    {
        $title = "Program Annual Report";


        $annual_plans = DB::select("
    
        select 
          academic_year, 
          semester_start, 
          semester_end, 
          program_id, 
          annual_plans.id as annual_id,
          annual_cycle.*
        from annual_plans 
        join annual_cycle on annual_cycle_id = annual_cycle.id 
        where program_id = {$program_id} 
        
        
          order by semester_start desc");
        $program = DB::table('programs')
            ->where('id', $program_id)
            ->first();


        return View::make('local.managers.shared.annual_report', compact('title', 'program_id', 'annual_plans', 'program'));
    }
}