<?php

namespace App\Http\Controllers\API;

use App\ConsultingEvaluate;
use App\Helpers\Notification;
use App\Http\Resources\UserResource;
use App\UmrahTrip;
use App\UsersNotification;
use Illuminate\Http\Request;
use App\UmrahTripReservation;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\DB;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Auth;
use App\Http\Resources\UmrahTripResource;
use Illuminate\Support\Facades\Validator;
use App\Http\Resources\UmrahTripReservationResource;
use App\Http\Requests\API\AddUmrahReservationRequest;

class UmrahTripController extends Controller
{

    /**
     * Get all umrah trips or by id
     * @param Request $request
     * @param null $umrah_trip_id
     * @return JsonResponse
     */
    public function umrahTrips(Request $request, $umrah_trip_id = null) :JsonResponse
    {
        $languageId = currentLanguage()->id;
        $umrahTrips = UmrahTrip::where('umrah_trips.status', 1)
            ->join('umrah_trip_descriptions as uDesc', 'uDesc.umrah_trip_id', 'umrah_trips.id')
            ->where('uDesc.language_id', $languageId);

        if ($request->sort == 'desc'){
            $umrahTrips->orderBy('umrah_trips.id', 'desc');
        }

        if ($request->sort == 'asc'){
            $umrahTrips->orderBy('umrah_trips.id', 'asc');
        }

        if ($request->sort == 'highest_price'){
            $umrahTrips->orderBy('umrah_trips.price_per_person', 'desc');
        }

        if ($request->sort == 'lowest_price'){
            $umrahTrips->orderBy('umrah_trips.price_per_person', 'asc');
        }

        if ($umrah_trip_id){
            $umrahTrips = $umrahTrips->where('umrah_trips.id', $umrah_trip_id)
                ->select([
                    'umrah_trips.*',
                    'uDesc.name',
                    'uDesc.description',
                ])->first();
            if (!($umrahTrips->status ?? null)){
                return response()->json(['message' => __('umrahTrips.umrah_trip_not_active'), 'data' => null], 401);
            }
        } else {
            $umrahTrips = $umrahTrips->select([
                'umrah_trips.*',
                'uDesc.name',
                'uDesc.description',
            ])->cursor();
        }

        $umrahTrips = $umrah_trip_id ? UmrahTripResource::make($umrahTrips) : UmrahTripResource::collection($umrahTrips);
        return response()->json(['message' => '', 'data' => $umrahTrips], 200);
    }

    /**
     * Umrah trip search
     * @param Request $request
     * @return JsonResponse
     */
//    public function search(Request $request)
//    {
//        $languageId = currentLanguage()->id;
//        $umrahTrips = UmrahTrip::where('umrah_trips.status', 1)
//            ->join('umrah_trip_descriptions as uDesc', 'uDesc.umrah_trip_id', 'umrah_trips.id')
//            ->where('uDesc.language_id', $languageId);
//
//        if ($request->sort == 'highest_rate'){
//            $umrahTrips->orderBy('umrah_trips.rate', 'desc');
//        }
//
//        if ($request->sort == 'lowest_rate'){
//            $umrahTrips->orderBy('umrah_trips.rate', 'asc');
//        }
//
//        if ($request->sort == 'highest_price'){
//            $umrahTrips->orderBy('umrah_trips.price_per_person', 'desc');
//        }
//
//        if ($request->sort == 'lowest_price'){
//            $umrahTrips->orderBy('umrah_trips.price_per_person', 'asc');
//        }
//
//        $umrahTrips->select([
//                'umrah_trips.*',
//                'uDesc.name',
//                'uDesc.description',
//            ]);
//
//        $umrahTrips = $umrahTrips->cursor();
//
//        return response()->json(['message' => '', 'data' => UmrahTripResource::collection($umrahTrips)], 200);
//
//    }



