<?php
namespace App\Controllers;

use App\Models\ReservationsModel;
use App\Models\ListingModel;
use GuzzleHttp\Client;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Slim\App;

class ReservationsController extends BaseController{
    public ReservationsModel $reservationsModel;
    public $listingModel;
    
    public string $layoutPath = "reservations";
    public function __construct(Request $request, Response $response, $args,App $app){
        parent::__construct($request, $response, $args,$app,true);
        $this->reservationsModel = new ReservationsModel();
        $this->listingModel = new ListingModel();
    }
    public function index():Response{
//        if(!$this->checkAuth($this->request)){ return $this->response->withStatus(401,'Unauthorized'); }
        return $this->renderLayout('advertisersBookingIndex.xml',[]);
    }
    
    public function quickQuoteService():Response{
        if(!$this->checkAuth($this->request)){ return $this->response->withStatus(401,'Unauthorized'); }
        $reqData    = $this->request->getParsedBody();
        $client = new Client([
            'base_uri'=>VRMANAGED_URL
        ]);

        $formattedReqData = [];
        $formattedReqData['checkin_date'] = $reqData['dateRange']['arrivalDate'];
        $formattedReqData['checkout_date'] = $reqData['dateRange']['departureDate'];
        $formattedReqData['unit_id'] = $reqData['listingExternalId'];

        $resp = $client->post('vrboconnector/quickQuoteService',[
            'body'=>json_encode($formattedReqData)
        ]);
        // $response = json_decode($resp->getBody()->getContents(),true);
        return $this->renderJson(json_decode($resp->getBody()->getContents(),true));
    }

    public function fastAvailabilityService():Response{
        if(!$this->checkAuth($this->request)){ return $this->response->withStatus(401,'Unauthorized'); }

        $reqData    = $this->request->getParsedBody();
        $reservationsModel = $this->reservationsModel;
        $listingModel = $this->listingModel;
        $unitIds    = array_map(function ($unit)use($listingModel) {
            return $unit['unitExternalId'];
//            $fetchedUnit = $listingModel->getVBUnitIdByUnitId($unit['unitExternalId']);
//            if (empty($fetchedUnit)) {
//                return $unit['unitExternalId'];
//            } else {
//                return $fetchedUnit[0]['id'];
//            }
        },$reqData['units']);
        $startDate  = $reqData['dateRange']['arrivalDate'];
        $endDate    = $reqData['dateRange']['departureDate'];
        $nights     = (new \DateTime($endDate))->diff(new \DateTime($startDate))->format("%a"); 
        $adults     = $reqData['adults'];
        $pets       = $reqData['pets'];
        
               
        $data = array_map(function ($unitId) use ($startDate,$endDate,$reservationsModel,$listingModel,$nights,$adults,$pets){
            $unitData = $listingModel->getListing($unitId);
            
            $seasons_up = $listingModel->getSeasonsByUnitId($unitId);
            $seasons = [];
            foreach($seasons_up as $season){
                $seasons[$season['date_from']] = $season['min_stay'];    
            }
            $min_night = isset($seasons[$startDate]) ? $seasons[$startDate] : 3;
            // replace this with unit config value
            if($nights < $min_night){
                return
                [
                    'unitExternalId' => $unitId,
                    'available' => false,
                    'errorCode'=>'MIN_STAY_NOT_MET',
                    'errorMessage'=>"Property Not Available.MIN STAY NOT MET"
                ];
            }
            if($nights > 28){
                return
                [
                    'unitExternalId' => $unitId,
                    'available' => false,
                    'errorCode'=>'EXCEEDS_MAX_STAY',
                    'errorMessage'=>"Property Not Available.EXCEEDS MAX STAY"
                ];
            }
            
            // replace this with unit config value
            if($adults > $unitData[0]['sleep']){
            // if($adults > 40){
                return
                [
                    'unitExternalId' => $unitId,
                    'available' => false,
                    'errorCode'=>'EXCEEDS_MAX_OCCUPANCY',
                    'errorMessage'=>"Property Not Available.EXCEEDS MAX OCCUPANCY"
                ];
            }
            
            // replace this with unit config value
            $details =  json_decode($unitData[0]['details'],true);
            $petsAllowd = false;
            if($details['dogs_allowed'] == "yes" ||  $details['cats_allowed'] == "yes" ){
                $petsAllowd = true;
            }
            if($pets > 0 && !$petsAllowd){
                return
                [
                    'unitExternalId' => $unitId,
                    'available' => false,
                    'errorCode'=>'PETS_NOT_ALLOWED',
                    'errorMessage'=>"Property Not Available.PETS NOT ALLOWED"
                ];
            }
            // $isResCheckinAllowed = $reservationsModel->getCheckinAllowedByUnitId($unitId,$startDate);
            
            
            $isResCheckoutAllowed = $reservationsModel->getCheckoutAllowedByUnitId($unitId,$endDate);
            if(!$isResCheckoutAllowed){
                return
                    [
                        'unitExternalId' => $unitId,
                        'available' => false,
                        'errorCode'=>'CHANGE_OVER_DAY_MISMATCH',
                        'errorMessage'=>"Property Not Available On The Dates Specified.CHANGE_OVER_DAY_MISMATCH"
                    ];
            }
            
            $isAvailable = $reservationsModel->getAvailabilityByUnitId($unitId,$startDate,$endDate);
            if($isAvailable) {
                return
                    [
                        'unitExternalId' => $unitId,
                        'available' => $isAvailable,
                    ];
            }else{
                return
                    [
                        'unitExternalId' => $unitId,
                        'available' => $isAvailable,
                        'errorCode'=>'PROPERTY_NOT_AVAILABLE',
                        'errorMessage'=>"Property Not Available On The Dates Specified."
                    ];
            }
        },$unitIds);

        return $this->renderJson(['units'=>$data]);
    }

