<?php
/**
 * Created by PhpStorm.
 * User: stana
 * Date: 02.03.2017
 * Time: 16:38
 */

namespace App\Http\Controllers;

use App\Accommodation;
use App\AccommodationEquipment;
use App\Booked;
use App\Customer;
use App\Reservation;
use App\Room;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\DB;
use App\User;

class ReservationController
{
    public function showCreateReservation($room_id)
    {
        $room = Room::find($room_id);
        $date = new \DateTime();
        $date_start = $date->format('Y-m-d');
        $date_end = $date->modify('+1 day')->format('Y-m-d');
        $accommodation = Accommodation::where('accommodation_id', '=', $room->accommodation_id)->pluck('accommodation_name')->first();

        return view('create_reservation', ['room' => $room, 'date_start' => $date_start, 'date_end' => $date_end, 'accommodation' => $accommodation]);
    }

    public function createReservation(Request $request)
    {
        $messages = [
            'fname.required' => 'Zadejte své jméno',
            'lname.required' => 'Zadejte své příjmení',
            'phone_number.required' => 'Zadejte své telefonní číslo',
            'phone_number.regex' => 'Telefonní číslo není ve správném formátu: (+ 420) XXX XXX XXX',
            'price.integer' => 'Neplatné znaky, zadejte číslice',
            'date_start.required' => 'Vyplňte datum',
            'date_end.required' => 'Vyplňte datum',
            'email.email' => 'E-mail není zadán ve správném formátu',
            'email.required' => 'Zadejte svůj e-mail',
        ];

        // VALIDATE USER INPUT
        $validator = Validator::make($request->all(), [
            'fname' => 'required|max:255',
            'lname' => 'required|max:255',
            'email' => 'required|email|max:255',
            'phone_number' => 'required|regex:/^[1-9][0-9]{2} ?[0-9]{3} ?[0-9]{3}$/',
            'date_start' => 'required',
            'date_end' => 'required',
        ], $messages);

        $date_start = $request->date_start . " 14:00:00";
        $date_end = $request->date_end . " 10:00:00";

        /* KONTROLA OBSAZENOSTI UBYTOVANI - POKUD OBSAZENO, VYHODIT FLASH MESSAGE S INFORMACI O OBSAZENOSTI */
        $availability = Booked::whereBetween('date', [$date_start, $date_end])->where('room_id', '=', $request->room_id)->get();
        $confirmed = 'true';

        if ($availability != null) {
            foreach ($availability as $item) {
                $reservation = Reservation::find($availability[0]->reservation_id);
                if ($reservation->confirmation == 'false') {
                    $confirmed = 'false';
                }
            }
        }

        // CURRENT DATE TIME
        $now = new \DateTime();
        $now = $now->format('Y-m-d H:i:s');

        // DATES DIFFERENCE
        $date1 = date_create($request->date_start);
        $date2 = date_create($request->date_end);
        $days = date_diff($date2, $date1)->format("%d");

        // VALIDATOR FAILRS
        if ($validator->fails()) {
            return redirect()->back()->withErrors($validator)->withInput();
        } // START DATE IS BIGGER OR EQUAL TO END DATE
        elseif (($request->date_start > $request->date_end) OR ($request->date_start == $request->date_end)) {
            flash('Datum příjezdu nesmí být větší nebo stejné datumu odjezdu!', 'danger');
            return redirect()->back()->withInput();
        } // START DATE IS SMALLER THAN CURRENT DATE
        elseif ($request->date_start . " 23:59:00" < $now) {
            flash('Datum příjezdu nesmí být menší než je aktuální datum!', 'danger');
            return redirect('create_reservation/' . $request->room_id)->withInput();
        } // ROOM IS NOT AVAILABLE
        elseif (!$availability->isEmpty()) {
            if ($confirmed == 'true') {
                flash('Požadovaný termín je již bohužel obsazený! Vyberte jiné datum nebo zkuste jiný pokoj (ubytování)', 'danger');
            } elseif ($confirmed == 'false') {
                flash('Požadovaný termín je již bohužel obsazený! Některá z rezervací v termínu však není potvrzená, během dvou dnů může být termín opět dostupný', 'danger');
            }
            return redirect('create_reservation/' . $request->room_id)->withInput();
        } // MAX LENGTH OF RESERVATION
        elseif($days >= 14){
            flash('Maximální délka rezervace je 2 týdny', 'danger');
            return redirect('create_reservation/' . $request->room_id)->withInput();
        }

        $customer = Customer::where('customer_email', '=', $request->email)->first();

        if ($customer == null) {
            $customer = new Customer([
                'customer_fname' => $request->fname,
                'customer_lname' => $request->lname,
                'customer_email' => $request->email,
                'customer_phone_number' => $request->phone_number,
            ]);
        } else {
            $customer->customer_fname = $request->fname;
            $customer->customer_lname = $request->lname;
            $customer->customer_email = $request->email;
            $customer->customer_phone_number = $request->phone_number;
        }
        $customer->save();

        $customer_id = $customer->customer_id;
        $reservation = new Reservation([
            'date_start' => $request->date_start . " 14:00:00",
            'date_end' => $request->date_end . " 10:00:00",
            'persons' => $request->persons,
            'customer_id' => $customer_id,
            'room_id' => $request->room_id,
        ]);
        $reservation->save();

        $startTime = new \DateTime($reservation->date_start);
        $endTime = new \DateTime($reservation->date_end);

        for ($i = $startTime; $i <= $endTime; $i->modify('+1 day')) {
            $booked = new Booked([
                'room_id' => $reservation->room_id,
                'date' => $i->format('Y-m-d H:i:s'),
                'reservation_id' => $reservation->reservation_id
            ]);
            $booked->save();
        }
        $booked = new Booked([
            'room_id' => $reservation->room_id,
            'date' => $i->modify('-4 hours')->format('Y-m-d H:i:s'),
            'reservation_id' => $reservation->reservation_id
        ]);
        $booked->save();

        flash('Rezervace pokoje byla úspěšně vytvořena!', 'success');

        // LOGGED IN
        if (Auth::check()) {
            // ADMIN
            if (Auth::user()->role == 'admin') {
                return redirect('filtering');
                // ACCO ADMIN
            } else {
                return redirect('reservations_list');
            }
            // CUSTOM USER
        } else {
            $accommodation_id = Room::select('accommodation_id')->where('room_id', '=', $request->room_id)->first();
            return redirect('detail/' . $accommodation_id->accommodation_id);
        }
    }

