<?php

namespace App\Modules\Hr\controllers\api\v1;

use Illuminate\Support\Facades\Response;
use Illuminate\Support\Facades\Auth;
use Exception;
use Illuminate\Support\Facades\DB;
use Carbon\Carbon;
use App\Exceptions\PermissionDeniedException;
use Illuminate\Http\Request;
use App\Http\Controllers\BaseController;
use App\Modules\Hr\TimeLogChangeRequest;
use App\Modules\Hr\TimeLog;

class TimeLogChangeRequestsControllerREST extends BaseController
{
    public function index(Request $request)
    {
        // This function requires management access
        if (! Auth::user()->hasPermission('access_hr')) {
            throw new PermissionDeniedException();
        }

        $query = TimeLogChangeRequest::query()->with('time_log', 'user');

        if ($request->input('open') && $request->input('open') != 'false') {
            $query->where('completed', 0);
        }

        // Paginate the results
        $query = $query->paginate($request->input('limit', 100));

        // Prepare the response
        $response = [
            'data'         => $query->getCollection()->toArray(),
            'total'        => $query->total(),
            'current_page' => $query->currentPage(),
            'last_page'    => $query->lastPage(),
            'per_page'     => $query->perPage(),
            'from'         => $query->firstItem(),
            'to'           => $query->lastItem(),
        ];

        // Return the response
        return $response;
    }

    public function store(\App\Http\Requests\StoreTimeLogChangeRequest $request)
    {
        // We are fetching the log that we are trying to change
        $log = TimeLog::findOrFail($request->input('time_log_id'));

        if ($log && $log->user_id != Auth::user()->id) {
            throw new Exception('You do not have access to this time log');
        }

        $request = TimeLogChangeRequest::create($request->only('time_log_id', 'time', 'type'));

        if (! $request->exists) {
            return Response::json(['errors' => $request->errors->all()], 400);
        }

        // We update the time log pending_change_request value to true
        if ($request->time_log) {
            $request->time_log->pending_change_request = 1;
            $request->time_log->save();
        }

        return $request;
    }

    /**
     * Updates a change request.
     *
     * @return [type] [description]
     */
    public function update(Request $request, $id)
    {
        // This function requires management access
        if (! Auth::user()->hasPermission('access_hr')) {
            throw new PermissionDeniedException();
        }

        $requestModel = TimeLogChangeRequest::findOrFail($id);

        // If the request has already been completed then there is no further action that can be taken
        if ($requestModel->completed == 1) {
            throw new Exception('This request has already been completed.');
        }

        $requestModel->fill($request->only('completed', 'declined'));

        // Store the time only if it exists otherwise the system will automatically set it to the current date
        if ($request->has('time')) {
            $requestModel->time = Carbon::parse($request->input('time'))->toDateTimeString();
        }

        // We will use database transactions
        // everything will save or nothing...
        DB::beginTransaction();

        // If the request was declined then we don't want to do anything
        // other than saving the state...
        if ($requestModel->declined == 0 && $requestModel->completed == 1) {
            $log = $requestModel->time_log()->first();
            $log->time = $requestModel->time;
            $log->pending_change_request = 0;
            $log->new_record_request = 0;
            if (! $log->save()) {
                DB::rollback();

                return Response::json(['errors' => $log->errors->all()], 400);
            }
        }
        // If a request has been declined it should also be marked as completed.
        elseif ($requestModel->declined == 1 && $requestModel->completed == 0) {
            $requestModel->completed = 1;
        }

        // Save the new state
        if (! $requestModel->save()) {
            DB::rollback();

            return Response::json(['errors' => $requestModel->errors->all()], 400);
        }

        // Commit the changes
        DB::commit();

        return $requestModel;
    }
}