    public function find_between_custom_tag($data, $tag) {
        $regex = '/<' . $tag . '>(.*?)<\/' . $tag . '>/smix';
        preg_match_all($regex, $data, $matches);
        return $matches[0][0];
    }

    public function getPaymentScheduleByReservationId($id){
        return $this->reservationsModel->getPaymentScheduleByReservationId($id);
    }

    public function bookingService() : Response{
        if(!$this->checkAuth($this->request)){ return $this->response->withStatus(401,'Unauthorized'); }

        $reqData = $this->request->getParsedBody();
        $xmlData = $this->request->getBody()->getContents();
        $orderItemList = $this->find_between_custom_tag($xmlData,'orderItemList');
        // $paymentScheduleXML = '<paymentSchedule><acceptedPaymentForms><paymentCardDescriptor><paymentFormType>CARD</paymentFormType><cardCode>MASTERCARD</cardCode><cardType>CREDIT</cardType></paymentCardDescriptor><paymentCardDescriptor><paymentFormType>CARD</paymentFormType><cardCode>VISA</cardCode><cardType>CREDIT</cardType></paymentCardDescriptor><paymentCardDescriptor><paymentFormType>CARD</paymentFormType><cardCode>VISA_ELECTRON</cardCode><cardType>CREDIT</cardType></paymentCardDescriptor><paymentCardDescriptor><paymentFormType>CARD</paymentFormType><cardCode>AMEX</cardCode><cardType>CREDIT</cardType></paymentCardDescriptor></acceptedPaymentForms>'
        // // .$this->find_between_custom_tag($xmlData,'paymentScheduleItemList')
        // .'<description>Property Manager Will Collect Soon.</description>'
        // .'</paymentSchedule>';
        $bookingRequestDetails = $reqData->bookingRequestDetails;
        $unit_id = (string)$bookingRequestDetails->listingExternalId;

        $idGot = $this->getUnitIdByListId($unit_id);

        if($idGot){ $unit_id = $idGot; }


        $unit = $this->listingModel->getListing($unit_id);
        $unit = $unit[0];


        $inquirer = $bookingRequestDetails->inquirer;
        $guest = [
            'first_name'=>(string)$inquirer->firstName,
            'last_name'=>(string)$inquirer->lastName,
            'email'=>(string)$inquirer->emailAddress,
            'phoneNumber'=>(string)$inquirer->phoneNumber,
            'address'=>[
                'address1'=>(string)$inquirer->address->addressLine1,
                'address2'=>(string)$inquirer->address->addressLine2,
                'city'=>(string)$inquirer->address->addressLine3,
                'state'=>(string)$inquirer->address->addressLine4,
                'country'=>(string)$inquirer->address->country,
                'postal_code'=>(string)$inquirer->address->postalCode,
            ]
        ];

        $charges = [];
        if(isset($bookingRequestDetails->olbMeta)) {
            $charges[] = ['name' => 'serviceFee', 'amount' => (string)$bookingRequestDetails->olbMeta->serviceFee];
        }

        $reservationData = $bookingRequestDetails->reservation;
        $reservation = [];
        $reservation['guestCounts']['adults'] = (string)$reservationData->numberOfAdults;
        $reservation['guestCounts']['child'] = (string)$reservationData->numberOfChildren;
        $reservation['guestCounts']['pets'] = (string)$reservationData->numberOfPets;
        $reservation['checkin_date'] = (string)$reservationData->reservationDates->beginDate;
        $reservation['checkout_date'] = (string)$reservationData->reservationDates->endDate;

        $numberOfAdults = $reservation['guestCounts']['adults'];
        $numberOfChildren = $reservation['guestCounts']['child'];
        $numberOfPets = $reservation['guestCounts']['pets'];
        $checkin_date = $reservation['checkin_date'];
        $checkout_date = $reservation['checkout_date'];

        $reservation['guest'] = $guest;
        $paymentForm = $bookingRequestDetails->paymentForm;
        $reservation['creditCard'] = [
            'cardNumber'=>(string)$paymentForm->paymentCard->number,
            'cvv'=>(string)$paymentForm->paymentCard->cvv,
            'expiration'=>(string)$paymentForm->paymentCard->expiration,
            'nameOnCard'=>(string)$paymentForm->paymentCard->nameOnCard,
        ];
        $rent = 0;
        $taxes = [];
        foreach($bookingRequestDetails->orderItemList->orderItem as $orderItem){
            if((string)$orderItem->productId == "RENT"){
                $rent += (float)$orderItem->preTaxAmount;
            }
            elseif ((string)$orderItem->productId == "TAX"){
                $taxes[] = ['name'=>(string)$orderItem->name,'amount'=>(float)$orderItem->preTaxAmount];
            }
            else{
                $charges[] = ['name'=>(string)$orderItem->name,'amount'=>(float)$orderItem->preTaxAmount];
            }
        }

        $totalPaymentAmount = 0;
        foreach ($bookingRequestDetails->paymentScheduleItemList->paymentScheduleItem as $paymentSchedule){
            $totalPaymentAmount += round((float)$paymentSchedule->amount,2);
        }

        $reservation['rent'] = $rent;
        $reservation['charges'] = $charges;
        $reservation['taxes'] = $taxes;
        $reservation['unit_id'] = $unit_id;
        $reservation['comment'] = (string)$bookingRequestDetails->message;
        $reservation['totalPaymentAmount'] = $totalPaymentAmount;
        $reservation['rowData'] = $this->request->getBody()->getContents();

        $client = new Client([
            'base_uri'=>VRMANAGED_URL
        ]);
        $resp = $client->post('vrboconnector/createreservationVRBO',[
            'body'=>json_encode($reservation)
        ]);
        // print_r($resp->getBody()->getContents());
        // die;
        $response = json_decode($resp->getBody()->getContents(),true);
        if($response['status']){
            $config = $this->listingModel->getConfig();
            $config = (json_decode($config[0]['data'],true));
            $cancel_policy_desc = $config['cancel_policy_desc'];
            $payment_policy_desc = $config['payment_policy_desc'];
            $file = fopen('res_data/'.$response['reservation']['id'].'.txt','a+');
            fwrite($file,"===============\n");
            fwrite($file,json_encode($reservation));
            fwrite($file,"===============\n");
            fwrite($file,json_encode($response['reservation']));
            fwrite($file,"===============\n");
            fclose($file);
            
            $reservation = $response['reservation'];
            $all_data_req = json_decode($reservation['all_data_req'],true);
            $fake_quote = json_decode($all_data_req['fake_quote'],true);
            $paymentSchedule = $this->getPaymentScheduleByReservationId($reservation['id']);            
            $paymentScheduleXML = '<paymentSchedule><acceptedPaymentForms><paymentCardDescriptor><paymentFormType>CARD</paymentFormType><cardCode>MASTERCARD</cardCode><cardType>CREDIT</cardType></paymentCardDescriptor><paymentCardDescriptor><paymentFormType>CARD</paymentFormType><cardCode>VISA</cardCode><cardType>CREDIT</cardType></paymentCardDescriptor><paymentCardDescriptor><paymentFormType>CARD</paymentFormType><cardCode>VISA_ELECTRON</cardCode><cardType>CREDIT</cardType></paymentCardDescriptor><paymentCardDescriptor><paymentFormType>CARD</paymentFormType><cardCode>AMEX</cardCode><cardType>CREDIT</cardType></paymentCardDescriptor></acceptedPaymentForms>';
            // $paymentScheduleXML .= $this->find_between_custom_tag($xmlData,'paymentScheduleItemList');
            $paymentScheduleXML .= '<description>'.$payment_policy_desc.'</description>';
            // if(count($paymentSchedule) > 0){
            //     $paymentScheduleXML .= '<paymentScheduleItemList>';
            //     foreach($paymentSchedule as $schedule){
            //         $paymentScheduleXML .= '
            //         <paymentScheduleItem>
            //             <amount currency="USD">'.$schedule['amount'].'</amount>
            //             <dueDate>'.$schedule['scheduled_date'].'</dueDate>
            //             <externalId>'.$schedule['id'].'</externalId>
            //         </paymentScheduleItem>';
            //     }
            //     $paymentScheduleXML .= '</paymentScheduleItemList>';
            // }
            // else{
            //     $paymentScheduleXML .= '<description>Schedule Will be Generated Soon.</description>';
            // }
            
            $paymentScheduleXML .= '</paymentSchedule>';
            return $this->renderLayout('bookingResponse.xml',[
                'unit'=>$unit,'cancel_policy_desc'=>$cancel_policy_desc,'payment_policy_desc'=>$payment_policy_desc,
                'reservation'=>$reservation,'all_data_req'=>$all_data_req,
                'orderItemList'=>$orderItemList,'paymentSchedule'=>$paymentScheduleXML,
                'checkout_date'=>$checkout_date,'checkin_date'=>$checkin_date,
                'numberOfAdults'=>$numberOfAdults,'numberOfPets'=>$numberOfPets,'numberOfChildren'=>$numberOfChildren,
            ]);
        }
        else{
            return $this->renderLayout('bookingResponseError.xml',[]);
        }
    }
    public function bookingServiceRA() : Response{
        if(!$this->checkAuth($this->request)){ return $this->response->withStatus(401,'Unauthorized'); }

        $reqData = $this->request->getParsedBody();
        $xmlData = $this->request->getBody()->getContents();
        $orderItemList = $this->find_between_custom_tag($xmlData,'orderItemList');
        // $paymentScheduleXML = '<paymentSchedule><acceptedPaymentForms><paymentCardDescriptor><paymentFormType>CARD</paymentFormType><cardCode>MASTERCARD</cardCode><cardType>CREDIT</cardType></paymentCardDescriptor><paymentCardDescriptor><paymentFormType>CARD</paymentFormType><cardCode>VISA</cardCode><cardType>CREDIT</cardType></paymentCardDescriptor><paymentCardDescriptor><paymentFormType>CARD</paymentFormType><cardCode>VISA_ELECTRON</cardCode><cardType>CREDIT</cardType></paymentCardDescriptor><paymentCardDescriptor><paymentFormType>CARD</paymentFormType><cardCode>AMEX</cardCode><cardType>CREDIT</cardType></paymentCardDescriptor></acceptedPaymentForms>'
        // // .$this->find_between_custom_tag($xmlData,'paymentScheduleItemList')
        // .'<description>Property Manager Will Collect Soon.</description>'
        // .'</paymentSchedule>';
        $bookingRequestDetails = $reqData->bookingRequestDetails;
        $unit_id = (string)$bookingRequestDetails->listingExternalId;

        $idGot = $this->getUnitIdByListId($unit_id);

        if($idGot){ $unit_id = $idGot; }


        $unit = $this->listingModel->getListing($unit_id);
        $unit = $unit[0];


        $inquirer = $bookingRequestDetails->inquirer;
        $guest = [
            'first_name'=>(string)$inquirer->firstName,
            'last_name'=>(string)$inquirer->lastName,
            'email'=>(string)$inquirer->emailAddress,
            'phoneNumber'=>(string)$inquirer->phoneNumber,
            'address'=>[
                'address1'=>(string)$inquirer->address->addressLine1,
                'address2'=>(string)$inquirer->address->addressLine2,
                'city'=>(string)$inquirer->address->addressLine3,
                'state'=>(string)$inquirer->address->addressLine4,
                'country'=>(string)$inquirer->address->country,
                'postal_code'=>(string)$inquirer->address->postalCode,
            ]
        ];

        $charges = [];
        if(isset($bookingRequestDetails->olbMeta)) {
            $charges[] = ['name' => 'serviceFee', 'amount' => (string)$bookingRequestDetails->olbMeta->serviceFee];
        }

        $reservationData = $bookingRequestDetails->reservation;
        $reservation = [];
        $reservation['guestCounts']['adults'] = (string)$reservationData->numberOfAdults;
        $reservation['guestCounts']['child'] = (string)$reservationData->numberOfChildren;
        $reservation['guestCounts']['pets'] = (string)$reservationData->numberOfPets;
        $reservation['checkin_date'] = (string)$reservationData->reservationDates->beginDate;
        $reservation['checkout_date'] = (string)$reservationData->reservationDates->endDate;

        $numberOfAdults = $reservation['guestCounts']['adults'];
        $numberOfChildren = $reservation['guestCounts']['child'];
        $numberOfPets = $reservation['guestCounts']['pets'];
        $checkin_date = $reservation['checkin_date'];
        $checkout_date = $reservation['checkout_date'];

        $reservation['guest'] = $guest;
        $paymentForm = $bookingRequestDetails->paymentForm;
        $reservation['creditCard'] = [
            'cardNumber'=>(string)$paymentForm->paymentCard->number,
            'cvv'=>(string)$paymentForm->paymentCard->cvv,
            'expiration'=>(string)$paymentForm->paymentCard->expiration,
            'nameOnCard'=>(string)$paymentForm->paymentCard->nameOnCard,
        ];
        $rent = 0;
        $taxes = [];
        foreach($bookingRequestDetails->orderItemList->orderItem as $orderItem){
            if((string)$orderItem->productId == "RENT"){
                $rent += (float)$orderItem->preTaxAmount;
            }
            elseif ((string)$orderItem->productId == "TAX"){
                $taxes[] = ['name'=>(string)$orderItem->name,'amount'=>(float)$orderItem->preTaxAmount];
            }
            else{
                $charges[] = ['name'=>(string)$orderItem->name,'amount'=>(float)$orderItem->preTaxAmount];
            }
        }

        $totalPaymentAmount = 0;
        foreach ($bookingRequestDetails->paymentScheduleItemList->paymentScheduleItem as $paymentSchedule){
            $totalPaymentAmount += round((float)$paymentSchedule->amount,2);
        }

        $reservation['rent'] = $rent;
        $reservation['charges'] = $charges;
        $reservation['taxes'] = $taxes;
        $reservation['unit_id'] = $unit_id;
        $reservation['comment'] = (string)$bookingRequestDetails->message;
        $reservation['totalPaymentAmount'] = $totalPaymentAmount;
        $reservation['rowData'] = $this->request->getBody()->getContents();
        $reservation['fromRA'] = true;
        $client = new Client([
            'base_uri'=>VRMANAGED_URL
        ]);
        $resp = $client->post('vrboconnector/createreservationVRBO',[
            'body'=>json_encode($reservation)
        ]);
        // print_r($resp->getBody()->getContents());
        // die;
        $response = json_decode($resp->getBody()->getContents(),true);
        if($response['status']){
            $config = $this->listingModel->getConfig();
            $config = (json_decode($config[0]['data'],true));
            $cancel_policy_desc = $config['cancel_policy_desc'];
            $payment_policy_desc = $config['payment_policy_desc'];
            $file = fopen('res_data/'.$response['reservation']['id'].'.txt','a+');
            fwrite($file,"===============\n");
            fwrite($file,json_encode($reservation));
            fwrite($file,"===============\n");
            fwrite($file,json_encode($response['reservation']));
            fwrite($file,"===============\n");
            fclose($file);
            
            $reservation = $response['reservation'];
            $all_data_req = json_decode($reservation['all_data_req'],true);
            $fake_quote = json_decode($all_data_req['fake_quote'],true);
            $paymentSchedule = $this->getPaymentScheduleByReservationId($reservation['id']);            
            $paymentScheduleXML = '<paymentSchedule><acceptedPaymentForms><paymentCardDescriptor><paymentFormType>CARD</paymentFormType><cardCode>MASTERCARD</cardCode><cardType>CREDIT</cardType></paymentCardDescriptor><paymentCardDescriptor><paymentFormType>CARD</paymentFormType><cardCode>VISA</cardCode><cardType>CREDIT</cardType></paymentCardDescriptor><paymentCardDescriptor><paymentFormType>CARD</paymentFormType><cardCode>VISA_ELECTRON</cardCode><cardType>CREDIT</cardType></paymentCardDescriptor><paymentCardDescriptor><paymentFormType>CARD</paymentFormType><cardCode>AMEX</cardCode><cardType>CREDIT</cardType></paymentCardDescriptor></acceptedPaymentForms>';
            // $paymentScheduleXML .= $this->find_between_custom_tag($xmlData,'paymentScheduleItemList');
            $paymentScheduleXML .= '<description>'.$payment_policy_desc.'</description>';
            // if(count($paymentSchedule) > 0){
            //     $paymentScheduleXML .= '<paymentScheduleItemList>';
            //     foreach($paymentSchedule as $schedule){
            //         $paymentScheduleXML .= '
            //         <paymentScheduleItem>
            //             <amount currency="USD">'.$schedule['amount'].'</amount>
            //             <dueDate>'.$schedule['scheduled_date'].'</dueDate>
            //             <externalId>'.$schedule['id'].'</externalId>
            //         </paymentScheduleItem>';
            //     }
            //     $paymentScheduleXML .= '</paymentScheduleItemList>';
            // }
            // else{
            //     $paymentScheduleXML .= '<description>Schedule Will be Generated Soon.</description>';
            // }
            
            $paymentScheduleXML .= '</paymentSchedule>';
            return $this->renderLayout('bookingResponse.xml',[
                'unit'=>$unit,'cancel_policy_desc'=>$cancel_policy_desc,'payment_policy_desc'=>$payment_policy_desc,
                'reservation'=>$reservation,'all_data_req'=>$all_data_req,
                'orderItemList'=>$orderItemList,'paymentSchedule'=>$paymentScheduleXML,
                'checkout_date'=>$checkout_date,'checkin_date'=>$checkin_date,
                'numberOfAdults'=>$numberOfAdults,'numberOfPets'=>$numberOfPets,'numberOfChildren'=>$numberOfChildren,
            ]);
        }
        else{
            return $this->renderLayout('bookingResponseError.xml',[]);
        }
    }

