<?php

namespace App\Http\Controllers\Web;

use App\Http\Requests\Web\ReservationContinueRequest;
use App\Http\Requests\Web\ReservationPayRequest;
use App\Models\BlockDate;
use App\Models\Reservation;
use App\Models\ReservationPayment;
use App\Services\Integration\Integration\SMS;
use App\Models\Room;
use App\Models\WorkDay;
use App\Services\Interfaces\ReservationRepositoryInterface;
use App\Services\Interfaces\RoomRepositoryInterface;
use App\Services\Payment\MyFatoorahPayment;
use App\Services\Payment\PaymentService;
use Carbon\Carbon;
use DateTime;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Session;
use Illuminate\View\View;
use App\Http\Controllers\Controller;

class ReservationController extends Controller
{
    private $view = 'web.pages.reservations.';

    private $roomRepository ;
    private $reservationRepository ;


    public function __construct(
        RoomRepositoryInterface $roomRepository,
        ReservationRepositoryInterface $reservationRepository
    )
    {
        $this->roomRepository = $roomRepository;
        $this->reservationRepository = $reservationRepository;
    }

    /**
     * Show the application dashboard.
     * @return View
     */

    public function reservation(Request $request) :View
    {
        $block_dates = BlockDate::pluck('date')->toArray();
        $min_capacity = Room::min('min_count');
        $max_capacity = Room::max('max_count');
        if($request->room_id)
        {
            $room = Room::findOrFail($request->room_id);
            $min_capacity = is_null($room->min_count) ? 1 : $room->min_count;
            $max_capacity = $room->max_count;
        }
        $title = __('web.reservation');
        return view($this->view.'first_step', get_defined_vars());
    }

    public function timeReservation(Request $request)
    {
        $day = date('l',strtotime($request->date));
        $work_day = WorkDay::where('day',$day)->first();
        return 9;
        // $date1=date_create($work_day->end_time);
        // $date2=date_create($work_day->start_time);
        // $diff=date_diff($date1,$date2);
        // return $diff->h;

    }


