<?php

namespace App\Console\Commands\ChannelManager;

use App\Core\Mail\CancelBookingMail;
use App\Core\Mail\LogMail;
use App\Core\Mail\ModifiedBookingMail;
use App\Core\Service\BookingContactService;
use App\Core\Service\BookingPaymentService;
use App\Core\Service\BookingRoomService;
use App\Core\Service\BookingService;
use App\Core\Service\ChannelManager\Reseliva;
use App\Core\Service\ChannelManagerMappingService;
use App\Core\Service\ChannelManagerPropertyMappingService;
use App\Core\Service\ChannelManagerPropertyRateMappingService;
use App\Core\Service\NewBookingMailService;
use App\Core\Service\PropertyRoomAvailabilityService;
use App\Exceptions\ApiErrorException;
use Carbon\Carbon;
use GuzzleHttp\Client;
use Illuminate\Console\Command;
use Illuminate\Mail\Mailer;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

class ReservationPullService extends Command
{
    protected $signature = 'cron:reservation-pull-service';

    protected $description = '';
    protected $mailer;
    protected $channelService;
    protected $channelManagerPropertyMappingService;
    protected $bookingService;
    protected $propertyRoomAvailabilityService;
    protected $newBookingMailService;

    public function __construct(
        Mailer $mailer,
        Reseliva $channelService,
        ChannelManagerMappingService $channelManagerMappingService,
        ChannelManagerPropertyMappingService $channelManagerPropertyMappingService,
        BookingService $bookingService,
        BookingContactService $bookingContactService,
        BookingRoomService $bookingRoomService,
        BookingPaymentService $bookingPaymentService,
        PropertyRoomAvailabilityService $propertyRoomAvailabilityService,
        NewBookingMailService $newBookingMailService
    )
    {
        parent::__construct();
        $this->mailer = $mailer;
        $this->channelService = $channelService;
        $this->channelManagerMappingService = $channelManagerMappingService;
        $this->channelManagerPropertyMappingService = $channelManagerPropertyMappingService;
        $this->bookingService = $bookingService;
        $this->bookingContactService = $bookingContactService;
        $this->bookingRoomService = $bookingRoomService;
        $this->bookingPaymentService = $bookingPaymentService;
        $this->propertyRoomAvailabilityService = $propertyRoomAvailabilityService;
        $this->newBookingMailService = $newBookingMailService;
    }

    public function reservationListParam($channelManagerPropertyId)
    {

        $userId = Config::get('app.channelManager.reseliva.userId');
        $userPSW = Config::get('app.channelManager.reseliva.userPassword');

        $requestParam = new \SimpleXMLElement('<?xml version="1.0" encoding="UTF-8"?><request></request>');

        $Authentication = $requestParam->addChild('Authentication');
        $Authentication->addChild('UserID', $userId);
        $Authentication->addChild('UserPSW', $userPSW);
        $Authentication->addChild('PropertyID', $channelManagerPropertyId);

        return $requestParam->asXML();
    }

    public function reservationConfirmParam($propertyId, $channelManagerBookingId, $bookingCode)
    {

        $userId = Config::get('app.channelManager.reseliva.userId');
        $userPSW = Config::get('app.channelManager.reseliva.userPassword');

        $requestParam = new \SimpleXMLElement('<?xml version="1.0" encoding="UTF-8"?><request></request>');

        $Authentication = $requestParam->addChild('Authentication');
        $Authentication->addChild('UserID', $userId);
        $Authentication->addChild('UserPSW', $userPSW);
        $Authentication->addChild('PropertyID', $propertyId);

        $reservations = $requestParam->addChild('reservations');
        $reservation = $reservations->addChild('reservation');
        $reservation->addAttribute('reseliva_id', $channelManagerBookingId);
        $reservation->addAttribute('pms_id', $bookingCode);

        return $requestParam->asXML();
    }

    public function getDateByDay($dates = [])
    {

        $dateByDay = [];

        $diffInDays = Carbon::parse($dates['checkIn'])->floatDiffInDays(Carbon::parse($dates['checkOut']));

        for ($i = 0; $i < $diffInDays; $i++) {
            $dateByDay[] = Carbon::parse($dates['checkIn'])->addDay($i)->format('Y-m-d');
        }

        return $dateByDay;

    }