    /**
     * Add umrah reservation foreach auth user and guest
     * @param AddUmrahReservationRequest $request
     * @param $umrah_trip_id
     * @return JsonResponse
     */
    public function addReservationForUserAndGuest(AddUmrahReservationRequest $request, $umrah_trip_id) :JsonResponse
    {

//        return response()->json(['message' => '', 'data' => $umrah_trip_id], 200);

        $data = $request->all();
        $umrah = UmrahTrip::find($umrah_trip_id);
        if (!$umrah){
            return response()->json(['message' => __('umrahTrips.umrah_trip_not_found'), 'data' => null], 401);
        }
        if (!$umrah->status){
            return response()->json(['message' => __('umrahTrips.umrah_trip_not_active'), 'data' => null], 401);
        }

        if ($request->house_type == 'private' && !$umrah->house_private){
            return response()->json(['message' => __('umrahTrips.house_type_not_available'), 'data' => null], 401);
        }
        if ($request->house_type == 'group' && !$umrah->house_group){
            return response()->json(['message' => __('umrahTrips.house_type_not_available'), 'data' => null], 401);
        }

        // In auth user => escorts | in guest => person_count
        $personCount = $request->escorts ? (count($request->escorts)+1) : $request->person_count;
        if ($personCount && ($umrah->maximum_person_count < $personCount)){
            $message = __('umrahTrips.maximum_person_count_exceed');
            $message = str_replace('@@', $umrah->maximum_person_count, $message);
            return response()->json(['message' => $message, 'data' => null], 401);
        }

        $userLogged = Auth::check() ? Auth::user() : null;
        $data['name'] = $userLogged ? $userLogged->name : $request->name;
        $data['email'] = $userLogged ? $userLogged->email : $request->email;
        $code = $userLogged ? $userLogged->code : $request->code;
        $phone = $userLogged ? $userLogged->phone : $request->phone;
        $data['phone'] = $code.$phone;
        $data['user_id'] = $userLogged ? $userLogged->id : null;
        $data['umrah_trip_id'] = $umrah_trip_id;
        $data['departure_city'] = $umrah->departure_city;
        $data['arrival_city'] = $umrah->arrival_city;
        $data['price_per_person'] = $umrah->price_per_person;
        $data['person_count'] = $request->person_count ? $request->person_count : 0;
        $data['rally_point_info'] = [$request->rally_point_info => $umrah->rally_point_info[$request->rally_point_info]];
        $escorts = [];

        if ($userLogged && $request->escorts && count($request->escorts)){
            foreach ($request->escorts as $escortId) {
                if (isset($userLogged->escorts[($escortId-1)])){
                    $escorts[($escortId-1)] = $userLogged->escorts[($escortId-1)];
                } else {
                    return response()->json(['message' => '', 'data' => __('umrahTripReservations.escorts_no_valid')], 403);
                }
            }
        }



        $data['escorts'] = $escorts;
        $addedValue = array_key_exists('added_value', settings()) ? settings('added_value') : 15;
        $price = $umrah->house_private ? $umrah->house_private_price : $umrah->house_group_price;
        $total = ($price*$personCount);
        $addedValueAmount = ($total*$addedValue)/100;
        $data['total'] = $total+$addedValueAmount;
        $data['status'] = 'current';
        $data['price_per_person'] = $price;
        $data['pay_type'] = $request->pay_type;
//        return response()->json(['message' => '', 'data' => $personCount], 200);
        $umrahReservation = UmrahTripReservation::create($data);
        $umrah->update(['maximum_person_count' => ($umrah->maximum_person_count - $personCount)]);

        if ($userLogged){
            $title = __('umrahTripReservations.reservation_success_title');
            $title = str_replace('@@', descriptions($umrah)->name, $title);
            $message = __('umrahTripReservations.reservation_success_message');
            $message = str_replace('@@', descriptions($umrah)->name, $message);
            $userNotification = [
                'title' => $title,
                'message' => $message,
                'user_id' => $userLogged->id,
                'reservation_id' => $umrahReservation->id,
                'notification_type' => 'umrah',
            ];

            UsersNotification::create($userNotification);

            $notificationData['notification'] = [
                'title' => $title,
                'body' => $message,
                'page_id' => $umrahReservation->id,
                'type' => 'umrah',
                'vibrate' => 1,
                'priority' => 'high',
                'visibility'=> 1,
                'foreground'=> true,
                'no-cache' => 1,
                'force-start' => 1,
                'sound' => 'default'
            ];
            $target['to'] = $userLogged->device_token['token'];
            Notification::send($notificationData, $target);
            return response()->json([
                'message' => '',
                'data' => $notificationData,
            ], 200);

        }

        return response()->json(['message' => '', 'data' => UmrahTripReservationResource::make($umrahReservation)], 200);

    }