    public function continue(ReservationContinueRequest $request) :View
    {
        $title = __('web.second_step');
        $room = Room::where('max_count','>=',$request->capacity)->where('min_count','<=',$request->capacity)->orderBy('id','DESC')->get();
        $rooms = [];
        $date = $request->date;
        $day = date('l',strtotime($request->date));
        $work_day = WorkDay::where('day',$day)->first();
        $capacity = $request->capacity;
        
        $date1= date_create($work_day->end_time);
        $date2=date_create($work_day->start_time);
        if($work_day->end_time > $work_day->start_time)
        {
            $diff=date_diff($date2,$date1);
            $hours =  $diff->h;
        }
        else
        {
            $end = date_create($work_day->end_time);
            $midnight = date_create(date('00:00:00'));
            $end_times = date_diff($end,$midnight);
            $end_hours =  $end_times->h;
            $start = date_create($work_day->start_time);
            $start_times = date_diff($midnight,$start);
            $start_hours =  $work_day->start_time < "12:00:00" ? $start_times->h : 24 - $start_times->h;
            $hours = $end_hours + $start_hours;
        }
        $count = (int) ($hours / $request->duration);
        
        foreach ($room as $key => $row)
        {
            $rooms[$key]['room'] = $this->roomRepository->getItem($row);
            for ($i = 0 ; $i < $count ; $i++) {
                $time = date('H', strtotime($work_day->start_time));

                $rooms[$key]['dates'][$i]['status'] = true;
                $start_time = (($time + ($i * $request->duration)) < 10 ? '0' . ($time + ($i * $request->duration)) : ($time + ($i * $request->duration))) . ':00';
                // $end_time = (($time + ($i * $request->duration) + $request->duration) < 10 ? '0' . ($time + ($i * $request->duration) + $request->duration) : ($time + ($i * $request->duration) + $request->duration)) . ':00';
                $end_time = date('H:i:s',strtotime($start_time .' +'.$request->duration.' hours'));
                $rooms[$key]['dates'][$i]['time'] = date('g:i ', strtotime($start_time)) . __('web.'.date('a', strtotime($start_time))) . ' / ' . date('g:i ', strtotime($end_time)). __('web.'.date('a', strtotime($end_time)));
                $rooms[$key]['dates'][$i]['time_input'] = $start_time . ' / ' . $end_time;
                $rooms[$key]['dates'][$i]['cost'] = $row->cost * $request->capacity * $request->duration;
                
                // $reservations = Reservation::where('room_id', $row->id)
                //     ->where('date', $request->date)
                //     ->get();
                
                // $start_time = DateTime::createFromFormat('h:i a', date('g:i a', strtotime($start_time)));
                // $end_time = DateTime::createFromFormat('h:i a', date('g:i a', strtotime($end_time)));
                
                // foreach ($reservations as $reservation) 
                // {
                    
                //     $reservation_start = DateTime::createFromFormat('h:i a', date('g:i a', strtotime($reservation->start_time)));
                //     $reservation_end = DateTime::createFromFormat('h:i a', date('g:i a', strtotime($reservation->end_time)));
                
                //     if (
                //         ($start_time >= $reservation_start && $start_time < $reservation_end) || 
                //         ($end_time > $reservation_start && $end_time <= $reservation_end) ||    
                //         ($start_time < $reservation_start && $end_time > $reservation_end)      
                //     ) 
                //     {
                //         $rooms[$key]['dates'][$i]['status'] = false;
                //     }
                // }
                
                // $reservations = Reservation::where('room_id', $row->id)
                //     ->where('date', $request->date)
                //     ->get();
                //     $start_time = DateTime::createFromFormat('h:i a', date('g:i a',strtotime($start_time)));
                //     $end_time = DateTime::createFromFormat('h:i a',  date('g:i a',strtotime($end_time)));

                //     foreach ($reservations as $reservation)
                //     {
                //         $reservation_start = DateTime::createFromFormat('h:i a', date('g:i a',strtotime($reservation->start_time)));
                //         $reservation_end = DateTime::createFromFormat('h:i a', date('g:i a',strtotime($reservation->end_time)));

                //         if($start_time < $reservation_end && $end_time > $reservation_start) 
                //         {
                //             $rooms[$key]['dates'][$i]['status'] = false;
                //         }
                //         // if ($end_time > $reservation_start && $end_time < $reservation_end)
                //         // {
                //         //     $rooms[$key]['dates'][$i]['status'] = false;
                //         // }
                //     }
                
                $starting = $start_time;
                $reservations = Reservation::where('room_id', $row->id)
                    ->where('date', $request->date)
                    ->get();
                
                // Convert new reservation's start_time and end_time to DateTime objects
                $start_time = DateTime::createFromFormat('h:i a', date('g:i a', strtotime($start_time)));
                $end_time = DateTime::createFromFormat('h:i a', date('g:i a', strtotime($end_time)));
                
                foreach ($reservations as $reservation) 
                {
                    // Convert reservation's start_time and end_time to DateTime objects
                    $reservation_start = DateTime::createFromFormat('h:i a', date('g:i a', strtotime($reservation->start_time)));
                    $reservation_end = DateTime::createFromFormat('h:i a', date('g:i a', strtotime($reservation->end_time)));
                    if($request->date == date('Y-m-d'))
                    {
                        if(date('H:i:s',strtotime($starting)) <= date('H:i:s') && date('H:i:s',strtotime($starting)) > '06:00:00')
                        {
                            $rooms[$key]['dates'][$i]['status'] = false;
                        }
                    }
                    
                    // Handle the case where the reservation spans midnight (i.e., end_time is before start_time)
                    if ($reservation_end < $reservation_start) {
                        // If reservation ends before it starts, it spans midnight (e.g., 11:00 PM to 2:00 AM)
                        $reservation_end->modify('+1 day'); // Add 1 day to end_time to account for crossing midnight
                    }
                
                    // Handle the case where the new reservation spans midnight
                    if ($end_time < $start_time) {
                        // If the new reservation ends before it starts, it spans midnight (e.g., 11:00 PM to 1:00 AM)
                        $end_time->modify('+1 day'); // Add 1 day to end_time
                    }
                    if ($end_time < $start_time || $start_time->format('H:i') === '00:00') {
                        $end_time->modify('+1 day'); // Adjust for crossing midnight
                    }
                
                    // Now check if the new reservation's time overlaps with the existing reservation's time
                    if (
                        ($start_time < $reservation_end && $end_time > $reservation_start) // If the new reservation overlaps the existing one
                    ) {
                        // Set the status to false if there's an overlap
                        $rooms[$key]['dates'][$i]['status'] = false;
                    }
                }
                
                $temporary_reservation = Reservation::onlyTrashed()->where('room_id', $row->id)
                    ->where('date', $request->date)
                    ->where('link_expire_at','>',date('Y-m-d H:i:s'))
                    ->get();
                
                foreach ($temporary_reservation as $reservation) 
                {
                    // Convert reservation's start_time and end_time to DateTime objects
                    $reservation_start = DateTime::createFromFormat('h:i a', date('g:i a', strtotime($reservation->start_time)));
                    $reservation_end = DateTime::createFromFormat('h:i a', date('g:i a', strtotime($reservation->end_time)));
                
                    // Handle the case where the reservation spans midnight (i.e., end_time is before start_time)
                    if ($reservation_end < $reservation_start) {
                        // If reservation ends before it starts, it spans midnight (e.g., 11:00 PM to 2:00 AM)
                        $reservation_end->modify('+1 day'); // Add 1 day to end_time to account for crossing midnight
                    }
                
                    // Handle the case where the new reservation spans midnight
                    if ($end_time < $start_time) 
                    {
                        // If the new reservation ends before it starts, it spans midnight (e.g., 11:00 PM to 1:00 AM)
                        $end_time->modify('+1 day'); // Add 1 day to end_time
                    }
                    if ($end_time < $start_time || $start_time->format('H:i') === '00:00') {
                        $end_time->modify('+1 day'); // Adjust for crossing midnight
                    }
                
                    // Now check if the new reservation's time overlaps with the existing reservation's time
                    if (
                        ($start_time < $reservation_end && $end_time > $reservation_start) // If the new reservation overlaps the existing one
                    ) {
                        // Set the status to false if there's an overlap
                        $rooms[$key]['dates'][$i]['status'] = false;
                    }
                }

//                if(is_null($reserved))
//                {
//                    $rooms[$key]['dates'][$i]['status'] = true;
//                }
            }
        }
        $day = $request->date;
        $duration = $request->duration;
        $title = __('web.reservation_continue');
        return view($this->view.'second_step', get_defined_vars());
    }

