<?php

namespace App\Http\Controllers\V1;

use App\Core\Service\LanguageService;
use App\Core\Mail\InventoryActionMail;
use App\Core\Mail\InventoryPdfLinkMail;
use App\Core\Service\PropertyChannelGroupService;
use App\Core\Service\PropertyChannelMappingService;
use App\Core\Service\PropertyRoomRateChannelMappingService;
use App\Core\Service\PropertyRoomService;
use App\Http\Controllers\Controller;
use App\Core\Service\PropertyRoomRateMappingService;
use App\Core\Service\PropertyRoomRatePriceService;
use App\Core\Service\PropertyRoomAvailabilityService;
use Carbon\Carbon;
use Illuminate\Http\Request;

use Illuminate\Mail\Mailer;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Config;
use Exception;
use App\Exceptions\ApiErrorException;
use Illuminate\Support\Facades\DB;

class PropertyRoomRateMappingController
{


    private $request;
    private $propertyRoomRateMappingService;
    private $propertyRoomRatePriceService;
    private $propertyRoomAvailabilityService;
    private $actionTitleByKey;


    public function __construct(
        Request $request,
        PropertyRoomRateMappingService $propertyRoomRateMappingService,
        PropertyRoomAvailabilityService $propertyRoomAvailabilityService,
        PropertyRoomRatePriceService $propertyRoomRatePriceService,
        PropertyChannelGroupService $propertyChannelGroupService,
        PropertyChannelMappingService $propertyChannelMappingService,
        PropertyRoomRateChannelMappingService $propertyRoomRateChannelMappingService,
        PropertyRoomService $propertyRoomService,
        Mailer $mailer,
        LanguageService $languageService
    )
    {
        $this->request = $request;
        $this->propertyRoomRateMappingService = $propertyRoomRateMappingService;
        $this->propertyRoomRatePriceService = $propertyRoomRatePriceService;
        $this->propertyRoomAvailabilityService = $propertyRoomAvailabilityService;
        $this->propertyChannelGroupService = $propertyChannelGroupService;
        $this->propertyChannelMappingService = $propertyChannelMappingService;
        $this->propertyRoomRateChannelMappingService = $propertyRoomRateChannelMappingService;
        $this->propertyRoomService = $propertyRoomService;
        $this->mailer = $mailer;
        $this->languageService = $languageService;

        $this->actionTitleByKey = [
            'PRC' => [
                'title' => 'Price',
                'language_key' => 'enw-action-title-price',
            ],
            'AVA' => [
                'title' => 'Availability',
                'language_key' => 'enw-action-title-availability',
            ],
            'STS' => [
                'title' => 'Stop Sell',
                'language_key' => 'enw-action-title-stop_sell',
            ],
            'MNS' => [
                'title' => 'Min Stay',
                'language_key' => 'enw-action-title-min_stay',
            ]
        ];

    }