    public function showReservationList()
    {
        $rooms = DB::table('rooms')
            ->join('accommodations', 'accommodations.accommodation_id', '=', 'rooms.accommodation_id')
            ->join('users', 'users.accommodation_id', '=', 'accommodations.accommodation_id')
            ->where('users.user_id', '=', Auth::user()->user_id)
            ->pluck('room_name', 'room_id');

        $reservations = DB::table('users')
            ->join('accommodations', 'accommodations.accommodation_id', '=', 'users.accommodation_id')
            ->join('rooms', 'rooms.accommodation_id', '=', 'accommodations.accommodation_id')
            ->join('reservations', 'rooms.room_id', '=', 'reservations.room_id')
            ->join('customers', 'customers.customer_id', '=', 'reservations.customer_id')
            ->select('accommodations.accommodation_id', 'rooms.room_name', 'reservations.date_start', 'reservations.confirmation', 'reservations.date_end', 'customers.customer_fname', 'customers.customer_lname', 'persons', 'customers.customer_email', 'customers.customer_phone_number', 'rooms.room_name', 'reservations.reservation_id')
            ->where('users.user_id', '=', Auth::user()->user_id)
            ->orderBy('reservations.date_start')
            ->get();

        $accommodation_id = User::where('user_id', '=', Auth::user()->user_id)->pluck('accommodation_id')->first();
        $accommodation = Accommodation::find($accommodation_id);

        return view('reservations_list', ['reservations' => $reservations, 'rooms' => $rooms, 'accommodation' => $accommodation]);
    }

    public function deleteReservation($reservation_id)
    {
        $reservation = Reservation::find($reservation_id);

        Booked::where('reservation_id', '=', $reservation_id);
        $reservation->delete();

        flash('Rezervace byla úspěšně smazána', 'success');
        return redirect('reservations_list');
    }

    public function confirmReservation($reservation_id)
    {
        $reservation = Reservation::find($reservation_id);
        $reservation->confirmation = 'true';
        $reservation->save();

        flash('Rezervace byla potvrzena', 'success');
        return redirect('reservations_list');
    }

    public function chooseRoom(Request $request)
    {
        if ($request->rooms == null) {
            flash('Nejsou k dispozici žádné pokoje', 'danger');
            return redirect()->back();
        }
        return redirect('create_reservation/' . $request->rooms);
    }

    public function showEditReservation($request)
    {
        $reservation = DB::table('reservations')
            ->join('customers', 'reservations.customer_id', '=', 'customers.customer_id')
            ->join('rooms', 'rooms.room_id', '=', 'reservations.room_id')
            ->where('reservations.reservation_id', '=', $request)->first();

        $reservation->date_start = \DateTime::createFromFormat('Y-m-d H:i:s', $reservation->date_start)->format('Y-m-d');
        $reservation->date_end = \DateTime::createFromFormat('Y-m-d H:i:s', $reservation->date_end)->format('Y-m-d');
        return view('edit_reservation', ['reservation' => $reservation]);
    }