    public function createBooking($param)
    {

        $response = ['status' => false, 'message' => ''];

        DB::beginTransaction();

        try {

            $bookingCode = getCodeGenerate('BKG');
            $bookingStatus = 1;

            $roomRequest = [];
            foreach ($param['room'] as $room) {
                $roomRequest[] = [
                    'adults' => $room['totalpax'],
                    'children' => $room['totalchd'],
                    'age' => []
                ];
            }

            if (empty(fillOnUndefined($param, 'reservno_ota'))) {
                $param['reservno_ota'] = null;
            }


            $bookingCreateParam = [
                'property_id' => $param['property']['id'],
                'channel_id' => $param['property']['channel_id'],
                'booking_code' => $bookingCode,
                'channel_booking_code' => fillOnUndefined($param, 'reservno_ota'),
                'search_key' => $param['reservno'],
                'checkin_date' => $param['checkinFormatted'],
                'checkout_date' => $param['checkoutFormatted'],
                'rooms' => json_encode($roomRequest),
                'payment_type_code' => 'CHN',
                'room_amount' => $param['paymenttotal'],
                'addon_amount' => 0,
                'discount_amount' => 0,
                'total' => $param['paymenttotal'],
                'currency_code' => $param['paymentcurr'],
                'channel_token' => null,
                'booking_engine_token' => null,
                'reservation_time' => $param['restimeUnixFormatted'],
                'status' => $param['status'] == 'A' ? 1 : 0
            ];

            $bookingCreate = $this->bookingService->create($bookingCreateParam);
            //$bookingCreate['status'] = 'success';
            //$bookingCreate['data']['id'] = 52;

            if ($bookingCreate['status'] != 'success') {
                throw new ApiErrorException(lang('Booking could not be made, Reservation: ' . $param['reservno']));
            }

            //INSERT CONTACT DATA
            $bookingContactCreateParam = [
                'booking_id' => $bookingCreate['data']['id'],
                'name' => $param['firstname'],
                'surname' => !empty($param['lastname']) ? $param['lastname'] : null,
                'phone_code' => null,
                'phone_number' => $param['tel'],
                'email' => $param['email'],
                'note' => !empty($param['note']) ? $param['note'] : null,
                'language_code' => fillOnUndefined($param, 'language', 'en'),
                'status' => 1
            ];

            $bookingContactCreate = $this->bookingContactService->create($bookingContactCreateParam);
            //$bookingContactCreate['status'] = 'success';

            if ($bookingContactCreate['status'] != 'success') {
                throw new ApiErrorException(lang('Booking Contact could not be made'));
            }

            //INSERT ROOM DATA
            foreach ($param['room'] as $roomOrder => $room) {

                $bookingRoomCreateParam = [
                    'booking_id' => $bookingCreate['data']['id'],
                    'room_order_number' => ($roomOrder + 1),
                    'occupancy_code' => str_repeat('A', $room['totalpax']) . str_repeat('C', $room['totalchd']),
                    'checkin_date' => $param['checkinFormatted'], //$room['checkin'],
                    'checkout_date' => $param['checkoutFormatted'],//$room['checkout'],
                    'rate_key' => null,
                    'rate_key_code' => null,
                    'availability_id' => 1,
                    'availability_code' => 'ROM',
                    'room_id' => $room['property']['room_id'],
                    'room_name' => $room['roomtype'],
                    'room_rate_mapping_id' => $room['property']['room_rate_mapping_id'],
                    'room_rate_name' => $room['ratename'],
                    'cancellation_policy' => null,
                    'payment_type_code' => 'CHN',
                    'rate_detail' => json_encode($room),
                    'total' => $room['total_amount'],
                    'currency_code' => $param['paymentcurr'],
                    'status' => $param['status'] == 'A' ? 1 : 0
                ];

                $bookingRoomCreate = $this->bookingRoomService->create($bookingRoomCreateParam);
                //$bookingRoomCreate['status'] = 'success';

                if ($bookingRoomCreate['status'] != 'success') {
                    throw new ApiErrorException(lang('Booking Room could not be made'));
                }


                /* ROOM AVAILABILITY */
                $dateByDay = [];
                $dateByDay = $this->getDateByDay(['checkIn' => $room['checkin'], 'checkOut' => $room['checkout']]);
                foreach ($dateByDay as $day) {

                    $requestParam = [
                        'criteria' => [
                            ['field' => 'property_id', 'condition' => '=', 'value' => $param['property']['id']],
                            ['field' => 'property_room_id', 'condition' => '=', 'value' => $room['property']['room_id']],
                            ['field' => 'availability_type_id', 'condition' => '=', 'value' => 1],
                            ['field' => 'date', 'condition' => '=', 'value' => $day]
                        ],
                    ];

                    $getPropertyRoomAndRoomRateAvailability = $this->propertyRoomAvailabilityService->select($requestParam);

                    if ($getPropertyRoomAndRoomRateAvailability['status'] != 'success') {
                        throw new ApiErrorException('getPropertyRoomAndRoomRateAvailability Empty');
                    }

                    foreach ($getPropertyRoomAndRoomRateAvailability['data'] as $roomAvailability) {
                        $roomAvailabilityUpdated = $roomAvailability['availability'] <= 0 ? 0 : ($roomAvailability['availability'] - 1);
                        $this->propertyRoomAvailabilityService->update($roomAvailability['id'], ['availability' => $roomAvailabilityUpdated]);
                    }

                }

                /* ROOM AVAILABILITY */

            }

            //INSERT PAYMENT DATA
            $bookingPaymentCreateParam = [
                'booking_id' => $bookingCreate['data']['id'],
                'payment_code' => (isset($param['cc_token']) && !empty($param['cc_token'])) ? fillOnUndefined($param, 'cc_token') : null,
                'payment_type_code' => 'CHN',
                'total' => $param['paymenttotal'],
                'currency_code' => $param['paymentcurr'],
                'status' => 2
            ];

            $bookingPaymentCreate = $this->bookingPaymentService->create($bookingPaymentCreateParam);
            //$bookingContactCreate['status'] = 'success';

            if ($bookingPaymentCreate['status'] != 'success') {
                throw new ApiErrorException(lang('Booking Payment could not be made'));
            }
            //INSERT PAYMENT DATA

            //INSERT CHANNEL PAYMENT DATA
            if (isset($param['cc_token']) && !empty($param['cc_token'])) {

                $bookingPaymentDataCreateParam = [
                    'booking_id' => $bookingCreate['data']['id'],
                    'type' => 'ch',
                    'data' => md5($param['reservno'].$param['channelManagerPropertyId'].$param['cc_token'])
                ];

                $bookingPaymentDataCreate = $this->bookingPaymentService->createPaymentData($bookingPaymentDataCreateParam);

                if ($bookingPaymentDataCreate['status'] != 'success') {
                    throw new ApiErrorException(lang('Booking Payment could not be made'));
                }
            }
            //INSERT CHANNEL PAYMENT DATA


            //$param['reservno'] = '27145472222';
            $reservationConfirmParam = $this->reservationConfirmParam($param['channelManagerPropertyId'], $param['reservno'], $bookingCode);
            $reservationConfirm = $this->channelService->reservationConfirm($reservationConfirmParam);

            if (!$reservationConfirm['status']) {
                throw new ApiErrorException($reservationConfirm['message']);
            }

            DB::commit();

            $mailParams = ['booking_id' => $bookingCreate['data']['id']];
            $this->newBookingMailService->process($mailParams);

            $response['status'] = true;

        } catch (ApiErrorException $e) {
            $response['message'] = implode(', ', $e->getMessageArr());
        } catch (Exception $e) {
            $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage();
            Log::error($message);
            $response['message'] = $e->getMessage();
        }

        if (!$response['status']) {
            DB::rollBack();
        }

        return $response;

    }