    public function getPropertyRoomRateMapping(Request $request)
    {

        $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500];
        try {

            if (is_null($this->request->getContent())) {
                throw new ApiErrorException(lang('Parameter Error.'));
            }

            $params = $this->request->params;

            $requestParams = [
                'locale' => fillOnUndefined($params, 'locale'),
                'property_id' => fillOnUndefined($params, 'property_id'),
                'room_id' => fillOnUndefined($params, 'room_id'),
            ];

            $propertyRoomRateMapping = $this->propertyRoomRateMappingService->getPropertyRoomRateMapping($requestParams);
            if ($propertyRoomRateMapping['status'] != 'success') {
                throw new ApiErrorException($propertyRoomRateMapping['message']);
            }

            $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyRoomRateMapping['data']];

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


    }

    public function addPropertyRoomRateMapping(Request $request)
    {

        $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500];
        try {

            if (is_null($this->request->getContent())) {
                throw new ApiErrorException(lang('Parameter Error.'));
            }

            $params = $this->request->params;

            $requestParams = [
                'locale' => fillOnUndefined($params, 'locale'),
                'property_id' => fillOnUndefined($params, 'property_id'),
                'room_id' => fillOnUndefined($params, 'room_id'),
                'room_rate_id' => fillOnUndefined($params, 'room_rate_id'),
                'description' => fillOnUndefined($params, 'description'),
                'rack_rate' => fillOnUndefined($params, 'rack_rate'),
                'included_occupancy' => fillOnUndefined($params, 'included_occupancy'),
                'user_id' => $this->request->auth->id,
            ];


            $propertyRoomRateMapping = $this->propertyRoomRateMappingService->addPropertyRoomRateMapping($requestParams);
            if ($propertyRoomRateMapping['status'] != 'success') {
                throw new ApiErrorException($propertyRoomRateMapping['message']);
            }

            $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyRoomRateMapping['data']];

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


    }

    public function addPropertyRoomRateMappingWithSetup(Request $request)
    {

        $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500];
        try {

            if (is_null($this->request->getContent())) {
                throw new ApiErrorException(lang('Parameter Error.'));
            }

            $params = $this->request->params;

            $requestParams = [
                'locale' => fillOnUndefined($params, 'locale'),
                'property_id' => fillOnUndefined($params, 'property_id'),
                'room_id' => fillOnUndefined($params, 'room_id'),
                'room_rate_id' => fillOnUndefined($params, 'room_rate_id'),
                'rack_rate' => fillOnUndefined($params, 'rack_rate'),
                'included_occupancy' => fillOnUndefined($params, 'included_occupancy'),
                'room_rate_mapping_setup' => [
                    [
                        'setup_type' => 'EXT_ADULT',
                        'value_type' => fillOnUndefined($params, 'ext_adult_type'),
                        'value' => fillOnUndefined($params, 'ext_adult_rate'),
                    ],

                    [
                        'setup_type' => 'EXT_CHILD',
                        'value_type' => fillOnUndefined($params, 'ext_child_type'),
                        'value' => fillOnUndefined($params, 'ext_child_rate'),
                    ],

                    [
                        'setup_type' => 'DIS_GUEST',
                        'value_type' => fillOnUndefined($params, 'dis_guest_type'),
                        'value' => fillOnUndefined($params, 'dis_guest_rate'),
                    ],


                ],
                'user_id' => $this->request->auth->id,
            ];


            $propertyRoomRateMapping = $this->propertyRoomRateMappingService->addPropertyRoomRateMappingWithSetup($requestParams);
            if ($propertyRoomRateMapping['status'] != 'success') {
                throw new ApiErrorException($propertyRoomRateMapping['message']);
            }

            $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyRoomRateMapping['data']];

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


    }

    public function updatePropertyRoomRateMapping(Request $request)
    {

        $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500];
        try {

            if (is_null($this->request->getContent())) {
                throw new ApiErrorException(lang('Parameter Error.'));
            }

            $params = $this->request->params;

            $requestParams = [

                'locale' => fillOnUndefined($params, 'locale'),
                'id' => fillOnUndefined($params, 'id'),
                'property_id' => fillOnUndefined($params, 'property_id'),
                'room_id' => fillOnUndefined($params, 'room_id'),
                'room_rate_id' => fillOnUndefined($params, 'room_rate_id'),
                'description' => fillOnUndefined($params, 'description'),
                'rack_rate' => fillOnUndefined($params, 'rack_rate'),
                'included_occupancy' => fillOnUndefined($params, 'included_occupancy'),

                'user_id' => $this->request->auth->id,
            ];


            if (isset($params['status'])) {
                $requestParams['status'] = fillOnUndefined($params, "status", 0);
            }
            $propertyRoomRateMapping = $this->propertyRoomRateMappingService->updatePropertyRoomRateMapping($requestParams);
            if ($propertyRoomRateMapping['status'] != 'success') {
                throw new ApiErrorException($propertyRoomRateMapping['message']);
            }

            $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyRoomRateMapping['data']];

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


    }

    public function deletePropertyRoomRateMapping(Request $request)
    {

        $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500];
        try {

            if (is_null($this->request->getContent())) {
                throw new ApiErrorException(lang('Parameter Error.'));
            }

            $params = $this->request->params;

            $requestParams = [

                'id' => fillOnUndefined($params, 'id'),
                'user_id' => $this->request->auth->id,

            ];

            $propertyRoomRateMapping = $this->propertyRoomRateMappingService->deletePropertyRoomRateMapping($requestParams);
            if ($propertyRoomRateMapping['status'] != 'success') {
                throw new ApiErrorException($propertyRoomRateMapping['message']);
            }

            $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyRoomRateMapping['data']];

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


    }

    public function channelGroupRoomRateAvailabilityMappingBulkUpdate($requestParams = [])
    {

        $channelGroupChannels = [];
        $channelGroupCriteria = [
            'criteria' => [
                ['field' => 'id', 'condition' => '=', 'value' => $requestParams['channel_group_id']],
                ['field' => 'property_id', 'condition' => '=', 'value' => $requestParams['property_id']],
                ['field' => 'status', 'condition' => '=', 'value' => 1],
            ],
            'firstRow' => true,
            'with' => ['channelGroupActiveChannels']
        ];

        $channelGroup = $this->propertyChannelGroupService->select($channelGroupCriteria);

        if ($channelGroup['status'] == 'success') {
            $channelGroupChannels = $channelGroup['data']['channel_group_active_channels'];
        }

        $paramsListChannel = [];
        foreach ($channelGroupChannels as $channel) {


            $propertyChannelMappingCriteria = [
                'criteria' => [
                    ['field' => 'property_id', 'condition' => '=', 'value' => $requestParams['property_id']],
                    ['field' => 'channel_id', 'condition' => '=', 'value' => $channel['channel_id']],
                    ['field' => 'status', 'condition' => '=', 'value' => 1],
                ],
                'firstRow' => true
            ];

            $propertyChannelMapping = $this->propertyChannelMappingService->select($propertyChannelMappingCriteria);
            if ($propertyChannelMapping['status'] != 'success') {
                continue;
            }


            $propertyRoomRateChannelMappingCriteria = [
                'criteria' => [
                    ['field' => 'property_id', 'condition' => '=', 'value' => $requestParams['property_id']],
                    ['field' => 'channel_id', 'condition' => '=', 'value' => $channel['channel_id']],
                    ['field' => 'status', 'condition' => '=', 'value' => 1],
                ]
            ];

            $propertyRoomRateChannelMapping = $this->propertyRoomRateChannelMappingService->select($propertyRoomRateChannelMappingCriteria);
            if ($propertyChannelMapping['status'] != 'success') {
                continue;
            }

            $propertyRoomRateChannelMappingCollect = collect($propertyRoomRateChannelMapping['data']);

            if ($requestParams['update_type'] == 'rate') {


                foreach ($requestParams['room_rates'] as $roomRate) {

                    $value = null;
                    $roomRates = [];

                    //currency_code check
                    if ($roomRate['currency'] == $propertyChannelMapping['data']['currency_code']) {

                        //room_rate_mapping_id check
                        if ($propertyRoomRateChannelMappingCollect->where('room_rate_mapping_id', $roomRate['room_rate_mapping_id'])->isNotEmpty()) {

                            $value = $roomRate['value'];
                            $roomRates[] = [
                                'room_id' => $roomRate['room_id'],
                                'room_rate_mapping_id' => [
                                    $roomRate['room_rate_mapping_id']
                                ],
                            ];

                        }

                    }

                    if (is_null($value) || empty($roomRate)) {
                        continue;
                    }

                    $paramsListChannel[] = [
                        'locale' => fillOnUndefined($requestParams, 'locale'),
                        'property_id' => fillOnUndefined($requestParams, 'property_id'),
                        'update_type' => fillOnUndefined($requestParams, 'update_type'),
                        'value' => $value,
                        'channel_id' => fillOnUndefined($channel, 'channel_id'),
                        'availability_type_id' => fillOnUndefined($requestParams, 'availability_type_id', 1),
                        'room_rates' => $roomRates,
                        'start_date' => fillOnUndefined($requestParams, 'start_date'),
                        'end_date' => fillOnUndefined($requestParams, 'end_date'),
                        'include_days' => fillOnUndefined($requestParams, 'include_days'),
                        'user_id' => $this->request->auth->id,
                    ];


                }

            } elseif (in_array($requestParams['update_type'], ['min_stay', 'rate_stop_sell'])) {

                foreach ($requestParams['room_rates'] as $roomRate) {

                    $value = null;
                    $roomRates = [];

                    //room_rate_mapping_id check
                    if ($propertyRoomRateChannelMappingCollect->where('room_rate_mapping_id', $roomRate['room_rate_mapping_id'])->isNotEmpty()) {

                        $value = $roomRate['value'];
                        $roomRates[] = [
                            'room_id' => $roomRate['room_id'],
                            'room_rate_mapping_id' => [
                                $roomRate['room_rate_mapping_id']
                            ],
                        ];

                    }


                    if (is_null($value) || empty($roomRate)) {
                        continue;
                    }

                    $paramsListChannel[] = [
                        'locale' => fillOnUndefined($requestParams, 'locale'),
                        'property_id' => fillOnUndefined($requestParams, 'property_id'),
                        'update_type' => fillOnUndefined($requestParams, 'update_type'),
                        'value' => $value,
                        'channel_id' => fillOnUndefined($channel, 'channel_id'),
                        'availability_type_id' => fillOnUndefined($requestParams, 'availability_type_id', 1),
                        'room_rates' => $roomRates,
                        'start_date' => fillOnUndefined($requestParams, 'start_date'),
                        'end_date' => fillOnUndefined($requestParams, 'end_date'),
                        'include_days' => fillOnUndefined($requestParams, 'include_days'),
                        'user_id' => $this->request->auth->id,
                    ];

                }


            }


        }

        //dd($paramsListChannel, $requestParams);

        return $paramsListChannel;
    }

    public function bulkUpdate(Request $request)
    {

        $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500];
        try {
            DB::beginTransaction();

            if (is_null($this->request->getContent())) {
                throw new ApiErrorException(lang('Parameter Error.'));
            }

            $params = $this->request->params;


            if (!Carbon::parse($params['start_date'])->lessThanOrEqualTo(Carbon::parse($params['end_date']))) {
                throw new ApiErrorException(lang('api-error-update-start_end_date_diff'));
            }

            $paramsListChannel = [];
            if (isset($params['channel_group_id'])) {

                if (Carbon::parse($params['start_date'])->diffInDays(Carbon::parse($params['end_date'])) > 365) {
                    throw new ApiErrorException(lang('api-error-update-date_month'));
                }

                $paramsListChannel = $this->channelGroupRoomRateAvailabilityMappingBulkUpdate($params);

            } elseif (isset($params['channel_id'])) {

                //CONNECTED CHANNEL RATE CHECK
                $currentChannelCriteria = [
                    'criteria' => [
                        ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']],
                        ['field' => 'channel_id', 'condition' => '=', 'value' => $params['channel_id']],
                        ['field' => 'status', 'condition' => '=', 'value' => 1],
                    ],
                    'firstRow' => true,
                    'with' => ['channel']
                ];

                $currentChannel = $this->propertyChannelMappingService->select($currentChannelCriteria);
                if ($currentChannel['status'] != 'success') {
                    throw new ApiErrorException($currentChannel['message']);
                }

                $currentChannel = $currentChannel['data'];

                if (!is_null($currentChannel['connected_channel_id'])) {
                    throw new ApiErrorException('Channel prices linked to a channel cannot be updated.');
                }
                //CONNECTED CHANNEL RATE CHECK

                $paramsListChannel[] = [
                    'locale' => fillOnUndefined($params, 'locale'),
                    'property_id' => fillOnUndefined($params, 'property_id'),
                    'update_type' => fillOnUndefined($params, 'update_type'),
                    'value' => fillOnUndefined($params, 'value'),
                    'channel_id' => fillOnUndefined($params, 'channel_id'),
                    'availability_type_id' => fillOnUndefined($params, 'availability_type_id', 1),
                    'room_rates' => fillOnUndefined($params, 'room_rates'),
                    'start_date' => fillOnUndefined($params, 'start_date'),
                    'end_date' => fillOnUndefined($params, 'end_date'),
                    'include_days' => fillOnUndefined($params, 'include_days'),
                    'user_id' => $this->request->auth->id,
                ];


                //CONNECTED CHANNEL RATE UPDATE
                if (in_array($params['update_type'], ['rate', 'rate_by_rate', 'rate_stop_sell', 'min_stay', 'quick_pricing'])) {
                    $propertyChannelMappingCriteria = [
                        'criteria' => [
                            ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']],
                            ['field' => 'connected_channel_id', 'condition' => '=', 'value' => $params['channel_id']],
                            ['field' => 'status', 'condition' => '=', 'value' => 1],
                        ],
                        'with' => ['channel']
                    ];

                    $propertyChannelMapping = $this->propertyChannelMappingService->select($propertyChannelMappingCriteria);
                    if ($propertyChannelMapping['status'] == 'success') {

                        foreach ($propertyChannelMapping['data'] as $channel) {

                            if (!is_null($channel['channel']['parent_id'])) {
                                continue;
                            }

                            $paramsListChannel[] = [
                                'locale' => fillOnUndefined($params, 'locale'),
                                'property_id' => fillOnUndefined($params, 'property_id'),
                                'update_type' => fillOnUndefined($params, 'update_type'),
                                'value' => fillOnUndefined($params, 'value'),
                                'channel_id' => $channel['channel_id'],
                                'availability_type_id' => fillOnUndefined($params, 'availability_type_id', 1),
                                'room_rates' => fillOnUndefined($params, 'room_rates'),
                                'start_date' => fillOnUndefined($params, 'start_date'),
                                'end_date' => fillOnUndefined($params, 'end_date'),
                                'include_days' => fillOnUndefined($params, 'include_days'),
                                'user_id' => $this->request->auth->id,
                            ];

                        }

                    }
                }
                //CONNECTED CHANNEL RATE UPDATE

            }


            if (in_array($params['update_type'], ['rate'])) {


                //CONNECTED RATE
                $roomRates = collect($params['room_rates']);
                $propertyRoomIds = $roomRates->pluck('room_id')->toArray();
                $propertyRoomIds = array_unique($propertyRoomIds);

                $propertyRoomRateMappingCriteria = [
                    'criteria' => [
                        ['field' => 'status', 'condition' => '=', 'value' => 1],
                    ],
                    'whereIn' => [
                        ['field' => 'room_id', 'value' => $propertyRoomIds]
                    ]
                ];

                $propertyRoomRateMapping = $this->propertyRoomRateMappingService->select($propertyRoomRateMappingCriteria);
                $propertyRoomRateMapping = $propertyRoomRateMapping['status'] == 'success' ? $propertyRoomRateMapping['data'] : [];
                $propertyRoomRateMapping = collect($propertyRoomRateMapping);

                $connectedRoomRateBulk = [];
                foreach ($params['room_rates'] as $roomRateKey => $roomRate) {

                    $currentRoomRateIds = $propertyRoomRateMapping->whereIn('id', $roomRate['room_rate_mapping_id'])->pluck('room_rate_id')->toArray();

                    $propertyRoomRateConnectedList = $propertyRoomRateMapping->where('room_id', $roomRate['room_id'])->whereIn('connected_rate_id', $currentRoomRateIds)->toArray();

                    if (empty($propertyRoomRateConnectedList)) {
                        continue;
                    }

                    foreach ($propertyRoomRateConnectedList as $propertyRoomRateConnected) {

                        $roomRateConnectedRoomRates = [];
                        $roomRateConnectedAmount = $params['value'];

                        $amountAffected = 0;
                        if ($propertyRoomRateConnected['is_affected_price']) {
                            if ($propertyRoomRateConnected['affect_price_type'] == 'PER') {
                                $amountAffected = ($roomRateConnectedAmount * $propertyRoomRateConnected['affect_price_value']) / 100;
                            } elseif ($propertyRoomRateConnected['affect_price_type'] == 'FIX') {
                                $amountAffected = $propertyRoomRateConnected['affect_price_value'];
                            }

                            if ($propertyRoomRateConnected['affect_price_action_type'] == 'INC') {
                                $roomRateConnectedAmount = $roomRateConnectedAmount + $amountAffected;
                            }

                            if ($propertyRoomRateConnected['affect_price_action_type'] == 'DEC') {
                                $roomRateConnectedAmount = $roomRateConnectedAmount - $amountAffected;
                            }
                        }

                        $roomRateConnectedAmount = $roomRateConnectedAmount == 0 ? "0" : $roomRateConnectedAmount;

                        $roomRateConnectedRoomRates[] = [
                            'room_id' => $propertyRoomRateConnected['room_id'],
                            'room_rate_mapping_id' => [$propertyRoomRateConnected['id']],
                        ];

                        foreach ($paramsListChannel as $channelParam) {
                            $connectedRoomRateBulk[] = [
                                'locale' => fillOnUndefined($params, 'locale'),
                                'property_id' => fillOnUndefined($params, 'property_id'),
                                'update_type' => fillOnUndefined($params, 'update_type'),
                                'value' => $roomRateConnectedAmount,
                                'channel_id' => $channelParam['channel_id'],
                                'availability_type_id' => fillOnUndefined($params, 'availability_type_id', 1),
                                'room_rates' => $roomRateConnectedRoomRates,
                                'start_date' => fillOnUndefined($params, 'start_date'),
                                'end_date' => fillOnUndefined($params, 'end_date'),
                                'include_days' => fillOnUndefined($params, 'include_days'),
                                'user_id' => $this->request->auth->id,
                            ];
                        }

                    }

                }

                if (!empty($connectedRoomRateBulk)) {
                    $paramsListChannel = array_merge($paramsListChannel, $connectedRoomRateBulk);
                }

            }

            //CONNECTED RATE

            foreach ($paramsListChannel as $channelParam) {


                $requestParams = [
                    'locale' => fillOnUndefined($channelParam, 'locale'),
                    'property_id' => fillOnUndefined($channelParam, 'property_id'),
                    'update_type' => fillOnUndefined($channelParam, 'update_type'),
                    'value' => fillOnUndefined($channelParam, 'value'),
                    'channel_id' => fillOnUndefined($channelParam, 'channel_id'),
                    'availability_type_id' => fillOnUndefined($channelParam, 'availability_type_id', 1),
                    'room_rates' => fillOnUndefined($channelParam, 'room_rates'),
                    'start_date' => fillOnUndefined($channelParam, 'start_date'),
                    'end_date' => fillOnUndefined($channelParam, 'end_date'),
                    'include_days' => fillOnUndefined($channelParam, 'include_days'),
                    'user_id' => $this->request->auth->id,
                ];

                $propertyRoomRateMapping = [];
                if ($requestParams['update_type'] == 'availability' || $requestParams['update_type'] == 'room_stop_sell') {
                    $propertyRoomRateMapping = $this->propertyRoomAvailabilityService->bulkUpdate($requestParams);
                } elseif ($requestParams['update_type'] == 'rate_by_rate') {

                    $roomRatesPriceGroup = [];
                    foreach ($requestParams['room_rates'] as $roomRateMapping) {
                        foreach ($roomRateMapping['room_rate_mapping_id'] as $roomRates) {
                            foreach ($roomRates as $roomRateMappingId => $roomRatePrice) {
                                $roomRatePriceHashed = md5($roomRatePrice);
                                $roomRatesPriceGroup[$roomRatePriceHashed]['amount'] = $roomRatePrice;
                                $roomRatesPriceGroup[$roomRatePriceHashed]['roomRates'][$roomRateMapping['room_id']][$roomRateMappingId] = [
                                    'roomId' => $roomRateMapping['room_id'],
                                    'roomRateMappingId' => $roomRateMappingId
                                ];
                            }
                        }
                    }

                    foreach ($roomRatesPriceGroup as $roomRatesPrice) {

                        $requestParams['room_rates'] = [];
                        $requestParams['value'] = $roomRatesPrice['amount'];
                        $requestParams['update_type'] = 'rate';

                        $roomRateKey = 0;
                        foreach ($roomRatesPrice['roomRates'] as $roomId => $roomRates) {
                            foreach ($roomRates as $roomRateMappingId => $roomRate) {
                                $requestParams['room_rates'][$roomRateKey]['room_id'] = $roomId;
                                $requestParams['room_rates'][$roomRateKey]['room_rate_mapping_id'][] = $roomRateMappingId;
                            }
                            $roomRateKey++;
                        }

                        $propertyRoomRateMapping = $this->propertyRoomRatePriceService->bulkUpdate($requestParams);

                    }

                } else {

                    $propertyRoomRateMapping = $this->propertyRoomRatePriceService->bulkUpdate($requestParams);
                }

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


            }


            $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyRoomRateMapping['data']];

            DB::commit();

            //$roomRateAvailabilityUpdateNotification
            foreach ($paramsListChannel as $channelParam) {
                $roomRateAvailabilityUpdateNotification = $this->roomRateAvailabilityBulkUpdateNotification($channelParam);
            }


        } catch (ApiErrorException $e) {
            $response['message'] = implode(', ', $e->getMessageArr());
            $response['statusCode'] = 400;
            DB::rollBack();
        } catch (Exception $e) {
            $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage();
            Log::error($message);
            $response['message'] = $e->getMessage();
            $response['statusCode'] = 500;
            DB::rollBack();
        }
        return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']);


    }


    public function channelGroupRoomRateAvailabilityMapping($requestParams = [])
    {

        //PRC_1_1_1_20210424
        //availability_type_id, room_id, room_rate_mapping_id, date

        $channelGroupChannels = [];
        $channelGroupCriteria = [
            'criteria' => [
                ['field' => 'id', 'condition' => '=', 'value' => $requestParams['channel_group_id']],
                ['field' => 'property_id', 'condition' => '=', 'value' => $requestParams['property_id']],
                ['field' => 'status', 'condition' => '=', 'value' => 1],
            ],
            'firstRow' => true,
            'with' => ['channelGroupActiveChannels']
        ];

        $channelGroup = $this->propertyChannelGroupService->select($channelGroupCriteria);

        if ($channelGroup['status'] == 'success') {
            $channelGroupChannels = $channelGroup['data']['channel_group_active_channels'];
        }

        $paramsListChannel = [];
        foreach ($channelGroupChannels as $channel) {


            $propertyChannelMappingCriteria = [
                'criteria' => [
                    ['field' => 'property_id', 'condition' => '=', 'value' => $requestParams['property_id']],
                    ['field' => 'channel_id', 'condition' => '=', 'value' => $channel['channel_id']],
                    ['field' => 'status', 'condition' => '=', 'value' => 1],
                ],
                'firstRow' => true
            ];

            $propertyChannelMapping = $this->propertyChannelMappingService->select($propertyChannelMappingCriteria);
            if ($propertyChannelMapping['status'] != 'success') {
                continue;
            }


            $propertyRoomRateChannelMappingCriteria = [
                'criteria' => [
                    ['field' => 'property_id', 'condition' => '=', 'value' => $requestParams['property_id']],
                    ['field' => 'channel_id', 'condition' => '=', 'value' => $channel['channel_id']],
                    ['field' => 'status', 'condition' => '=', 'value' => 1],
                ]
            ];

            $propertyRoomRateChannelMapping = $this->propertyRoomRateChannelMappingService->select($propertyRoomRateChannelMappingCriteria);
            if ($propertyChannelMapping['status'] != 'success') {
                continue;
            }

            $propertyRoomRateChannelMappingCollect = collect($propertyRoomRateChannelMapping['data']);


            $roomRateAvailabilityMapping = [];
            foreach ($requestParams['data'] as $roomRateKey => $roomRateValue) {

                $roomRateKeyParsed = explode('_', $roomRateKey);

                $roomRateKeyArray['type'] = $roomRateKeyParsed[0];
                $roomRateKeyArray['availabilityId'] = $roomRateKeyParsed[1];
                $roomRateKeyArray['roomId'] = $roomRateKeyParsed[2];
                $roomRateKeyArray['roomRateMappingId'] = $roomRateKeyParsed[3];
                $roomRateKeyArray['date'] = $roomRateKeyParsed[4];
                $roomRateKeyArray['currencyCode'] = $roomRateKeyParsed[0] == 'PRC' && isset($roomRateKeyParsed[5]) ? $roomRateKeyParsed[5] : null;

                if ($roomRateKeyArray['type'] == 'PRC') {

                    //currency_code check
                    if (!is_null($roomRateKeyArray['currencyCode']) && $roomRateKeyArray['currencyCode'] == $propertyChannelMapping['data']['currency_code']) {

                        //room_rate_mapping_id check
                        if ($propertyRoomRateChannelMappingCollect->where('room_rate_mapping_id', $roomRateKeyArray['roomRateMappingId'])->isNotEmpty()) {
                            unset($roomRateKeyArray['currencyCode']);
                            $roomRateKey = implode('_', $roomRateKeyArray);
                            $roomRateAvailabilityMapping[$roomRateKey] = $roomRateValue;
                        }

                    }

                } elseif (in_array($roomRateKeyArray['type'], ['STS', 'MNS'])) {

                    if ($roomRateKeyArray['roomRateMappingId'] != 0) {

                        //room_rate_mapping_id check
                        if ($propertyRoomRateChannelMappingCollect->where('room_rate_mapping_id', $roomRateKeyArray['roomRateMappingId'])->isNotEmpty()) {
                            $roomRateAvailabilityMapping[$roomRateKey] = $roomRateValue;
                        }

                    } else {
                        $roomRateAvailabilityMapping[$roomRateKey] = $roomRateValue;
                    }

                } else {
                    $roomRateAvailabilityMapping[$roomRateKey] = $roomRateValue;
                }

            }

            if (!empty($roomRateAvailabilityMapping)) {
                $paramsListChannel[] = [
                    'locale' => fillOnUndefined($requestParams, 'locale'),
                    'property_id' => fillOnUndefined($requestParams, 'property_id'),
                    'channel_id' => fillOnUndefined($channel, 'channel_id'),
                    'rates' => $roomRateAvailabilityMapping,
                    'user_id' => $this->request->auth->id,
                ];
            }

        }

        //dd($paramsListChannel, $requestParams);

        return $paramsListChannel;
    }

    public function roomRateAvailabilityUpdate(Request $request)
    {

        $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500];
        try {

            DB::beginTransaction();


            if (is_null($this->request->getContent())) {
                throw new ApiErrorException(lang('Parameter Error.'));
            }

            $params = $this->request->params;

            $paramsListChannel = [];
            if (isset($params['channel_group_id'])) {

                $paramsListChannel = $this->channelGroupRoomRateAvailabilityMapping($params);

            } elseif (isset($params['channel_id'])) {


                //CONNECTED CHANNEL RATE CHECK
                $currentChannelCriteria = [
                    'criteria' => [
                        ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']],
                        ['field' => 'channel_id', 'condition' => '=', 'value' => $params['channel_id']],
                        ['field' => 'status', 'condition' => '=', 'value' => 1],
                    ],
                    'firstRow' => true,
                    'with' => ['channel']
                ];

                $currentChannel = $this->propertyChannelMappingService->select($currentChannelCriteria);
                if ($currentChannel['status'] != 'success') {
                    throw new ApiErrorException($currentChannel['message']);
                }

                $currentChannel = $currentChannel['data'];

                if (!is_null($currentChannel['connected_channel_id'])) {
                    throw new ApiErrorException('Channel prices linked to a channel cannot be updated.');
                }
                //CONNECTED CHANNEL RATE CHECK

                $paramsListChannel[] = [
                    'locale' => fillOnUndefined($params, 'locale'),
                    'property_id' => fillOnUndefined($params, 'property_id'),
                    'channel_id' => fillOnUndefined($params, 'channel_id'),
                    'rates' => fillOnUndefined($params, 'data'),
                    'user_id' => $this->request->auth->id,
                ];

                //CONNECTED CHANNEL RATE UPDATE
                $propertyChannelMappingCriteria = [
                    'criteria' => [
                        ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']],
                        ['field' => 'connected_channel_id', 'condition' => '=', 'value' => $params['channel_id']],
                        ['field' => 'status', 'condition' => '=', 'value' => 1],
                    ],
                    'with' => ['channel']
                ];

                $propertyChannelMapping = $this->propertyChannelMappingService->select($propertyChannelMappingCriteria);
                if ($propertyChannelMapping['status'] == 'success') {

                    foreach ($propertyChannelMapping['data'] as $channel) {

                        if (!is_null($channel['channel']['parent_id'])) {
                            continue;
                        }

                        $paramsListChannel[] = [
                            'locale' => fillOnUndefined($params, 'locale'),
                            'property_id' => fillOnUndefined($params, 'property_id'),
                            'channel_id' => $channel['channel_id'],
                            'rates' => fillOnUndefined($params, 'data'),
                            'user_id' => $this->request->auth->id,
                        ];

                    }

                }
                //CONNECTED CHANNEL RATE UPDATE

            }

            foreach ($paramsListChannel as $channelParam) {

                $requestParams = [
                    'locale' => fillOnUndefined($channelParam, 'locale'),
                    'property_id' => fillOnUndefined($channelParam, 'property_id'),
                    'channel_id' => fillOnUndefined($channelParam, 'channel_id'),
                    'rates' => fillOnUndefined($channelParam, 'rates'),
                    'user_id' => $this->request->auth->id,
                ];

                $formMapping = $this->propertyRoomRatePriceService->formElementsToArray($requestParams);

                if (!$formMapping) {
                    throw new ApiErrorException('Form Error.');
                }

                $requestParams['rates'] = $formMapping['rates'];
                $requestParams['availability'] = $formMapping['availability'];

                //Amount Empty to Zero Value !important
                foreach ($requestParams['rates'] as $roomRateKey => $roomRate) {
                    if (isset($roomRate['amount']) && empty($roomRate['amount'])) {
                        $requestParams['rates'][$roomRateKey]['amount'] = "0";
                    }
                }

                //CONNECTED RATE
                $roomRates = collect($requestParams['rates']);
                $propertyRoomIds = $roomRates->pluck('room_id')->toArray();
                $propertyRoomIds = array_unique($propertyRoomIds);


                $propertyRoomRateMappingCriteria = [
                    'criteria' => [
                        ['field' => 'status', 'condition' => '=', 'value' => 1],
                    ],
                    'whereIn' => [
                        ['field' => 'room_id', 'value' => $propertyRoomIds]
                    ]
                ];

                $propertyRoomRateMapping = $this->propertyRoomRateMappingService->select($propertyRoomRateMappingCriteria);
                $propertyRoomRateMapping = $propertyRoomRateMapping['status'] == 'success' ? $propertyRoomRateMapping['data'] : [];
                $propertyRoomRateMapping = collect($propertyRoomRateMapping);

                //dd($propertyRoomRateMapping, $propertyRoomRateMappingCriteria);

                foreach ($requestParams['rates'] as $roomRateKey => $roomRate) {

                    if (!isset($roomRate['amount'])) {
                        continue;
                    }

                    $currentRoomRateIds = $propertyRoomRateMapping->whereIn('id', $roomRate['room_rate_mapping_id'])->pluck('room_rate_id')->toArray();
                    $propertyRoomRateConnectedList = $propertyRoomRateMapping->where('room_id', $roomRate['room_id'])->whereIn('connected_rate_id', $currentRoomRateIds)->toArray();


                    if (empty($propertyRoomRateConnectedList)) {
                        continue;
                    }

                    foreach ($propertyRoomRateConnectedList as $propertyRoomRateConnected) {

                        $roomRateConnected = $roomRate;
                        $roomRateConnectedAmount = $roomRate['amount'];

                        $amountAffected = 0;
                        if ($propertyRoomRateConnected['is_affected_price']) {
                            if ($propertyRoomRateConnected['affect_price_type'] == 'PER') {
                                $amountAffected = ($roomRateConnectedAmount * $propertyRoomRateConnected['affect_price_value']) / 100;
                            } elseif ($propertyRoomRateConnected['affect_price_type'] == 'FIX') {
                                $amountAffected = $propertyRoomRateConnected['affect_price_value'];
                            }

                            if ($propertyRoomRateConnected['affect_price_action_type'] == 'INC') {
                                $roomRateConnectedAmount = $roomRateConnectedAmount + $amountAffected;
                            }

                            if ($propertyRoomRateConnected['affect_price_action_type'] == 'DEC') {
                                $roomRateConnectedAmount = $roomRateConnectedAmount - $amountAffected;
                            }
                        }

                        $roomRateConnected['amount'] = $roomRateConnectedAmount == 0 ? "0" : $roomRateConnectedAmount;
                        $roomRateConnected['room_rate_mapping_id'] = $propertyRoomRateConnected['id'];


                        $roomRateConnectedKeyParam = [];
                        $roomRateConnectedKeyParam[] = $roomRateConnected['setup_type_id'];
                        $roomRateConnectedKeyParam[] = $roomRateConnected['room_id'];
                        $roomRateConnectedKeyParam[] = $roomRateConnected['room_rate_mapping_id'];
                        $roomRateConnectedKeyParam[] = $roomRateConnected['date'];
                        $roomRateConnectedKey = implode('|', $roomRateConnectedKeyParam);

                        if (array_key_exists($roomRateConnectedKey, $requestParams['rates'])) {
                            continue;
                        }

                        $requestParams['rates'][$roomRateConnectedKey] = $roomRateConnected;

                    }

                }
                //CONNECTED RATE


                $roomRateUpdate = $this->propertyRoomRatePriceService->roomRateUpdate($requestParams);
                if ($roomRateUpdate['status'] != 'success') {
                    throw new ApiErrorException($roomRateUpdate['message']);
                }

                $availabilityUpdate = $this->propertyRoomAvailabilityService->roomAvailabilityUpdate($requestParams);

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


            }

            DB::commit();

            //$roomRateAvailabilityUpdateNotification
            foreach ($paramsListChannel as $channelParam) {
                $roomRateAvailabilityUpdateNotification = $this->roomRateAvailabilityUpdateNotification($channelParam);
            }

            $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => null];


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

        return apiResponse($response['status'], $response['message'], $response['data'], $response['statusCode']);


    }

    public function roomRateAvailabilityUpdateNotification($requestParams = [])
    {

        //dd($requestParams['locale'], $requestParams['property_id'], $requestParams['channel_id']);

        //PRC_1_1_1_20210424 - Price Room Rate
        //availability_type_id, room_id, room_rate_mapping_id, date
        //AVA_1_2_0_20210424 - Availability Room
        //STS_1_1_0_20210426 - Stop Sell Room
        //STS_1_1_1_20210425 - Stop Sell Room Rate
        //MNS_1_1_1_20210421 - Min Stay Room Rate


        $propertyChannelMappingCriteria = [
            'criteria' => [
                ['field' => 'property_id', 'condition' => '=', 'value' => $requestParams['property_id']],
                ['field' => 'channel_id', 'condition' => '=', 'value' => $requestParams['channel_id']],
                ['field' => 'status', 'condition' => '=', 'value' => 1],
            ],
            'with' => ['channel', 'property', 'channelContact'],
            'firstRow' => true
        ];

        $propertyChannelMapping = $this->propertyChannelMappingService->select($propertyChannelMappingCriteria);
        if ($propertyChannelMapping['status'] != 'success') {
            return false;
        }

        if (empty($propertyChannelMapping['data']['channel_contact'])) {
            return false;
        }

        $channelContact = collect($propertyChannelMapping['data']['channel_contact'])->where('status', 1)->pluck('email')->toArray();

        if (empty($channelContact)) {
            return true;
        }


        //LANGUAGE
        $availableLanguageRequest = [
            'criteria' => [
                ['field' => 'status', 'condition' => '=', 'value' => 1],
                ['field' => 'is_application', 'condition' => '=', 'value' => 1],
                ['field' => 'is_published', 'condition' => '=', 'value' => 1]
            ],
        ];

        $availableLanguages = $this->languageService->select($availableLanguageRequest, ['code', 'name', 'language_key']);
        $availableLanguages = Collect($availableLanguages['data'])->keyBy('code')->all();

        $mailLanguage = 'en';
        if (array_key_exists($propertyChannelMapping['data']['channel']['country_code'], $availableLanguages)) {
            $mailLanguage = $propertyChannelMapping['data']['channel']['country_code'];
        }


        $propertyRoomRateChannelMappingCriteria = [
            'criteria' => [
                ['field' => 'property_id', 'condition' => '=', 'value' => $requestParams['property_id']],
                ['field' => 'channel_id', 'condition' => '=', 'value' => $requestParams['channel_id']],
                ['field' => 'status', 'condition' => '=', 'value' => 1],
            ],
            'with' => [
                'propertyRoomRateMapping.propertyRoomRate.propertyRoomRateAccommodation',
                'propertyRoomRateMapping.propertyRoom.propertyRoomType'
            ]
        ];

        $propertyRoomRateChannelMapping = $this->propertyRoomRateChannelMappingService->select($propertyRoomRateChannelMappingCriteria);
        $propertyRoomRateChannelMappingCollect = collect($propertyRoomRateChannelMapping['data']);

        $propertyRoomsParams = [
            'property_id' => $requestParams['property_id'],
        ];

        $getPropertyRooms = $this->propertyRoomService->getPropertyRooms($propertyRoomsParams);
        $propertyRoomsCollect = collect($getPropertyRooms['data']);


        $roomRateGrouped = [];
        foreach ($requestParams['rates'] as $roomRateKey => $roomRateValue) {

            $roomRateKeyParsed = explode('_', $roomRateKey);

            $roomRateKeyArray['type'] = $roomRateKeyParsed[0];
            $roomRateKeyArray['availabilityId'] = $roomRateKeyParsed[1];
            $roomRateKeyArray['roomId'] = $roomRateKeyParsed[2];
            $roomRateKeyArray['roomRateMappingId'] = $roomRateKeyParsed[3];
            $roomRateKeyArray['date'] = $roomRateKeyParsed[4];

            $roomRateGrouped[$roomRateKeyArray['type']]
            [$roomRateKeyArray['roomId']][$roomRateKeyArray['roomRateMappingId']][$roomRateKeyArray['date']] = [
                'value' => $roomRateValue,
                'currency' => $propertyChannelMapping['data']['currency_code'],
            ];

            ksort($roomRateGrouped[$roomRateKeyArray['type']][$roomRateKeyArray['roomId']][$roomRateKeyArray['roomRateMappingId']]);

        }

        $roomRateNotificationGroup = [];
        foreach ($roomRateGrouped as $typeKey => $room) {

            foreach ($room as $roomKey => $roomRate) {

                //roomDetail
                $roomDetail = $propertyRoomsCollect->where('id', $roomKey)->first();
                if (empty($roomDetail)) {
                    continue;
                }

                foreach ($roomRate as $roomRateKey => $roomRateDate) {


                    //roomRateChannelMappingDetail
                    $roomRateDetail = [];
                    $roomRateChannelMappingDetail = $propertyRoomRateChannelMappingCollect->where('room_rate_mapping_id', $roomRateKey)->first();
                    if (empty($roomRateChannelMappingDetail) && $roomRateKey != 0) {
                        continue;
                    }

                    if ($roomRateKey != 0) {
                        $roomRateDetail = $roomRateChannelMappingDetail['property_room_rate_mapping']['property_room_rate'];
                    }


                    $actionByDate = [];
                    foreach ($roomRateDate as $dateKey => $dateValue) {

                        $dateKey = substr($dateKey, 0, 4) . '-' . substr($dateKey, 4, 2) . '-' . substr($dateKey, 6, 2);


                        $lastAction = last($actionByDate);
                        $lastActionKey = array_key_last($actionByDate);


                        //if ($dateKey == '2021-04-27') {
                        // dd($actionByDate, $lastAction, $lastActionKey);

                        //}

                        if ($lastAction['value'] == $dateValue['value'] && Carbon::parse($lastAction['endDate'])->addDay()->toDateString() == $dateKey) {
                            $actionByDate[$lastActionKey]['endDate'] = $dateKey;
                        } else {
                            if ($typeKey == 'PRC') {
                                $actionByDate[] = [
                                    'startDate' => $dateKey,
                                    'endDate' => $dateKey,
                                    'value' => $dateValue['value'],
                                    'currency' => $dateValue['currency']
                                ];
                            } else {
                                $actionByDate[] = [
                                    'startDate' => $dateKey,
                                    'endDate' => $dateKey,
                                    'value' => $dateValue['value']
                                ];
                            }

                        }

                    }

                    $roomRateNotificationGroup[$typeKey]['title'] = isset($this->actionTitleByKey[$typeKey]) ? $this->actionTitleByKey[$typeKey]['language_key'] : $typeKey;

                    $roomRateNotificationGroup[$typeKey]['data'][$roomKey]['title'] = $roomDetail['name'];
                    $roomRateNotificationGroup[$typeKey]['data'][$roomKey]['titleRoomType'] = $roomDetail['property_room_type']['language_key'];

                    if (empty($roomRateDetail)) {
                        $roomRateNotificationGroup[$typeKey]['data'][$roomKey]['data'][$roomRateKey]['title'] = null;
                        $roomRateNotificationGroup[$typeKey]['data'][$roomKey]['data'][$roomRateKey]['titleAccommodation'] = null;
                    } else {
                        $roomRateNotificationGroup[$typeKey]['data'][$roomKey]['data'][$roomRateKey]['title'] = $roomRateDetail['name'];
                        $roomRateNotificationGroup[$typeKey]['data'][$roomKey]['data'][$roomRateKey]['titleAccommodation'] = $roomRateDetail['property_room_rate_accommodation']['language_key'];
                    }

                    $roomRateNotificationGroup[$typeKey]['data'][$roomKey]['data'][$roomRateKey]['actionByDate'] = $actionByDate;

                    //$roomRateNotificationGroup[$typeKey][$roomKey][$roomRateKey] = $actionByDate;

                }

            }

        }


        //inventoryActionMail
        $mailParams = [
            'locale' => $mailLanguage,
            'propertyName' => $propertyChannelMapping['data']['property']['name'],
            'channelContact' => $channelContact,
            'roomRateNotificationData' => $roomRateNotificationGroup,
        ];

        $this->mailer->onQueue('inventoryActionMail', new InventoryActionMail($mailParams));
        //inventoryActionMail


        return true;
    }

    public function roomRateAvailabilityBulkUpdateNotification($requestParams = [])
    {

        //update_type, rate, min_stay, rate_stop_sell

        $typeKeyMapping = [
            'rate' => 'PRC',
            'min_stay' => 'MNS',
            'rate_stop_sell' => 'STS',
        ];

        $typeKey = null;
        if (isset($typeKeyMapping[$requestParams['update_type']])) {
            $typeKey = $typeKeyMapping[$requestParams['update_type']];
        }

        if (is_null($typeKey)) {
            return false;
        }

        $propertyChannelMappingCriteria = [
            'criteria' => [
                ['field' => 'property_id', 'condition' => '=', 'value' => $requestParams['property_id']],
                ['field' => 'channel_id', 'condition' => '=', 'value' => $requestParams['channel_id']],
                ['field' => 'status', 'condition' => '=', 'value' => 1],
            ],
            'with' => ['channel', 'property', 'channelContact'],
            'firstRow' => true
        ];

        $propertyChannelMapping = $this->propertyChannelMappingService->select($propertyChannelMappingCriteria);
        if ($propertyChannelMapping['status'] != 'success') {
            return false;
        }

        if (empty($propertyChannelMapping['data']['channel_contact'])) {
            return false;
        }

        $channelContact = collect($propertyChannelMapping['data']['channel_contact'])->where('status', 1)->pluck('email')->toArray();

        if (empty($channelContact)) {
            return true;
        }

        //LANGUAGE
        $availableLanguageRequest = [
            'criteria' => [
                ['field' => 'status', 'condition' => '=', 'value' => 1],
                ['field' => 'is_application', 'condition' => '=', 'value' => 1],
                ['field' => 'is_published', 'condition' => '=', 'value' => 1]
            ],
        ];

        $availableLanguages = $this->languageService->select($availableLanguageRequest, ['code', 'name', 'language_key']);
        $availableLanguages = Collect($availableLanguages['data'])->keyBy('code')->all();

        $mailLanguage = 'en';
        if (array_key_exists($propertyChannelMapping['data']['channel']['country_code'], $availableLanguages)) {
            $mailLanguage = $propertyChannelMapping['data']['channel']['country_code'];
        }


        $propertyRoomRateChannelMappingCriteria = [
            'criteria' => [
                ['field' => 'property_id', 'condition' => '=', 'value' => $requestParams['property_id']],
                ['field' => 'channel_id', 'condition' => '=', 'value' => $requestParams['channel_id']],
                ['field' => 'status', 'condition' => '=', 'value' => 1],
            ],
            'with' => [
                'propertyRoomRateMapping.propertyRoomRate.propertyRoomRateAccommodation',
                'propertyRoomRateMapping.propertyRoom.propertyRoomType'
            ]
        ];

        $propertyRoomRateChannelMapping = $this->propertyRoomRateChannelMappingService->select($propertyRoomRateChannelMappingCriteria);
        $propertyRoomRateChannelMappingCollect = collect($propertyRoomRateChannelMapping['data']);

        $propertyRoomsParams = [
            'property_id' => $requestParams['property_id'],
        ];

        $getPropertyRooms = $this->propertyRoomService->getPropertyRooms($propertyRoomsParams);
        $propertyRoomsCollect = collect($getPropertyRooms['data']);


        //Burada time lar hesaplancak, hepsinde aynı zaten mantığı

        $actionByDate = [];


        $diffInDays = Carbon::parse($requestParams['start_date'])->diffInDays($requestParams['end_date']);

        $startDate = $requestParams['start_date'];
        for ($i = 0; $i <= $diffInDays; $i++) {

            $dateKey = Carbon::parse($startDate)->addDays($i)->toDateString();

            if (!in_array(Carbon::parse($dateKey)->shortDayName, $requestParams['include_days'])) {
                continue;
            }

            $lastAction = last($actionByDate);
            $lastActionKey = array_key_last($actionByDate);

            if (Carbon::parse($lastAction['endDate'])->addDay()->toDateString() == $dateKey) {
                $actionByDate[$lastActionKey]['endDate'] = $dateKey;
            } else {
                if ($typeKey == 'PRC') {
                    $actionByDate[] = [
                        'startDate' => $dateKey,
                        'endDate' => $dateKey,
                        'value' => $requestParams['value'],
                        'currency' => $propertyChannelMapping['data']['currency_code']
                    ];
                } else {
                    $actionByDate[] = [
                        'startDate' => $dateKey,
                        'endDate' => $dateKey,
                        'value' => $requestParams['value']
                    ];
                }

            }

        }

        $roomRateNotificationGroup = [];
        foreach ($requestParams['room_rates'] as $room) {

            foreach ($room['room_rate_mapping_id'] as $roomRateId) {

                //roomDetail
                $roomDetail = $propertyRoomsCollect->where('id', $room['room_id'])->first();
                if (empty($roomDetail)) {
                    continue;
                }

                //roomRateChannelMappingDetail
                $roomRateDetail = [];
                $roomRateChannelMappingDetail = $propertyRoomRateChannelMappingCollect->where('room_rate_mapping_id', $roomRateId)->first();
                if (empty($roomRateChannelMappingDetail) && $roomRateId != 0) {
                    continue;
                }

                if ($roomRateId != 0) {
                    $roomRateDetail = $roomRateChannelMappingDetail['property_room_rate_mapping']['property_room_rate'];
                }


                $roomRateNotificationGroup[$typeKey]['title'] = isset($this->actionTitleByKey[$typeKey]) ? $this->actionTitleByKey[$typeKey]['language_key'] : $typeKey;

                $roomRateNotificationGroup[$typeKey]['data'][$room['room_id']]['title'] = $roomDetail['name'];
                $roomRateNotificationGroup[$typeKey]['data'][$room['room_id']]['titleRoomType'] = $roomDetail['property_room_type']['language_key'];

                if (empty($roomRateDetail)) {
                    $roomRateNotificationGroup[$typeKey]['data'][$room['room_id']]['data'][$roomRateId]['title'] = null;
                    $roomRateNotificationGroup[$typeKey]['data'][$room['room_id']]['data'][$roomRateId]['titleAccommodation'] = null;
                } else {
                    $roomRateNotificationGroup[$typeKey]['data'][$room['room_id']]['data'][$roomRateId]['title'] = $roomRateDetail['name'];
                    $roomRateNotificationGroup[$typeKey]['data'][$room['room_id']]['data'][$roomRateId]['titleAccommodation'] = $roomRateDetail['property_room_rate_accommodation']['language_key'];
                }

                $roomRateNotificationGroup[$typeKey]['data'][$room['room_id']]['data'][$roomRateId]['actionByDate'] = $actionByDate;

            }

        }

        //inventoryActionMail
        $mailParams = [
            'locale' => $mailLanguage,
            'propertyName' => $propertyChannelMapping['data']['property']['name'],
            'channelContact' => $channelContact,
            'roomRateNotificationData' => $roomRateNotificationGroup,
        ];

        $this->mailer->onQueue('inventoryActionMail', new InventoryActionMail($mailParams));
        //inventoryActionMail


        return true;
    }

    public function setStatusPropertyRoomRateMapping(Request $request)
    {

        $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500];
        try {

            if (is_null($this->request->getContent())) {
                throw new ApiErrorException(lang('Parameter Error.'));
            }

            $params = $this->request->params;
            $params['user_id'] = $this->request->auth->id;


            if (isset($params['status'])) {
                $requestParams['status'] = fillOnUndefined($params, "status", 0);
            }
            $propertyRoomRateMapping = $this->propertyRoomRateMappingService->setStatusPropertyRoomRateMapping($params);
            if ($propertyRoomRateMapping['status'] != 'success') {
                throw new ApiErrorException($propertyRoomRateMapping['message']);
            }

            $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyRoomRateMapping['data']];

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


    }

    public function postInventoryLink(Request $request)
    {


        $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500];
        try {

            $params = $this->request->params;

            $propertyChannelMappingCriteria = [
                'criteria' => [
                    ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']],
                    ['field' => 'channel_id', 'condition' => '=', 'value' => $params['channel_id']],
                    ['field' => 'status', 'condition' => '=', 'value' => 1],
                ],
                'with' => ['channel', 'property', 'channelContact'],
                'firstRow' => true
            ];


            $propertyChannelMapping = $this->propertyChannelMappingService->select($propertyChannelMappingCriteria);
            if ($propertyChannelMapping['status'] != 'success') {
                throw new ApiErrorException($propertyChannelMapping['message']);
            }

            if (empty($propertyChannelMapping['data']['channel_contact'])) {
                throw new ApiErrorException("There is not any email address founded for this channel");
            }

            $channelContact = collect($propertyChannelMapping['data']['channel_contact'])->where('status', 1)->pluck('email')->toArray();

            if (empty($channelContact)) {
                return true;
            }


            $availableLanguageRequest = [
                'criteria' => [
                    ['field' => 'status', 'condition' => '=', 'value' => 1],
                    ['field' => 'is_application', 'condition' => '=', 'value' => 1],
                    ['field' => 'is_published', 'condition' => '=', 'value' => 1]
                ],
            ];

            $availableLanguages = $this->languageService->select($availableLanguageRequest, ['code', 'name', 'language_key']);
            $availableLanguages = Collect($availableLanguages['data'])->keyBy('code')->all();

            $mailLanguage = 'en';
            if (array_key_exists($propertyChannelMapping['data']['channel']['country_code'], $availableLanguages)) {
                $mailLanguage = $propertyChannelMapping['data']['channel']['country_code'];
            }


            $mailParams = [
                'locale' => $mailLanguage,
                'propertyName' => $propertyChannelMapping['data']['property']['name'],
                'channelContact' => $channelContact,
                'link' => Config::get('app.url') . '/app/v1/channel-pdf-inventory/' . $propertyChannelMapping['data']['token']

            ];

            $this->mailer->onQueue('inventoryPdfLinkMail', new InventoryPdfLinkMail($mailParams));

            $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $mailParams];

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

    }
}