    public function bookingContentIndex(){
        if(!$this->checkAuth($this->request)){ return $this->response->withStatus(401,'Unauthorized'); }
        $reqData = $this->request->getParsedBody();
        if(!isset($reqData->startDate)){
            return $this->response->withStatus(404,'Start Date Not found');
        }
        if(empty($reqData->startDate)){
            return $this->response->withStatus(404,'Start Date Not found');
        }
        $startDate = $reqData->startDate;
        $endDate = $reqData->endDate;
        $reservations = $this->reservationsModel->getAllReservationsByDates($startDate,$endDate);
        return $this->renderLayout('bookingContentIndex.xml',['reservations'=>$reservations]);
    }

    public function bookingUpdate(){
        if(!$this->checkAuth($this->request)){ return $this->response->withStatus(401,'Unauthorized'); }

        $reqData = $this->request->getQueryParams();

        if(!isset($reqData['id'])){
            return $this->response->withStatus(404,'Id not found');
        }
        if(empty($reqData['id'])){
            return $this->response->withStatus(404,'Id not found');
        }
        $reservation = $this->reservationsModel->getReservationByBookingNumber($reqData['id']);
        $escapiaReservation = $this->reservationsModel->getEscapiaReservationByBookingNumber($reqData['id']);
        if(count($reservation) == 0){
            return $this->response->withStatus(404,'not found');
        }
        $reservation = $reservation[0];
        $paymentSchedule = $this->getPaymentScheduleByReservationId($reservation['id']);
        $escapiaReservation = $escapiaReservation[0];
        $xmlData = (json_decode($escapiaReservation['ru_data'],true)['rowData']);
        $orderItemList = $this->find_between_custom_tag($xmlData,'orderItemList');
        $all_data_req = (json_decode($reservation['all_data_req'],true));
        // $orderItemList = NULL;
        if($orderItemList == NULL){
            $all_data_req = (json_decode($reservation['all_data_req'],true));
            $alltaxes = [];
            $orderitemlistarray = [];
            $orderitemlistarray[] = [
                'type'=>"RENTAL",
                'name'=>"RENT",
                'preTaxAmount'=>str_replace(',','',number_format($all_data_req['rent']['rent_price'],2)),
                'productId'=>"RENT",
                'totalAmount'=>str_replace(',','',number_format($all_data_req['rent']['rent_price'],2)),
                ];
            foreach($all_data_req['rent']['rent_tax'] as $tax){
                if(!isset($alltaxes[$tax['name']])){
                    $alltaxes[$tax['name']] = str_replace(',','',number_format($tax['value']));
                }
                else{
                    $alltaxes[$tax['name']] = $alltaxes[$tax['name']] + str_replace(',','',number_format($tax['value']));
                }
            }
            foreach($all_data_req['charges'] as $charge ){
                $orderitemlistarray[] = [
                'type'=>"MISC",
                'name'=>$charge['name'],
                'preTaxAmount'=>str_replace(',','',number_format($charge['amount'],2)),
                'productId'=>"ADMINISTRATIVE",
                'totalAmount'=>str_replace(',','',number_format($charge['amount'],2)),
                ];
                foreach($charge['tax'] as $tax){
                    if(!isset($alltaxes[$tax['name']])){
                        $alltaxes[$tax['name']] = str_replace(',','',number_format($tax['value']));
                    }
                    else{
                        $alltaxes[$tax['name']] = $alltaxes[$tax['name']] + str_replace(',','',number_format($tax['value']));
                    }
                }   
            }
            if(isset($all_data_req['comm']) && isset($all_data_req['comm']['comm_amount'])){
                $orderitemlistarray[] = [
                'type'=>"MISC",
                'name'=>'VR FEES',
                'preTaxAmount'=>str_replace(',','',number_format($all_data_req['comm']['comm_amount'],2)),
                'productId'=>"ADMINISTRATIVE",
                'totalAmount'=>str_replace(',','',number_format($all_data_req['comm']['comm_amount'],2)),
                ];
                foreach($all_data_req['comm']['comm_taxes'] as $tax){
                    if(!isset($alltaxes[$tax['name']])){
                        $alltaxes[$tax['name']] = str_replace(',','',number_format($tax['value']));
                    }
                    else{
                        $alltaxes[$tax['name']] = $alltaxes[$tax['name']] + str_replace(',','',number_format($tax['value']));
                    }
                }   
            }
            $totalTax = 0; 
            foreach($alltaxes as $tax){
                $totalTax = $totalTax + $tax;
            }
            $orderitemlistarray[] = [
            'type'=>"TAX",
            'name'=>'TAX',
            'preTaxAmount'=>str_replace(',','',number_format($totalTax,2)),
            'productId'=>"TAX",
            'totalAmount'=>str_replace(',','',number_format($totalTax,2)),
            ];
            foreach($orderitemlistarray as $orderitemlistarrays){
                $orderItemList .= '
                <orderItem>
                    <feeType>'.$orderitemlistarrays['type'].'</feeType>
                    <name>'.$orderitemlistarrays['name'].'</name>
                    <preTaxAmount currency="USD">'.$orderitemlistarrays['preTaxAmount'].'</preTaxAmount>
                    <productId>'.$orderitemlistarrays['productId'].'</productId>
                    <totalAmount currency="USD">'.$orderitemlistarrays['totalAmount'].'</totalAmount>
                </orderItem>
                ';
            }
            $orderItemList = '<orderItemList>'.$orderItemList.'</orderItemList>';
        }
        $config = $this->listingModel->getConfig();
        $config = (json_decode($config[0]['data'],true));
        $cancel_policy_desc = $config['cancel_policy_desc'];
        $payment_policy_desc = $config['payment_policy_desc'];

        $paymentScheduleXML = '<paymentSchedule><acceptedPaymentForms><paymentCardDescriptor><paymentFormType>CARD</paymentFormType><cardCode>MASTERCARD</cardCode><cardType>CREDIT</cardType></paymentCardDescriptor><paymentCardDescriptor><paymentFormType>CARD</paymentFormType><cardCode>VISA</cardCode><cardType>CREDIT</cardType></paymentCardDescriptor><paymentCardDescriptor><paymentFormType>CARD</paymentFormType><cardCode>VISA_ELECTRON</cardCode><cardType>CREDIT</cardType></paymentCardDescriptor><paymentCardDescriptor><paymentFormType>CARD</paymentFormType><cardCode>AMEX</cardCode><cardType>CREDIT</cardType></paymentCardDescriptor></acceptedPaymentForms>';
        // $paymentScheduleXML .= $this->find_between_custom_tag($xmlData,'paymentScheduleItemList');
        $paymentScheduleXML .= '<description>'.$payment_policy_desc.'</description>';
        // .'<description>Property Manager Will Collect Soon.</description>'
        // if(count($paymentSchedule) > 0){
        //     $paymentScheduleXML .= '<paymentScheduleItemList>';
        //     foreach($paymentSchedule as $schedule){
        //         $paymentScheduleXML .= '
        //         <paymentScheduleItem>
        //             <amount currency="USD">'.$schedule['amount'].'</amount>
        //             <dueDate>'.$schedule['scheduled_date'].'</dueDate>
        //             <externalId>'.$schedule['id'].'</externalId>
        //         </paymentScheduleItem>';
        //     }
        //     $paymentScheduleXML .= '</paymentScheduleItemList>';
        // }
        // else{
        //     $paymentScheduleXML .= '<description>Schedule Will be Generated Soon.</description>';
        // }
        $paymentScheduleXML .= '</paymentSchedule>';

        $guest = $this->reservationsModel->getGuest($reservation['contact_id']);
        $guest = $guest[0];
        $guest['phone_number'] = json_decode($guest["phone_number"],true)[0];
        $paymentStatus = "";
        switch (true){
            case $reservation['payment_status'] == "Not Paid":
            case $reservation['payment_status'] == "Unpaid":
                $paymentStatus = "UNPAID";
                break;
            case $reservation['payment_status'] == "Partially Paid":
                $paymentStatus = "PARTIAL_PAID";
                break;
            case $reservation['payment_status'] == "Fully Paid":
                $paymentStatus = "PAID";
                break;
            case $reservation['payment_status'] == "Over Paid":
                $paymentStatus = "OVERPAID";
                break;
        }
        
        $cancelCustomerstatus = [ 
            "Customer canceled - No Reason applies",
            "Customer changed their mind",
            "Customer doesnot meet minimum age requirement",
            "Customer unable to make travel arrangements",
            "Customer unable to take vacation"];
        
        $reservationStatus = $reservation['iscancelled'] ? 'CANCELLED_BY_OWNER':'CONFIRMED';
        $reservationStatus = strlen($reservation['vrbo_cancelled_by']) > 0 ? 'CANCELLED_BY_TRAVELER' : $reservationStatus;
        $reservationStatus = "CONFIRMED";
        if($reservation['iscancelled']){
            if(in_array($reservation['cancel_reason'],$cancelCustomerstatus)){
                $reservationStatus = 'CANCELLED_BY_TRAVELER';
            }
            else{
                $reservationStatus = "CANCELLED_BY_OWNER";    
            }
        }

        $customers = json_decode($reservation['all_data_req'],true)['customers'];
        if(!isset($customers['adult'])){ $customers['adult'] = 0; }
        if($customers['adult'] == ""){ $customers['adult'] = 0; }
        if(!isset($customers['pets'])){ $customers['pets'] = 0; }
        if($customers['child'] == ""){ $customers['child'] = 0; }
        if(!isset($customers['child'])){ $customers['child'] = 0; }
        if($customers['pets'] == ""){ $customers['pets'] = 0; }
        $unit = $this->listingModel->getListing($reservation['unit_id'])[0];
        return $this->renderLayout('bookingUpdate.xml',[
            'config'=>$config,
            'cancel_policy_desc'=>$cancel_policy_desc,'payment_policy_desc'=>$payment_policy_desc,
            'unit'=>$unit,'reservationStatus'=>$reservationStatus,'customers'=>$customers,'paymentStatus'=>$paymentStatus,'reservation'=>$reservation,'guest'=>$guest,'orderItemList'=>$orderItemList,'paymentScheduleXML'=>$paymentScheduleXML
            
            ]);
    }
    public function bookingCanceltest(){
        $reservation = $this->reservationsModel->getReservationByBookingNumber("BKG-2229722");

        $this->reservationsModel->insertHistory($reservation[0]['id'],
            'Cancel Request Received - '.$reqData['cancellationCategory'].' - '.$reqData['cancellationReason'],
        );
        return $this->renderJson([
            'status'=>'SUCCESS'
        ]);

    }
    