    public function cancelBooking($param)
    {

        $response = ['status' => false, 'message' => ''];

        DB::beginTransaction();

        try {

            $bookingCode = null;

            $bookingDetailParam = [
                'criteria' => [
                    ['field' => 'property_id', 'condition' => '=', 'value' => $param['property']['id']],
                    ['field' => 'search_key', 'condition' => '=', 'value' => $param['reservno']]
                ],
                'with' => ['bookingRoom'],
                'firstRow' => true
            ];

            $bookingDetail = $this->bookingService->select($bookingDetailParam);

            if ($bookingDetail['status'] != 'success') {
                throw new ApiErrorException(lang('Booking could not be found, Reservation: ' . $param['reservno']));
            }

            if (!empty($bookingDetail['data'])) {

                $bookingCode = $bookingDetail['data']['booking_code'];

                $this->bookingService->update($bookingDetail['data']['id'], ['status' => 0]);

                foreach ($bookingDetail['data']['booking_room'] as $roomOrder => $room) {

                    $bookingRoomCreate = $this->bookingRoomService->update($room['id'], ['status' => 0]);


                    /* ROOM AVAILABILITY */
                    $dateByDay = [];
                    $dateByDay = $this->getDateByDay(['checkIn' => $room['checkin_date'], 'checkOut' => $room['checkout_date']]);
                    foreach ($dateByDay as $day) {

                        $requestParam = [
                            'criteria' => [
                                ['field' => 'property_id', 'condition' => '=', 'value' => $param['property']['id']],
                                ['field' => 'property_room_id', 'condition' => '=', 'value' => $room['room_id']],
                                ['field' => 'availability_type_id', 'condition' => '=', 'value' => 1],
                                ['field' => 'date', 'condition' => '=', 'value' => $day]
                            ],
                        ];

                        $getPropertyRoomAndRoomRateAvailability = $this->propertyRoomAvailabilityService->select($requestParam);

                        if ($getPropertyRoomAndRoomRateAvailability['status'] != 'success') {
                            throw new ApiErrorException('getPropertyRoomAndRoomRateAvailability Empty');
                        }

                        foreach ($getPropertyRoomAndRoomRateAvailability['data'] as $roomAvailability) {
                            $roomAvailabilityUpdated = $roomAvailability['availability'] <= 0 ? 1 : ($roomAvailability['availability'] + 1);
                            $this->propertyRoomAvailabilityService->update($roomAvailability['id'], ['availability' => $roomAvailabilityUpdated]);
                        }

                    }

                    /* ROOM AVAILABILITY */

                }

            }

            $response['status'] = true;

            $bookingCode = is_null($bookingCode) ? 'ENW' . $param['reservno'] : $bookingCode;

            $reservationConfirmParam = $this->reservationConfirmParam($param['channelManagerPropertyId'], $param['reservno'], $bookingCode);
            $reservationConfirm = $this->channelService->reservationConfirm($reservationConfirmParam);

            if (!$reservationConfirm['status']) {
                throw new ApiErrorException($reservationConfirm['message']);
            }

            $notificationCancelToPropertyUser = [
                'channel' => $param['otaname'],
                'channelBookingCode' => $param['reservno_ota'],
                'propertyChannelManager' => $param['otaname'],//$channelManagerMapping['property_channel_manager']['name'],
                'nameSurname' => $param['firstname'] . ' ' . $param['lastname'],
                'propertyId' => $param['property']['id'],
            ];

            $this->mailer->onQueue('cancelBookingMail', new CancelBookingMail($notificationCancelToPropertyUser));

        } catch (ApiErrorException $e) {
            $response['message'] = implode(', ', $e->getMessageArr());
        } catch (Exception $e) {
            $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage();
            Log::error($message);
            $response['message'] = $e->getMessage();
        }

        if ($response['status']) {

            DB::commit();

        } else {
            DB::rollBack();
        }

        return $response;

    }

