<?php

namespace App\Http\Controllers\Web;

use App\Country;
use App\Course;
use App\Evaluate;
use App\Hotel;
use App\Helpers\ImageHelper;
use App\Http\Requests\EvaluateRequest;
use App\Http\Requests\UserRegisterRequest;
use App\Http\Requests\UserUpdateProfileRequest;
use App\Jobs\CodeVerificationJob;
use App\Order;
use App\Region;
use App\Reservation;
use App\User;
use App\UserCourse;
use App\UsersNotification;
use App\Verification;
use Illuminate\Contracts\View\Factory;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\RedirectResponse;
use Illuminate\Routing\Redirector;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator;
use Illuminate\Http\Request;
use App\Http\Requests\LoginRequest;
use Illuminate\Support\Facades\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Route;
use Illuminate\Validation\ValidationException;
use Illuminate\View\View;
use PHPUnit\Framework\Constraint\Count;

class UserController extends Controller
{

    protected $view = 'web.members.users.';
    protected $passwordView = 'web.members.password.';

    /**
     * User profile
     * @return Factory|View
     * @throws \Exception
     */
    public function index()
    {
        $user = Auth::user();
        if (!in_array($user->role, ['user'])){
            return  abort(404);
//            return redirect()->route('home');
        }

        $country = Country::withDescription($user->country_id);
        $state = Region::withDescription(null, $user->state_id);
        $countries = Country::withDescription();
        $states = Region::withDescription($user->country_id);
        $title = __('members.my_profile');

        $reservations = Reservation::userReservations(null, null, null, null, $user->id)->groupBy('re_status');
        $dailyReservations = Reservation::userReservations('daily');

        $notifications = UsersNotification::orderBy('id', 'DESC')
            ->where('user_id', $user->id)
            ->orWhere('user_id', null)
            ->cursor();

        $notificationsCount = [];

        $allNotifications = $notifications->pluck('is_read')->toArray();

        foreach ($allNotifications as $allNotification) {
            if (is_array($allNotification) && !in_array($user->id, $allNotification)){
                $notificationsCount[] = true;
            }
            if (!is_array($allNotification)){
                $notificationsCount[] = true;
            }

        }

        $notificationsCount = count($notificationsCount);


        return view($this->view.'profile', compact(
            'user',
            'notifications',
            'notificationsCount',
            'reservations',
            'dailyReservations',
            'countries',
            'country',
            'state',
            'states',
            'title'
        ));
    }

    public function hallEvaluate(EvaluateRequest $request)
    {

        $user = Auth::user();
        $hall = Hotel::find($request->hall_id);
        $reservation = Reservation::find($request->reservation_id);
        $evaluate = Evaluate::where('hall_id', $hall->id)->where('user_id', $user->id)->first();

        if (!$hall){
            return response()->json(['errors' => __('halls.hall_not_found')]);
        }
        if (!$reservation){
            return response()->json(['errors' => __('halls.reservation_not_found')]);
        }
        if ($hall->id != $reservation->hall_id || $reservation->user_id != $user->id){
            return response()->json(['errors' => __('halls.evaluate_not_allowed')]);
        }
        if ($reservation->re_status != 'finished' || $evaluate){
            return response()->json(['errors' => __('halls.evaluate_not_allowed')]);
        }

        $data = $request->all();

        $data['cleaning'] = $request->cleaning ?? 0 ;
        $data['services'] = $request->services ?? 0 ;
        $data['staffs'] = $request->staffs ?? 0 ;
        $data['comforts'] = $request->comforts ?? 0 ;
        $data['financial_value'] = $request->financial_value ?? 0 ;
        $data['location'] = $request->location ?? 0 ;


        $evaluate_average = ($data['cleaning']+$data['services']+$data['staffs']+$data['comforts']+$data['financial_value']+$data['location'])/6;

        Evaluate::create([
            'comment' => $request->comment,
            'evaluate_average' => round($evaluate_average),
            'evaluate_details' => [
                'cleaning' => $data['cleaning'],
                'services' => $data['services'],
                'staffs' => $data['staffs'],
                'comforts' => $data['comforts'],
                'financial_value' => $data['financial_value'],
                'location' => $data['location'],
            ],
            'user_id' => $user->id,
            'hall_id' => $hall->id,
        ]);

        $reservation->update(['is_evaluate' => 1]);
        $evaluates = Evaluate::where('hall_id', $hall->id);
        $rate = $evaluates->sum('evaluate_average')/$evaluates->count();
        $hall->update(['rate' => $rate]);

        return response()->json(['message' => __('halls.evaluate_successfully')]);

    }

    public function refreshNotification(Request $request)
    {
        if ($request->ajax()){
            $user = Auth::user();
            $courses = $user->courses()->pluck('course_id')->toArray();
            $notifications = UsersNotification::orderBy('id', 'DESC')
                    ->orWhere('user_id', $user->id)
                    ->orWhereIn('send_to', ['all_users'])
                    ->orWhereIn('course_id', $courses)
                    ->cursor() ?? [];
            $notificationsCount = $notifications->count();
            return view($this->view.'refresh_notification', compact('notifications', 'notificationsCount', 'user'));
        }
    }

    public function markAsRead()
    {
        $user = Auth::user();
        $notifications = UsersNotification::orderBy('id', 'DESC')
            ->where('user_id', $user->id)
            ->orWhere('user_id', null)
            ->cursor();

        foreach ($notifications as $notification) {
            $isRead = $notification->is_read;
            if (is_array($isRead)){
                if (!in_array($user->id, $isRead)){
                    array_push($isRead, $user->id);
                }
            } else {
                $isRead = [$user->id];
            }
            $notification->update(['is_read' => $isRead]);
        }

        return response()->json(['success' => true]);
    }

    public function updateProfile(UserUpdateProfileRequest $request, User $user)
    {
        $data = $request->all();
        $data['password'] = $request->password ? bcrypt($request->password) : $user->password;
        if ($request->has('photo')){
            if (file_exists(public_path().'/'.$user->photo)){
                File::delete(public_path().'/'.$user->photo);
            }
            $data['photo'] = ImageHelper::upload($request->photo, 'users/profile');
        }

        $data['email_receive'] = $request->email_receive ? $request->email_receive : 0;

        $user->update($data);

        return response()->json(['message' => __('members.save_successfully')]);
    }

    public function reservationSearch(Request $request)
    {
        if ($request->ajax()){
            $user = Auth::user();
            $reservations = Reservation::userReservations(null, $request->re_date_from, $request->re_date_to, $request->re_no, $user->id);
            return view($this->view.'reservation_search', compact('reservations', 'user'));
        }
    }


    /**
     * Show register form for user
     * @return Factory|RedirectResponse|View
     */
    public function register()
    {
        $countryCods = Country::withDescription()->pluck('code')->toArray();
        return view($this->view.'register', compact('countryCods'));
    }

    /**
     * Register new user
     * @param UserRegisterRequest $request
     * @return JsonResponse
     */
    public function doRegister(UserRegisterRequest $request)
    {
        $data = $request->all();
        $data['password'] = bcrypt($request->password);
        $data['role'] = 'user';
        $user = User::create($data);
        Auth::login($user);
        return response()->json(['url' =>route('home')]);
    }

    public function getState(Request $request)
    {
        if ($request->ajax()){
            $states = Region::withDescription($request->country_id);
            if (count($states)){
                return response()->json(['states' => $states]);
            } else {
                return response()->json(['states' => false]);
            }
        }
    }


}