    /**
     * Get all reservation by umrah id or umrah id and reservation status [current-finished]
     * @param $umrah_trip_id
     * @param null $status
     * @return JsonResponse
     */
    public function getReservations($umrah_trip_id = null, $status = null) :JsonResponse
    {
        $user = Auth::user();
        $reservations = UmrahTripReservation::whereIn('umrah_trip_reservations.status', ['finished', 'current'])
            ->where('umrah_trip_reservations.user_id', $user->id)
//            ->where('umrah_trip_id', $umrah_trip_id)
            ->get()->groupBy('status');
        $previous = isset($reservations['finished']) ? $reservations['finished'] : [];
        $current = isset($reservations['current']) ? $reservations['current'] : [];

        return response()->json(['message' => '', 'data' => [
            'current' => count($current) ? UmrahTripReservationResource::collection($current) : [],
            'previous' =>  count($previous) ? UmrahTripReservationResource::collection($previous) : [],
        ]], 200);

    }

    /**
     * Umrah trip evaluate
     * @param Request $request
     * @param $reservation_id
     * @return JsonResponse
     */
    public function evaluate(Request $request, $reservation_id) :JsonResponse
    {
        $validation = Validator::make($request->all(),
            [
                'evaluate_average' => 'required|in:1,2,3,4,5',
                'comment' => 'required|min:3|max:400',
            ],[],[
                'comment' => __('evaluates.comment'),
                'evaluate_average' => __('evaluates.evaluate_average')
            ]);

        if ($validation->fails()){
            return response()->json(['message' => $validation->errors()->first()], 400);
        }

//        $umrah = UmrahTrip::find($umrah_trip_id);
//        if (!$umrah){
//            return response()->json(['message' => __('umrahTrips.umrah_trip_not_found'), 'data' => null], 401);
//        }
//        if (!$umrah->status){
//            return response()->json(['message' => __('umrahTrips.umrah_trip_not_active'), 'data' => null], 401);
//        }

        $user = Auth::user();

        $umrahTripReservation = UmrahTripReservation::where('status', 'finished')
            ->where('id', $reservation_id)->where('user_id', $user->id)->first();

        if (!$umrahTripReservation){
            return response()->json(['message' => __('umrahTrips.reservation_not_found')], 400);
        }

        if ($umrahTripReservation->umrah_trip_date > date('Y-m-d') || $umrahTripReservation->status != 'finished'){
            return response()->json(['message' => __('umrahTrips.reservation_not_finished')], 400);
        }

        $isEvaluateBefore = ConsultingEvaluate::where('user_id', $user->id)
            ->where('umrah_trip_id', $umrahTripReservation->umrah_trip_id)
            ->where('umrah_trip_reservation_id', $reservation_id)
            ->first();

        if ($isEvaluateBefore){
            return response()->json(['message' => __('umrahTrips.evaluate_before')], 400);
        }

        $umrah_trip_id = $umrahTripReservation->umrah_trip_id;
        ConsultingEvaluate::create([
            'user_id' => $user->id,
            'umrah_trip_id' => $umrah_trip_id,
            'umrah_trip_reservation_id' => $reservation_id,
            'comment' => $request->comment,
            'evaluate_average' => $request->evaluate_average,
        ]);
        $rate = DB::table('evaluates')
            ->selectSub("SELECT SUM(evaluate_average) FROM evaluates WHERE umrah_trip_id={$umrah_trip_id} LIMIT 1", 'evaluate_sum')
            ->selectSub("SELECT COUNT(evaluate_average) FROM evaluates WHERE umrah_trip_id=$umrah_trip_id LIMIT 1", 'evaluate_count')->first();
        $rate = $rate->evaluate_sum/$rate->evaluate_count;

        $umrahTrip = UmrahTrip::find($umrah_trip_id)->update(['rate' => $rate]);
        if ($umrahTrip){
            $umrahTrip->update(['rate' => $rate]);
        }

        return response()->json(['message' => __('hotels.evaluate_successfully'), 'data' => UserResource::make($user)], 200);

    }