    public function editReservation(Request $request)
    {
        $messages = [
            'fname.required' => 'Zadejte své jméno',
            'lname.required' => 'Zadejte své příjmení',
            'phone_number.required' => 'Zadejte své telefonní číslo',
            'phone_number.regex' => 'Telefonní číslo není ve správném formátu: (+ 420) XXX XXX XXX',
            'price.integer' => 'Neplatné znaky, zadejte číslice',
            'date_start.required' => 'Vyplňte datum',
            'date_end.required' => 'Vyplňte datum',
        ];

        // VALIDATE USER INPUT
        $validator = Validator::make($request->all(), [
            'fname' => 'required|max:255',
            'lname' => 'required|max:255',
            'email' => 'required|email|max:255',
            'phone_number' => 'required|regex:/^(\+420)? ?[1-9][0-9]{2} ?[0-9]{3} ?[0-9]{3}$/',
            'date_start' => 'required',
            'date_end' => 'required',
        ], $messages);

        // FIND RESERVATION
        $reservation = Reservation::find($request->reservation_id);

        // EDIT DATE TO DATETIME FORMAT
        $date_start = $request->date_start . " 14:00:00";
        $date_end = $request->date_end . " 10:00:00";

        // CHECK AVAILABILITY
        $booked = Booked::where('reservation_id', '=', $request->reservation_id)->get();
        foreach ($booked as $item) {
            $item->delete();
        }
        $availability = Booked::whereBetween('date', [$date_start, $date_end])->where('room_id', '=', $reservation->room_id)->get();

        // CURRENT DATETIME
        $now = new \DateTime();
        $now = $now->format('Y-m-d H:i:s');

        // VALIDATOR FAILS
        if ($validator->fails()) {
            return redirect()->back()->withErrors($validator)->withInput();
        }// START DATE IS BIGGER OR EQUAL TO END DATE
        elseif (($request->date_start > $request->date_end) OR ($request->date_start == $request->date_end)) {
            flash('Datum příjezdu nesmí být větší nebo stejné datumu odjezdu!', 'danger');
            return redirect()->back()->withInput();
        } // START DATE IS SMALLER THAN CURRENT DATE
        elseif ($request->date_start . ' 23:59:00' < $now) {
            flash('Datum příjezdu nesmí být menší než je aktuální datum!', 'danger');
            return redirect()->back()->withInput();
        } // ROOM IS NOT AVAILABLE
        elseif (!$availability->isEmpty()) {
            flash('Požadovaný termín je již bohužel obsazený! Vyberte jiné datum nebo zkuste jiný pokoj (ubytování)', 'danger');
            return redirect()->back()->withInput();
        }


        $customer = Customer::where('customer_email', '=', $request->email)->first();

        if ($customer == null) {// IF EMAIL DOES NOT EXISTS, JUST UPDATE CUSTOMER
            $customer = Customer::find($reservation->customer_id);
            $customer->customer_fname = $request->fname;
            $customer->customer_lname = $request->lname;
            $customer->customer_email = $request->email;
            $customer->customer_phone_number = $request->phone_number;
        } else { // IF EMAIL EXISTS, CHANGE CUSTOMER WITH THAT EMAIL AND REPLACE WITH HIM CUSTOMER_ID IN RESERVATIONS
            $customer->customer_fname = $request->fname;
            $customer->customer_lname = $request->lname;
            $customer->customer_email = $request->email;
            $customer->customer_phone_number = $request->phone_number;
        }
        $customer->save();

        // SET NEW RESERVATION DATE
        $reservation->persons = $request->persons;
        $reservation->date_start = $date_start;
        $reservation->date_end = $date_end;
        $reservation->customer_id = $customer->customer_id;
        $reservation->save();

        $startTime = new \DateTime($reservation->date_start);
        $endTime = new \DateTime($reservation->date_end);

        for ($i = $startTime; $i <= $endTime; $i->modify('+1 day')) {
            $booked = new Booked([
                'room_id' => $reservation->room_id,
                'date' => $i->format('Y-m-d H:i:s'),
                'reservation_id' => $reservation->reservation_id
            ]);
            $booked->save();
        }
        $booked = new Booked([
            'room_id' => $reservation->room_id,
            'date' => $i->modify('-4 hours')->format('Y-m-d H:i:s'),
            'reservation_id' => $reservation->reservation_id
        ]);
        $booked->save();

        flash('Rezervace byla úspěšně upravena!', 'success');
        return redirect('reservations_list');
    }
}