    public function bill(Request $request)
    {
        $arr = explode('-',$request->time);
        $room = Room::findOrFail($arr[1]);
        $room = $this->roomRepository->getItem($room);
        $date_input = $request->date;
        $date = date('d',strtotime($request->date)) .' ';
        $date .= __('web.'.date('F',strtotime($request->date))) .' ';
        $date .= date('Y',strtotime($request->date));
        $time_input = $arr[0];
        $times =  explode('/',$request->time);
        $end_time = explode('-',$times[1]);
        $time = date('g:i ',strtotime($times[0])).__('web.'.date('a',strtotime($times[0]))) . ' / '. date('g:i ',strtotime($end_time[0])).__('web.'.date('a',strtotime($end_time[0])));
        $capacity = $request->capacity;
        $new_times = explode('/',$time_input);
        $start_time = date('H:i:s',strtotime($new_times[0]));
        $end_time = date('H:i:s',strtotime($new_times[1]));
        $request->merge(['room'=>$room,'start_time'=>$start_time,'end_time'=>$end_time]);
        $response = $this->reservationRepository->calculate($request);
        $cobon_id = $response['cobon_id'];
        $discount = $response['discount'];
        $cobon = $request->cobon;
        $coupon = $response['cobon'];
        $total_reservation = $response['total_reservation'];
        $cobon_msg = $response['cobon_msg'];
        $tax = $response['tax'];
        $cobon_id = $response['cobon_id'];
        $total = $response['total'];
        // $total = $room->cost * $request->duration *  $capacity;
        $title = __('web.bill');
        return view($this->view.'bill', get_defined_vars());
    }

    public function pay(ReservationPayRequest $request)
    {
        $request->merge(['url'=>url()->previous()]);
        $order = null; //Session::get('order');
        if ($order)
        {
            $response = $this->reservationRepository->orderReservation($request);
        }
        else
        {
            $response = $this->reservationRepository->pay($request);
        }
        return $response;
    }

