<?php


namespace App\Repositories;


use App\Notifications\FreeSiteNotification;
use App\TrainingSession;
use App\User;
use Carbon\Carbon;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Session;

class TrainingSessionRepository implements RepositoryInterface
{
    public static function all() {
        return TrainingSession::all();
    }

    public static function create(array $data){
        $ts = TrainingSession::create($data);
        return self::find($ts->id);
    }

    public static function update(array $data, $id){
        TrainingSession::findOrFail($id)->update($data);
        return TrainingSession::findOrFail($id);
    }

    public static function delete($id){
        return TrainingSession::destroy($id);
    }

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

    public static function users($id){
        return TrainingSession::findOrFail($id)->users;
    }

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

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

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

    public static function userBenchmarks($id) {
        return TrainingSession::findOrFail($id)->userBenchmarks;
    }

    public static function join($id_session, $id_user){
        $user = UserRepository::find($id_user);

        // Sessions dels boxes als quals te una subscripció
        $availableWorkoutSessionsId  = $user->availableWorkoutSessionsId();

        $session = TrainingSession::find($id_session);

        $box = $session->box_id;

        $enoughtCredits = $session->capacity()>0 ? UserRepository::cobrarCredits($session,$box,$id_user) : false;

        if(in_array($id_session,$availableWorkoutSessionsId)!=false && $session->capacity()>0 && $enoughtCredits){
            $user = UserRepository::find($id_user);
            $availableToJoin = $user->availableWorkoutSessionsId();
            $availableToLeave = $user->availableWorkoutSessionsToLeaveId();
            return self::transformWithStatus($user,TrainingSessionRepository::find($id_session),$availableToJoin,$availableToLeave);
        }else {
            //2.2. Retornem un missatge d'error en cas de no poder
            if ((in_array($id_session,$availableWorkoutSessionsId)==false)) {
                return "No puedes apuntarte a esta sesion, no estas apuntado a este box o es demasiado pronto";
            } else if ($session->capacity()<=0) {
                UserRepository::joinToNotifyTrainingsession($id_user,$id_session);
                $user = UserRepository::find($id_user);
                $availableToJoin = $user->availableWorkoutSessionsId();
                $availableToLeave = $user->availableWorkoutSessionsToLeaveId();
                return self::transformWithStatus($user,TrainingSessionRepository::find($id_session),$availableToJoin,$availableToLeave);
            } else {
                return "No puedes apuntarte a esta sesion";
            }
        }
    }

    public static function leave($id_session, $id_user){
        $user = UserRepository::find($id_user);

        // Sessions dels boxes als quals te una subscripció
        $availableWorkoutSessionsId  = $user->availableWorkoutSessionsToLeaveId();

        $session = TrainingSession::find($id_session);

        $box = $session->box_id;

        $canReturnCredits = !$session->credits || UserRepository::retornarCredits($session,$box,$id_user);

        if(in_array($id_session,$availableWorkoutSessionsId)!=false && $canReturnCredits){
            $user = UserRepository::find($id_user);
            $availableToJoin = $user->availableWorkoutSessionsId();
            $availableToLeave = $user->availableWorkoutSessionsToLeaveId();
            if (TrainingSession::find($id_session)->capacity()>0) TrainingSessionRepository::notifyAllUsersWaiting($id_session);
            return self::transformWithStatus($user,TrainingSessionRepository::find($id_session),$availableToJoin,$availableToLeave);
        }else {
            if (!(in_array($id_session,$availableWorkoutSessionsId)!=false)) {
                return "No puedes desapuntarte de esta sesion, no estas apuntado a este box o ya es demasiado tarde";
            } else return "No puedes desapuntarte de esta sesion";
        }
    }

    public static function notifyAllUsersWaiting($id_session) {
        $trainingSession = TrainingSessionRepository::find($id_session);
        foreach ($trainingSession->usersToNotify as $user) {
            $params = [
                "title" => "Hay un hueco libre, entra en la app para reservar ya... Vamos! No te quedes sin ella",
                "user_id" => $user->id
            ];

            $trainingSession->usersToNotify()->detach($user->id);

            NotificationRepository::sendNotification($params);
        }
    }

    public static function transformWithStatus($user,$training_session,$availableToJoin,$availableToLeave) {
        $currentDate = Carbon::now();

        if (in_array($training_session->id,$availableToJoin)) {
            if($training_session->capacity <= count($training_session->users) && $user->one_signal_player_id!=null){ // La capacidad esta llena
                $n = DB::table('notify_user_training_sessions')
                    ->where('user_id','=',$user->id)
                    ->where('training_session_id','=',$training_session->id)
                    ->first();
                if ($n!=null) $training_session->state = "waiting";
                else $training_session->state = "notify";
            } else $training_session->state = "join"; // Se puede apuntar
        } else if (array_search($training_session->id,$availableToLeave)) { // Se puede desapuntar
            $training_session->state = "leave";
        } else if (Carbon::createFromFormat('Y-m-d H:i:s',$training_session->date_start) <= $currentDate
            && $currentDate <= Carbon::createFromFormat('Y-m-d H:i:s',$training_session->date_end)) { // Esta ahora en curso
            $training_session->state = "now";
        } else if($currentDate < Carbon::createFromFormat('Y-m-d H:i:s',$training_session->date_end)) { // Aun no es posible apuntarse
            if ($user->trainingSessions->contains($training_session->id)) $training_session->state = "joined";
            else $training_session->state = "future";
        } else if(Carbon::createFromFormat('Y-m-d H:i:s',$training_session->date_start) <= $currentDate) { // Ya se ha hecho esta clase
            if (($training_session->users)->contains($user->id)) { // El atleta ha hecho esta clase
                $ub = DB::table('user_benchmarks')->where('user_id','=',$user->id)->where('training_session_id','=',$training_session->id)->first();
                if ($ub) { // El atleta ha entrado resultado
                    $training_session->state = "benchmark";
                    $training_session->benchmark = UserBenchmarkRepository::find($ub->id);
                } else {
                    $training_session->state = "done";
                }
            } else $training_session->state = "past";
        } else {
            $training_session->state = "disabled";
        }

        return $training_session;
    }

}
