<?php

namespace App\Http\Controllers;

use Carbon\Carbon;
use Illuminate\Http\Request;
use App\Repositories\BoxRepository;

class BoxController extends Controller {

    /**
     * Pre: --
     * Post: Injecta les dependències de BoxRepository
     */
    public function __construct() {
        $this->middleware('auth:api', ['except' => ['pricings']]);
    }

    /**
     * @param Request $request
     * @return Retorna un JSON amb un array de Box.
     *
     * Si ets SUPERADMIN:
     *  - I no passes company_id: Et retorna tots els boxes.
     *  - Passes un company_id: Et retorna els boxes d'aquella empresa.
     * Si ets un COMPANY ADMIN:
     *  - No passes mai un company_id. Et retorna els boxes.
     * Si ets un BOX ADMIN:
     *  - No passes mai un company_id. Et retorna el teu box, dins un array de size 1.
     * Si ets un COACH:
     */
    public function index(Request $request){
        //1. Obtenim query parameters opcionals

        //2. Autoritzem
        auth()->user()->authorize("super_admin");

        //3. Obtenim el resultat
        try {
            $boxes = BoxRepository::index();
        }
        catch(\Exception $e) { return response()->json(["error" => $e->getMessage()], 400); };

        return response()->json($boxes,200);
    }

    public function show($id){
        try {
            //1. Sense query parametres

            //2. Autoritzem
            auth()->user()->authorize("athlete", $id);

            //3. Obtenim el resultat
            $box = BoxRepository::find($id);
        }
        catch(\Exception $e) { return response()->json(["error" => $e->getMessage()], 400); };

        return response()->json($box,200);
    }

    public function update($id,Request $request) {
        //1. Query parameters - no en té

        //2. Autoritzem
        auth()->user()->authorize("box_admin", $id);

        //3. Obtenim resultat
        try {
            $box = BoxRepository::update($request->all(),$id);
        }
        catch(\Exception $e) { return response()->json(["error" => $e->getMessage()], 400); };

        return response()->json($box,200);
    }

    public function create(Request $request){
        //1. Query parameters
        $company_id = $request->company_id;

        //2. Autoritzem
        auth()->user()->authorize("company_admin", $company_id);

        //3. Obtenim
        try {
            $box = BoxRepository::create($request->all());
        }
        catch(\Exception $e) { return response()->json(["error" => $e->getMessage()], 400); };

        return response()->json($box,200);
    }

    public function destroy($id){
        //1. Query parameters - no en té
        $company_id = BoxRepository::find($id)->company_id;

        //2. Autoritzem
        auth()->user()->authorize("company_admin", $company_id);

        //3. Executem acció
        try {
            BoxRepository::delete($id);
        }
        catch(\Exception $e) { return response()->json(["error" => $e->getMessage()], 400); };

        return response()->json("OK",200);
    }

    public function users(Request $request, $id){
        //1. Query parameters. No en té
        $active = $request->query("active") == "Y";
        $company_id = BoxRepository::find($id)->company->id;

        //2. Authorize
        auth()->user()->authorize("company_admin", $company_id);

        //3. Executem acció
        try {
            $users = BoxRepository::users($id, $active);
        }
        catch(\Exception $e) { return response()->json(["error" => $e->getMessage()], 400); };

        return response()->json($users,200);
    }

    public function userSubscriptions(Request $request, $id) {
        //1. query

        //2. Authorize
        auth()->user()->authorize("coach", $id);

        try {
            $user_subscriptions = BoxRepository::userSubscriptions($id, $request->query());
        }
        catch(\Exception $e) { return response()->json(["error" => $e->getMessage()], 400); };

        return response()->json($user_subscriptions,200);
    }

    public function trainingRooms(Request $request, $id) {
        //1. parameters

        //2. Authorize
        auth()->user()->authorize("coach", $id);

        try {
            $tr = BoxRepository::trainingRooms($id);
        }
        catch(\Exception $e) { return response()->json(["error" => $e->getMessage()], 400); };

        return response()->json($tr, 200);
    }

    public function calendarTemplates(Request $request, $id){
        //1. parameters

        //2. authorize
        auth()->user()->authorize("coach", $id);

        //3. fetch
        try {
            $cts = BoxRepository::calendarTemplate($id);
        }
        catch(\Exception $e) { return response()->json(["error" => $e->getMessage()], 400); };

        return response()->json($cts,200);
    }