    public function paymentStatus(Request $request)
    {
        if (isset($_GET['paymentId'])) {
            // $username=Config::get('app.username');
            // $password= Config::get('app.password');
            // $tokenApi=Config::get('app.tokenApi');
            // $transaction=Config::get('app.transaction');

            // $curl = curl_init();
            // curl_setopt($curl, CURLOPT_URL, $tokenApi);
            // curl_setopt($curl, CURLOPT_POST, 1);
            // curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
            // curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
            // curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
            // curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query(array('grant_type' => 'password', 'username' => $username, 'password' => $password)));
            // $result = curl_exec($curl);
            // $error = curl_error($curl);
            // $info = curl_getinfo($curl);
            // curl_close($curl);
            // $json = json_decode($result, true);
            // $access_token = $json['access_token'];
            // $token_type = $json['token_type'];
            // if (isset($_GET['paymentId'])) {
            //     $id = $_GET['paymentId'];
            // }
            // $url = $transaction . $id;
            // $soap_do1 = curl_init();
            // curl_setopt($soap_do1, CURLOPT_URL, $url);
            // curl_setopt($soap_do1, CURLOPT_CONNECTTIMEOUT, 10);
            // curl_setopt($soap_do1, CURLOPT_TIMEOUT, 10);
            // curl_setopt($soap_do1, CURLOPT_RETURNTRANSFER, true);
            // curl_setopt($soap_do1, CURLOPT_SSL_VERIFYPEER, false);
            // curl_setopt($soap_do1, CURLOPT_SSL_VERIFYHOST, false);
            // curl_setopt($soap_do1, CURLOPT_POST, false);
            // curl_setopt($soap_do1, CURLOPT_POST, 0);
            // curl_setopt($soap_do1, CURLOPT_HTTPGET, 1);
            // curl_setopt($soap_do1, CURLOPT_HTTPHEADER, array('Content-Type: application/json; charset=utf-8', 'Accept: application/json', 'Authorization: Bearer ' . $access_token));
            // $result_in = curl_exec($soap_do1);
            // $err_in = curl_error($soap_do1);
            // $file_contents = htmlspecialchars(curl_exec($soap_do1));
            // curl_close($soap_do1);
            // $getRecorById = json_decode($result_in, true);
            $createPay = config('app.callback');
            $access_token = config('app.accessToken');
            $post_string = '{ 
                "Key": "' . $request->paymentId . '",
                "KeyType": "PaymentId"
            }';
            //$url = $transaction . $id;
            $soap_do1 = curl_init();
            curl_setopt($soap_do1, CURLOPT_URL, $createPay);
            curl_setopt($soap_do1, CURLOPT_CONNECTTIMEOUT, 10);
            curl_setopt($soap_do1, CURLOPT_TIMEOUT, 10);
            curl_setopt($soap_do1, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($soap_do1, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($soap_do1, CURLOPT_SSL_VERIFYHOST, false);
            curl_setopt($soap_do1, CURLOPT_POST, true);
            curl_setopt($soap_do1, CURLOPT_POSTFIELDS, $post_string);
            curl_setopt($soap_do1, CURLOPT_HTTPHEADER, array('Content-Type: application/json; charset=utf-8', 'Content-Length: ' . strlen($post_string), 'Accept: application/json', 'Authorization: Bearer ' . $access_token));
            $result_in = curl_exec($soap_do1);
            $info = curl_getinfo($soap_do1);
            $err_in = curl_error($soap_do1);
            $file_contents = htmlspecialchars(curl_exec($soap_do1));
            curl_close($soap_do1);
            $getRecorById = json_decode($result_in, true);
            if(!is_null($getRecorById['Data']))
            {
                $payment = ReservationPayment::where('payment_id',$getRecorById['Data']['InvoiceId'])->first();
                if ($getRecorById['Data']['InvoiceStatus'] == 'Paid' && $payment) 
                {
                    $reservation = $payment->reservation;
                    $reservation->restore();
                    $reservation->payment->update
                    ([
                        'payment_log'=>$result_in,
                    ]);
                    $message = 'تم تأكيد حجزك رقم ('.$reservation->id.') بنجاح في مطعم The Chord بتاريخ ( '.$reservation->date.') و وقت (وقت الحجز '.$reservation->start_time.'-'.$reservation->end_time.') لغرفة ('.$reservation->room->currentDescription->title.') ';
                    $phone = $reservation->user->phone;
                    SMS::sendSMS($phone,$message);
                
                    session()->flash('success', __('web.success'));
                    return redirect(getCurrentLocale().'/profile');
                
                }

            }
        }
        session()->flash('error',__('web.failed'));
        return redirect($lang.'/reservation');
    }
    
    // public function calculate(Request $request)
    // {
    //     // $arr = explode('-',$request->time);
    //     // $room = Room::findOrFail($arr[1]);
    //     // $room = $this->roomRepository->getItem($room);
    //     // $date_input = $request->date;
    //     // $date = date('d',strtotime($request->date)) .' ';
    //     // $date .= __('web.'.date('F',strtotime($request->date))) .' ';
    //     // $date .= date('Y',strtotime($request->date));
    //     // $time_input = $arr[0];
    //     // $times =  explode('/',$time_input);
    //     // $end_time = date('H:i:s',strtotime($times[1]));
    //     // $start_time = date('H:i:s',strtotime($times[0]));
    //     // $time = date('g:i ',strtotime($times[0])).__('web.'.date('a',strtotime($times[0]))) . ' / '. date('g:i ',strtotime($end_time[0])).__('web.'.date('a',strtotime($end_time[0])));
    //     // $request->merge(['room'=>$room,'start_time'=>$start_time,'end_time'=>$end_time]);
    //     $response = $this->reservationRepository->calculate($request);
    //     dd($response);
    // }
}
