<?php


namespace App\Repositories;


use App\Exercise;
use App\TrainingSession;
use App\TrainingWorkoutSection;
use App\TrainingWorkout;
use App\TrainingWorkoutLine;
use App\User;
use App\UserBenchmark;
use App\UserBenchmarkLine;
use Illuminate\Support\Facades\DB;

class TrainingWorkoutRepository implements RepositoryInterface
{
    public static function all() {
        return TrainingWorkout::all();
    }

    public static function create(array $data)
    {
        //Ja s'ha hagut de comprovar que es admin si en crea un sense box_id....

        if(!isset($data["training_workout_sections"])) throw new \Exception("Añade alguna sección al entrenamiento!");
        $sections = $data["training_workout_sections"];
        unset($data["training_workout_sections"]);

        DB::beginTransaction();
        try {
            $workout = TrainingWorkout::create($data);

            foreach ($sections as $section) {
                if(!isset($section["lines"])) throw new \Exception("Añade algun ejercicio a la sección vacía!");
                $lines = $section["lines"];
                unset($section["lines"]);

                $section["training_workout_id"] = $workout->id;
                $createdSection = TrainingWorkoutSection::create($section);

                foreach ($lines as $line) {
                    $line['training_workout_section_id'] = $createdSection->id;
                    TrainingWorkoutLine::create($line);
                }
            }
        }
        catch(\Exception $e) {
            DB::rollBack();
            throw $e;
        }
        DB::commit();

        return TrainingWorkout::find($workout->id);
    }

    public static function update(array $data, $id)
    {
        DB::beginTransaction();
        try {
            $sections = isset($data["training_workout_sections"]) ? $data["training_workout_sections"] : [];
            if(isset($data["training_workout_sections"])) unset($data["training_workout_sections"]);

            // Mirem si ja te resultats
            $workout = TrainingWorkout::find($id);

            $workout->update($data);

            // Borrem linies
            foreach ($workout->trainingWorkoutSections as $ts) {
                $ts->lines()->delete();
            }

            // Borrem seccions
            $workout->trainingWorkoutSections()->delete();

            foreach ($sections as $section) {
                $section["training_workout_id"] = $workout->id;

                $createdSection = TrainingWorkoutSection::create($section);

                foreach ($section['lines'] as $line) {
                    $line['training_workout_section_id'] = $createdSection->id;
                    $createdLine = TrainingWorkoutLine::create($line);
                }
            }
        }
        catch(\Exception $e) {
            DB::rollBack();
            throw $e;
        }

        DB::commit();

        return TrainingWorkout::find($workout->id);
    }

    public static function delete($id)
    {
        $workout = TrainingWorkout::find($id);
        // Borrem linies
        foreach ($workout->trainingWorkoutSections as $ts) {
            $ts->lines()->delete();
        }
        // Borrem seccions
        $workout->trainingWorkoutSections()->delete();

        return TrainingWorkout::destroy($id);
    }

    public static function find($id)
    {
        return TrainingWorkout::findOrFail($id);
    }

    public static function box($id)
    {
        return TrainingWorkout::findOrFail($id)->box;
    }

    public static function templates()
    {
        return TrainingWorkout::whereNull("box_id")->get();
    }

    public static function trainingWorkoutSections($id)
    {
        return TrainingWorkout::findOrFail($id)->trainingWorkoutSections;
    }

    public static function sectionTypes() {
        $t = DB::table('training_workout_sections')
            ->select('type')
            ->groupBy('type')
            ->get();

        $types = [];

        foreach ($t as $item) {
            array_push($types,$item->type);
        }

        return $types;
    }

    public static function available($params) {
        $user_id = $params['user_id'];
        /*      APLICAR EN TRAINING WORKOUT     */
        $sort_dir = $params['sort_dir'];
        $sort_col = $params['sort_col'];
        $name = $params['name'];
        $favorites = $params['favorites'];
        $category = $params['category'];
        /*      APLICAR EN TRAINING WORKOUT SECTION     */
        $seconds = $params['seconds'];
        $section_types = $params['section_types'];
        /*      APLICAR EN TRAINING WORKOUT LINE - EXERCISE     */
        $exercise_types = $params['exercise_types'];
        $difficulty = $params['difficulty'];
        $equipment = $params['equipment'];

        $boxes_ids = User::find($user_id)->boxes_id();

        $training_workouts_1 = TrainingWorkout::where(function($q) use ($boxes_ids) {
            $q->whereIn('training_workouts.box_id', $boxes_ids)
                ->orWhereNull('training_workouts.box_id');
        })->where(function($n) use ($name) {
            $n->where('training_workouts.name','LIKE','%'.$name.'%')
                ->orWhere('training_workouts.name','LIKE',$name.'%')
                ->orWhere('training_workouts.name','LIKE','%'.$name);
        })->where(function($c) use ($category) {
            $c->where('training_workouts.category','LIKE','%'.$category.'%')
                ->orWhere('training_workouts.category','LIKE',$category.'%')
                ->orWhere('training_workouts.category','LIKE','%'.$category);
        })->where(function($f) use ($category, $favorites, $user_id) {
            if ($favorites) {
                $f->whereIn('id',User::find($user_id)->favorite_workouts_ids);
            }
        })->orderBy($sort_col,$sort_dir)->get();



        $training_workouts_2 = [];
        if($seconds!=null || $section_types!=null || $exercise_types!=null || $equipment!=null) {
            foreach ($training_workouts_1 as $tw) {
                $s = 0;
                $hasType = true;
                $difficultyExercise = true;
                $containsExerciseType = false;
                $containsEquipmentType = false;
                foreach ($tw->trainingWorkoutSections as $tws) {
                    $s = $s + ($tws->seconds!=null ? $tws->seconds : 0);
                    $hasType = $hasType ? ($section_types!=null ? in_array($tws->type,$section_types) : true) : false;

                    if($hasType && ($seconds!=null ? $s<=(int)$seconds : true)) { // Val la pena continuar baixant de nivell
                        foreach ($tws->lines as $twl) {
                            $exercise = Exercise::find($twl->exercise_id);
                            $difficultyExercise = $difficultyExercise ? ($exercise->level<=(int)$difficulty) : false;
                            if ($exercise_types!=null && !$containsExerciseType && $exercise->type!=null) {
                                $containsExerciseType = array_intersect(explode(', ',$exercise->type),$exercise_types);
                            } else $containsExerciseType = true;
                            if ($equipment!=null && !$containsEquipmentType && $exercise->equipment_type!=null) {
                                $containsEquipmentType = array_intersect(explode(', ',$exercise->equipment_type),$equipment);
                            } else $containsEquipmentType = true;
                        }
                    }
                }
                if($hasType && ($seconds!=null ? $s<=(int)$seconds : true) && $difficultyExercise && $containsExerciseType && $containsEquipmentType) {
                    array_push($training_workouts_2,$tw);
                }
            }
        } else $training_workouts_2 = $training_workouts_1;

        return $training_workouts_2;
    }
}