    public function modifiedBooking($param)
    {

        $response = ['status' => false, 'message' => ''];

        DB::beginTransaction();

        try {

            $bookingCode = null;

            $bookingDetailParam = [
                'criteria' => [
                    ['field' => 'property_id', 'condition' => '=', 'value' => $param['property']['id']],
                    ['field' => 'search_key', 'condition' => '=', 'value' => $param['reservno']]
                ],
                'with' => ['bookingRoom', 'bookingContact'],
                'firstRow' => true
            ];

            $bookingDetail = $this->bookingService->select($bookingDetailParam);

            if ($bookingDetail['status'] != 'success') {
                throw new ApiErrorException(lang('Booking could not be found, Reservation: ' . $param['reservno']));
            }

            if (!empty($bookingDetail['data'])) {

                $bookingCode = $bookingDetail['data']['booking_code'];

                $bookingUpdateParam = [
                    'channel_booking_code' => fillOnUndefined($param, 'reservno_ota'),
                    'search_key' => $param['reservno'],
                    'checkin_date' => $param['checkinFormatted'],
                    'checkout_date' => $param['checkoutFormatted'],
                    'payment_type_code' => 'CHN',
                    'total' => $param['paymenttotal'],
                    'currency_code' => $param['paymentcurr'],
                ];

                $bookingUpdate = $this->bookingService->update($bookingDetail['data']['id'], $bookingUpdateParam);

                $bookingContactUpdateParam = [
                    'name' => $param['firstname'],
                    'surname' => $param['lastname'],
                    'phone_code' => null,
                    'phone_number' => $param['tel'],
                    'email' => $param['email'],
                    'note' => !empty($param['note']) ? $param['note'] : null,
                    'language_code' => fillOnUndefined($param, 'language', 'en')
                ];

                $bookingContactUpdate = $this->bookingContactService->update($bookingDetail['data']['booking_contact']['id'], $bookingContactUpdateParam);

                foreach ($bookingDetail['data']['booking_room'] as $roomOrder => $room) {

                    foreach ($param['room'] as $roomOrderChannel => $roomChannel) {

                        if ($roomOrder == $roomOrderChannel) {


                            $bookingRoomUpdateParam = [
                                'occupancy_code' => str_repeat('A', $roomChannel['totalpax']) . str_repeat('C', $roomChannel['totalchd']),
                                'checkin_date' => $roomChannel['checkin'],
                                'checkout_date' => $roomChannel['checkout'],
                                'room_id' => $roomChannel['property']['room_id'],
                                'room_name' => $roomChannel['roomtype'],
                                'room_rate_mapping_id' => $roomChannel['property']['room_rate_mapping_id'],
                                'room_rate_name' => $roomChannel['ratename'],
                                'rate_detail' => json_encode($roomChannel),
                                'total' => $roomChannel['total_amount'],
                                'currency_code' => $param['paymentcurr'],
                            ];

                            $bookingRoomUpdate = $this->bookingRoomService->update($room['id'], $bookingRoomUpdateParam);

                        }
                    }

                }

            }

            $response['status'] = true;

            $bookingCode = is_null($bookingCode) ? 'ENW' . $param['reservno'] : $bookingCode;

            $reservationConfirmParam = $this->reservationConfirmParam($param['channelManagerPropertyId'], $param['reservno'], $bookingCode);
            $reservationConfirm = $this->channelService->reservationConfirm($reservationConfirmParam);

            if (!$reservationConfirm['status']) {
                throw new ApiErrorException($reservationConfirm['message']);
            }

            $notificationModifiedToPropertyUser = [
                'channel' => $param['otaname'],
                'channelBookingCode' => $param['reservno_ota'],
                'propertyChannelManager' => $param['otaname'],//$channelManagerMapping['property_channel_manager']['name'],
                'nameSurname' => $param['firstname'] . ' ' . $param['lastname'],
                'propertyId' => $param['property']['id'],
            ];

            $this->mailer->onQueue('modifiedBookingMail', new ModifiedBookingMail($notificationModifiedToPropertyUser));

        } catch (ApiErrorException $e) {
            $response['message'] = implode(', ', $e->getMessageArr());
        } catch (Exception $e) {
            $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage();
            Log::error($message);
            $response['message'] = $e->getMessage();
        }

        if ($response['status']) {

            DB::commit();

        } else {
            DB::rollBack();
        }

        return $response;

    }