    public function bookingCancel(){
        if(!$this->checkAuth($this->request)){ return $this->response->withStatus(401,'Unauthorized'); }

        $client = new Client([
            'base_uri'=>VRMANAGED_URL
        ]);
        // $reqData = $this->request->getParsedBody();
        $reqData = json_decode(file_get_contents('php://input'),true); // pr
        
        $bookingNumber = $reqData['reservationExternalId'];
        $reservation = $this->reservationsModel->getReservationByBookingNumber($bookingNumber);
//        print_r($reservation);die;
        if(count($reservation) == 0){
            return $this->response->withStatus(404,'Reservation Not Found');
        }
        $reservation = $reservation[0];
        
        $this->reservationsModel->insertHistory($reservation['id'],
            'Cancel Request Received - '.$reqData['cancellationCategory'].' - '.$reqData['cancellationReason'],
        );
        
        // $resp = $client->post('reservations/cancelreservation',[
        //     'form_params'=>[
        //         'id'=>$reservation['id'],
        //         'cancel_reason'=>"Other",
        //         'cancel_notes'=>$reqData['cancellationCategory'].' - '.$reqData['cancellationReason'],
        //         'cancellationDate'=>$reqData['cancellationDate']
        //     ]
        // ]);
        
        return $this->renderJson([
            'status'=>'SUCCESS'
        ]);
        
        if(strpos($resp->getBody()->getContents(), "successful") !== false){  // pr
        // if($resp->getBody()->getContents() == "successful"){
            $this->reservationsModel->updateCancelStatus($bookingNumber);
            return $this->renderJson([
                'status'=>'SUCCESS'
            ]);
        }
        else{
            return $this->renderJson([
                'status'=>'ERROR',
                'errorCode'=>'INTERNAL_SERVER_ERROR'
            ]);
        }
    }
    public function bookingCancelRA(){
        if(!$this->checkAuth($this->request)){ return $this->response->withStatus(401,'Unauthorized'); }

        $client = new Client([
            'base_uri'=>VRMANAGED_URL
        ]);
        // $reqData = $this->request->getParsedBody();
        $reqData = json_decode(file_get_contents('php://input'),true); // pr
        
        $bookingNumber = $reqData['reservationExternalId'];
        $reservation = $this->reservationsModel->getReservationByBookingNumber($bookingNumber);
//        print_r($reservation);die;
        if(count($reservation) == 0){
            return $this->response->withStatus(404,'Reservation Not Found');
        }
        $reservation = $reservation[0];
        
        $this->reservationsModel->insertHistory($reservation['id'],
            'Cancel Request Received - '.$reqData['cancellationCategory'].' - '.$reqData['cancellationReason'],
        );
        
        // $resp = $client->post('reservations/cancelreservation',[
        //     'form_params'=>[
        //         'id'=>$reservation['id'],
        //         'cancel_reason'=>"Other",
        //         'cancel_notes'=>$reqData['cancellationCategory'].' - '.$reqData['cancellationReason'],
        //         'cancellationDate'=>$reqData['cancellationDate']
        //     ]
        // ]);
        
        
        if(strpos($resp->getBody()->getContents(), "successful") !== false){  // pr
        // if($resp->getBody()->getContents() == "successful"){
            $this->reservationsModel->updateCancelStatus($bookingNumber);
            return $this->renderJson([
                'status'=>'SUCCESS'
            ]);
        }
        else{
            return $this->renderJson([
                'status'=>'ERROR',
                'errorCode'=>'INTERNAL_SERVER_ERROR'
            ]);
        }
    }
}