    /**
     * Add or remove hotel to favorite
     * @param $umrah_trip_id
     * @return JsonResponse
     */
    public function addToFavorite($umrah_trip_id) :JsonResponse
    {
        $user = Auth::user();
        $umrah = UmrahTrip::find($umrah_trip_id);
        if (!$umrah){
            return response()->json(['message' => __('umrahTrips.umrah_trip_not_found'), 'data' => null], 401);
        }
        if (!$umrah->status){
            return response()->json(['message' => __('umrahTrips.umrah_trip_not_active'), 'data' => null], 401);
        }
        $favoriteUmrah = $user->umrahFavorites()->pluck('umrah_trip_id')->toArray();
        $message = __('umrahTrips.favorite_successfully');
        if (in_array($umrah_trip_id, $favoriteUmrah)){
            $message = __('umrahTrips.remove_favorite_successfully');
        }
        $user->umrahFavorites()->toggle($umrah_trip_id);
        return response()->json(['message' => $message, 'data' => UserResource::make($user)], 200);
    }

    /**
     * Get flights reservation requires like escorts and rally point info
     * @param $umrah_trip_id
     * @return JsonResponse
     */
    public function requires($umrah_trip_id = null) :JsonResponse
    {
        $user = Auth::check() ? Auth::user() : null;
        $escorts = [];
        if ($user){
            if ($user->escorts && is_array($user->escorts)){
                $escorts = is_string($user->escorts) ? json_decode($user->escorts, true) : $user->escorts;
            }
        }

        $umrahTrip = $umrah_trip_id ? UmrahTrip::find($umrah_trip_id) : UmrahTrip::first();
        if (!$umrahTrip){
            return response()->json(['message' => __('umrahTrips.umrah_trip_not_found'), 'data' => null], 401);
        }
        if (!$umrahTrip->status){
            return response()->json(['message' => __('umrahTrips.umrah_trip_not_active'), 'data' => null], 401);
        }

        $rallyPoints = is_string($umrahTrip->rally_point_info) ? json_decode($umrahTrip->rally_point_info, true) : $umrahTrip->rally_point_info;
        $umrahTripDates = is_string($umrahTrip->umrah_trip_date) ? json_decode($umrahTrip->umrah_trip_date, true) : $umrahTrip->umrah_trip_date;

        $points = [];
        foreach ($rallyPoints as $name => $rallyPoint) {
            $points[] = [
                'name' => $name,
                'lat' => $rallyPoint['lat'],
                'lng' => $rallyPoint['lng'],
                'address' => $rallyPoint['address'],
            ];
        }

        return response()->json(['message' => '', 'data' => [
            'escorts' =>  $escorts,
            'maximum_person_count' => $umrahTrip->maximum_person_count,
            'rally_point' => $points,
            'umrah_trip_dates' => $umrahTripDates,
        ]], 200);

    }


}