    public function trainingSessions(Request $request, $id) {
        //1. parameters
        $date_start = $request->query("date_start");
        $date_end = $request->query("date_end");
        $training_room_id = $request->query('training_room_id');

        //2. authorize
        auth()->user()->authorize("athlete", $id);

        try {
            $cw = BoxRepository::trainingSessions($id, $training_room_id, $date_start, $date_end);
        }
        catch(\Exception $e) { return response()->json(["error" => $e->getMessage()], 400); };

        return response()->json($cw, 200);
    }

    public function company($id) {
        //1. parameters

        //2. authorize
        auth()->user()->authorize("box_admin", $id);

        try {
            $company = BoxRepository::company($id);
        }
        catch(\Exception $e) { return response()->json(["error" => $e->getMessage()], 400); };

        return response()->json($company, 200);
    }

    public function coaches($id) {
        //1. parameters

        //2. authorize
        auth()->user()->authorize("athlete", $id);

        try {
            $coaches = BoxRepository::coachesActive($id);
        }
        catch(\Exception $e) { return response()->json(["error" => $e->getMessage()], 400); };

        return response()->json($coaches, 200);
    }

    public function usersCanBeCoaches($id) {
        auth()->user()->authorize("athlete", $id);

        try {
            $coaches = BoxRepository::usersCanBeCoaches($id);
        }
        catch(\Exception $e) { return response()->json(["error" => $e->getMessage()], 400); };

        return response()->json($coaches, 200);
    }

    public function workouts(Request $request, $id) {
        //1. parameters
        $filter_name = $request->query('name');
        $filter_category = $request->query('category');
        $filters = [];
        if($filter_name != null) $filters['name'] = $filter_name;
        if($filter_category != null) $filters['category'] = $filter_category;

        if($request->query('sort_col') != null) $sort_col = $request->query('sort_col');
        else $sort_col = 'name';
        if($request->query('sort_dir') != null) $sort_dir = $request->query('sort_dir');
        else $sort_dir = 'asc';

        //2. authorize
        auth()->user()->authorize("athlete", $id);

        try {
            $workouts = BoxRepository::workouts($id, $filters,$sort_col,$sort_dir);
        }
        catch(\Exception $e) { return response()->json(["error" => $e->getMessage()], 400); };

        return response()->json($workouts, 200);
    }

    public function workoutTypes(Request $request, $id) {
        //Authorize
        auth()->user()->authorize("athlete", $id);

        try {
            $types = BoxRepository::trainingWorkoutTypes($id);
        }
        catch(\Exception $e) { return response()->json(["error" => $e->getMessage()], 400); };

        return response()->json($types, 200);
    }

    public function news(Request $request, $id) {
        //1. parameters

        //2. authorize
        auth()->user()->authorize("athlete", $id);

        try {
            $news = BoxRepository::news($id, $request->query());
        }
        catch(\Exception $e) { return response()->json(["error" => $e->getMessage()], 400); };

        return response()->json($news, 200);
    }

    public function getLastNew(Request $request, $id) {
        //1. parameters

        //2. authorize
        auth()->user()->authorize("athlete", $id);

        //3.
        try {
            $new = BoxRepository::getLastNew($id);
        }
        catch(\Exception $e) { return response()->json(["error" => $e->getMessage()], 400); };

        return response()->json($new, 200);
    }

    public function generateCalendar(Request $request, $id) {
        //1. parameters
        $start_date = Carbon::parse($request->start_date);
        $end_date = Carbon::parse($request->end_date);
        $calendar_template_id = $request->calendar_template_id;
        $training_room_id = $request->training_room_id;
        $coach_id = $request->coach_id;
        $training_type_id = $request->training_type_id;

        if(!$start_date || !$end_date || !$calendar_template_id || !$training_room_id) return response()->json(["error"=>"Please provide all required parameters."], 400);

        //2. Authorize
        auth()->user()->authorize("coach", $id);

        //3. generate
        try {
            $sessions = BoxRepository::generateSessions($id, $start_date, $end_date, $calendar_template_id, $training_room_id, $training_type_id, $coach_id);
        }
        catch(\Exception $e) { return response()->json(["error" => $e->getMessage()], 400); };

        return response()->json($sessions, 200);
    }