    public function handle()
    {
        //$request = $this->channelService->productList(14480);

        try {

            /*
             1. Reseliva mapping olan oteller  çekilecek
             2. Her otel için foreach ile reservaion servisi çağrılacak
            3. Gelen bilgiler enw ye işlenecek, sonra da confirmcheck yapılacak
             * */

            $this->info(date('Y-m-d H:i:s') . ' : Start');

            $channelManagerMappingCriteria =
                [
                    'criteria' =>
                        [
                            ['field' => 'status', 'condition' => '=', 'value' => 1],
                        ],
                    'with' => ['propertyChannelManager'],
                    'orderBy' => [
                        ['field' => 'id', 'value' => 'ASC']
                    ]
                ];

            $channelManagerMappingData = $this->channelManagerMappingService->select($channelManagerMappingCriteria);
            $channelManagerMappingCollect = collect($channelManagerMappingData['data']);

            $channelManagerPropertyMappingCriteria = [
                'criteria' =>
                    [
                        ['field' => 'status', 'condition' => '=', 'value' => 1],
                        ['field' => 'channel_manager_id', 'condition' => '=', 'value' => 1],
                        ['field' => 'channel_manager_property_id', 'condition' => '!=', 'value' => null],
                        //['field' => 'property_id', 'condition' => '=', 'value' => 326],//TODO: Delete
                    ],
                'with' => ['channelManagerRoomRate.propertyRoomRateMapping'],
                'orderBy' => [
                    ['field' => 'id', 'value' => 'ASC']
                ]
            ];

            $channelManagerPropertyMapping = $this->channelManagerPropertyMappingService->select($channelManagerPropertyMappingCriteria);

            if ($channelManagerPropertyMapping['status'] == 'success') {

                foreach ($channelManagerPropertyMapping['data'] as $propertyMapping) {

                    $channelManagerRoomRateCollect = collect($propertyMapping['channel_manager_room_rate']);

                    $reservationListParam = $this->reservationListParam($propertyMapping['channel_manager_property_id']);
                    $reservationList = $this->channelService->reservationList($reservationListParam);

                    if (!$reservationList['status']) {

                        //$logMessage
                        $mailParams = [
                            'title' => 'ReservationPullService Error - ReservationList Error',
                            'logMessage' => '<pre>' . $reservationListParam . '</pre>'
                        ];

                        $this->mailer->onQueue('logMail', new LogMail($mailParams));
                        //$logMessage

                        throw new ApiErrorException('ReservationList Error: ' . $reservationList['message']);
                    }

                    foreach ($reservationList['data'] as $reservationKey => $reservation) {

                        //Check Channel Manager Mapping
                        $channelManagerMapping = $channelManagerMappingCollect->where('channel_manager_channel_id', $reservation['otaname'])->first();

                        //Eğer ExtranetWork ise içeri almadan onayla
                        if ($reservation['otaname'] == 'ExtranetWork') {

                            $reservationConfirmParam = $this->reservationConfirmParam($propertyMapping['channel_manager_property_id'], $reservation['reservno'], 'ENWRES' . $reservation['reservno']);
                            //$reservationConfirm = $this->channelService->reservationConfirm($reservationConfirmParam);
                            $reservationConfirm['status'] = true;
                            if (!$reservationConfirm['status']) {
                                throw new ApiErrorException($reservationConfirm['message']);
                            }

                            continue;
                        }

                        if (empty($channelManagerMapping)) {
                            //Eğer mapping yapılmış kanal bulunamamış ise rezervasyonu içeri alamazsın
                            //$logMessage
                            $mailParams = [
                                'title' => 'ReservationPullService Error - Channel Manager Mapping',
                                'logMessage' => '<pre>' . print_r(array_merge($propertyMapping, $reservation), true) . '</pre>'
                            ];

                            $this->mailer->onQueue('logMail', new LogMail($mailParams));
                            //$logMessage

                            unset($reservationList['data'][$reservationKey]);
                            continue;
                        }

                        $reservationList['data'][$reservationKey]['property']['id'] = $propertyMapping['property_id'];
                        $reservationList['data'][$reservationKey]['property']['channel_id'] = $channelManagerMapping['property_channel_id'];

                        foreach ($reservation['room'] as $roomKey => $room) {

                            //Check Room Rate Mapping
                            $channelManagerRoomRate = $channelManagerRoomRateCollect->where('channel_manager_room_id', $room['roomid'])->where('channel_manager_room_rate_id', $room['rateid'])->first();
                            if (empty($channelManagerRoomRate)) {
                                $channelManagerRoomRate = $channelManagerRoomRateCollect->where('channel_manager_room_id', $room['roomid'])->first();
                            }

                            $reservationList['data'][$reservationKey]['room'][$roomKey]['property']['room_id'] = null;
                            $reservationList['data'][$reservationKey]['room'][$roomKey]['property']['room_rate_id'] = null;
                            $reservationList['data'][$reservationKey]['room'][$roomKey]['property']['room_rate_mapping_id'] = null;
                            $reservationList['data'][$reservationKey]['channelManagerPropertyId'] = $propertyMapping['channel_manager_property_id'];

                            if (empty($channelManagerRoomRate)) {
                                //Eğer mapping yapılmış oda bulunamamış ise rezervasyonu içeri alamazsın
                                //$logMessage
                                $mailParams = [
                                    'title' => 'ReservationPullService Error - Channel Manager Room Rate Mapping',
                                    'logMessage' => '<pre>' . print_r(array_merge($propertyMapping, $reservation), true) . '</pre>'
                                ];

                                $this->mailer->onQueue('logMail', new LogMail($mailParams));
                                //$logMessage
                                unset($reservationList['data'][$reservationKey]);
                                $this->error(date('Y-m-d H:i:s') . ' : Error: RoomRate Mapping Reservation: ' . $reservation['reservno']);


                                //Eşleşmeyen ve iptal edilen işlemin otele bildirilmesi.
                                if ($reservation['status'] == 'C') {

                                    $notificationCancelToPropertyUser = [
                                        'channel' => $reservation['otaname'],
                                        'channelBookingCode' => $reservation['reservno_ota'],
                                        'propertyChannelManager' => $channelManagerMapping['property_channel_manager']['name'],
                                        'nameSurname' => $reservation['firstname'] . ' ' . $reservation['lastname'],
                                        'propertyId' => $propertyMapping['property_id'],
                                    ];

                                    $this->mailer->onQueue('cancelBookingMail', new CancelBookingMail($notificationCancelToPropertyUser));

                                    $reservationConfirmParam = $this->reservationConfirmParam($propertyMapping['channel_manager_property_id'], $reservation['reservno'], 'ENWRES' . $reservation['reservno']);
                                    $reservationConfirm = $this->channelService->reservationConfirm($reservationConfirmParam);

                                    if (!$reservationConfirm['status']) {
                                        throw new ApiErrorException($reservationConfirm['message']);
                                    }

                                }

                            } else {
                                $reservationList['data'][$reservationKey]['room'][$roomKey]['property']['room_id'] = $channelManagerRoomRate['property_room_rate_mapping']['room_id'];
                                $reservationList['data'][$reservationKey]['room'][$roomKey]['property']['room_rate_id'] = $channelManagerRoomRate['property_room_rate_mapping']['room_rate_id'];
                                $reservationList['data'][$reservationKey]['room'][$roomKey]['property']['room_rate_mapping_id'] = $channelManagerRoomRate['property_room_rate_mapping']['id'];
                            }

                        }

                    }

                    foreach ($reservationList['data'] as $reservationKey => $reservation) {

                        //Eğer ExtranetWork ise içeri almadan onayla
                        if ($reservation['otaname'] == 'ExtranetWork') {

                            $reservationConfirmParam = $this->reservationConfirmParam($propertyMapping['channel_manager_property_id'], $reservation['reservno'], 'ENWRES' . $reservation['reservno']);
                            $reservationConfirm = $this->channelService->reservationConfirm($reservationConfirmParam);

                            if (!$reservationConfirm['status']) {
                                throw new ApiErrorException($reservationConfirm['message']);
                            }

                            continue;
                        }

                        $booking = ['status' => false, 'message' => ''];

                        if ($reservation['status'] == 'A') {
                            $booking = $this->createBooking($reservation);
                        } elseif ($reservation['status'] == 'C') {
                            $booking = $this->cancelBooking($reservation);
                        } elseif ($reservation['status'] == 'M') {
                            $booking = $this->modifiedBooking($reservation);
                        }

                        //M Modified kayıt bul güncelle ve sonra mail atılacak cancel ile aynı mail yapısı kullanılacak

                        if ($booking['status']) {
                            $this->info(date('Y-m-d H:i:s') . ' : Success: ' . $reservation['reservno']);
                        } else {

                            //$logMessage
                            $mailParams = [
                                'title' => 'ReservationPullService Error - Booking',
                                'logMessage' => '<pre>' . print_r(array_merge($booking, $reservation), true) . '</pre>'
                            ];

                            $this->mailer->onQueue('logMail', new LogMail($mailParams));
                            //$logMessage

                            $this->error(date('Y-m-d H:i:s') . ' : Error: ' . $booking['message']);
                        }


                    }

                }
            }


            $this->info(date('Y-m-d H:i:s') . ' : Finished');

        } catch (ApiErrorException $e) {
            $this->error(date('Y-m-d H:i:s') . ' : Error: ' . $e->getMessage());
        } catch
        (Exception $e) {
            $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage();
            Log::error($message);
            $this->error(date('Y-m-d H:i:s') . ' : Error: ' . $message);
        }

    }

}