    public function sessionsBulkEditWorkouts(Request $request, $id) {
        //1. Parameters

        //2. authorize
        auth()->user()->authorize("coach", $id);

        //3. bulk edit
        try {
            $sessions = BoxRepository::sessionsBulkEditWorkouts($id, $request->all());
        }
        catch(\Exception $e) { return response()->json(["error" => $e->getMessage()], 400); };

        return response()->json($sessions);
    }

    public function pricings(Request $request, $id) {
        //1. Parameters

        //2. authorize
        $public = $request->query("is_public");
        if($public==null || $public==false) {
            auth()->user()->authorize("coach", $id);
        }

        //3. bulk edit
        try {
            $pricings = BoxRepository::pricings($id, $request->query());
        }
        catch(\Exception $e) { return response()->json(["error" => $e->getMessage()], 400); };

        return response()->json($pricings);
    }

    public function settings(Request $request, $id) {
        //1. parameters
        $company_id = BoxRepository::find($id)->company_id;

        //2. authorize
        auth()->user()->authorize("company_admin", $company_id);

        //3. get
        try {
            $settings = BoxRepository::settings($id);
        }
        catch(\Exception $e) { return response()->json(["error" => $e->getMessage()], 400); };

        return response()->json($settings);
    }

    public function updateSettings(Request $request, $id) {
        //1. parameters
        $company_id = BoxRepository::find($id)->company_id;

        //2. authorize
        auth()->user()->authorize("company_admin", $company_id);

        //3. get
        try {
            $settings = BoxRepository::updateSettings($id, $request->all());
        }
        catch(\Exception $e) { return response()->json(["error" => $e->getMessage()], 400); };

        return response()->json($settings);
    }

    public function assistance(Request $request, $box_id, $user_id) {
        //1. parameters

        //2. authorize
        if(!auth()->user()->itsMe($user_id)) {
            auth()->user()->authorize("coach", $box_id);
        }

        //3. get
        try {
            $data = BoxRepository::getUserAssistance($box_id, $user_id, $request->query());
        }
        catch(\Exception $e) { return response()->json(["error" => $e->getMessage()], 400); };

        return response()->json($data);
    }

    public function userBoxOrders($box_id, $user_id) {
        //1. parameters

        //2. authorize
        if(!auth()->user()->itsMe($user_id)) {
            auth()->user()->authorize("box_admin", $box_id);
        }

        //3. Get
        try {
            $data = BoxRepository::getUserBoxOrders($box_id, $user_id);
        }
        catch(\Exception $e) { return response()->json(["error" => $e->getMessage()], 400); };

        return response()->json($data);
    }

    public function lastSessionBenchmark(Request $request, $box_id, $user_id) {
        //1. parameters

        //2. authorize
        if(!auth()->user()->itsMe($user_id)) {
            auth()->user()->authorize("coach", $box_id);
        }

        //3. get
        try {
            $data = BoxRepository::lastSessionBenchmark($box_id, $user_id, $request->query());
        }
        catch(\Exception $e) { return response()->json(["error" => $e->getMessage()], 400); };

        return response()->json($data);
    }

    public function nextTrainingSession(Request $request, $box_id, $user_id) {
        //1. parameters

        //2. authorize
        if(!auth()->user()->itsMe($user_id)) {
            auth()->user()->authorize("coach", $box_id);
        }

        //3. get
        try {
            $data = BoxRepository::nextTrainingSession($box_id, $user_id, $request->query());
        }
        catch(\Exception $e) { return response()->json(["error" => $e->getMessage()], 400); };

        return response()->json($data);
    }

    public function shouldTrainMore(Request $request, $box_id, $user_id) {
        //1. parameters

        //2. authorize
        if(!auth()->user()->itsMe($user_id)) {
            auth()->user()->authorize("coach", $box_id);
        }

        //3. get
        try {
            $data = BoxRepository::shouldTrainMore($box_id, $user_id);
        }
        catch(\Exception $e) { return response()->json(["error" => $e->getMessage()], 400); };

        return response()->json(["show" => $data]);
    }

    public function birthdays($id) {
        //1. parameters

        //2. authorize
        auth()->user()->authorize("athlete", $id);

        //3. get
        try {
            $users = BoxRepository::birthdays($id);
        }
        catch(\Exception $e) { return response()->json(["error" => $e->getMessage()], 400); };

        return response()->json($users);
    }
}
