<?php


namespace App\Http\Controllers\MetaSearch\Trivago\v1;

use App\Core\Service\ChannelManagerPropertyMappingService;
use App\Core\Service\CurrencyService;
use App\Core\Service\PropertyChannelCouponService;
use App\Exceptions\ApiErrorException;
use App\Http\Controllers\Controller;
use App\Models\PropertyChannel;
use App\Models\PropertyContact;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Log;

use Exception;


class TrivagoController extends Controller
{

    private $username;
    private $password;
    private $authorization;
    private $channelManagerId;
    private $channelManagerLogId;
    private $mealCodeMapping;
    private $paymentTypeMapping;
    private $countryCodeCampaign;

    public function __construct(
        Request $request,
        CurrencyService $currencyService,
        ChannelManagerPropertyMappingService $channelManagerPropertyMappingService,
        PropertyChannelCouponService $propertyChannelCouponService
    )
    {

        $this->username = 'trivago';
        $this->password = 'P8MUQtNP6TkKMz3E';

        $this->channelManagerId = 11;//Trivago

        $this->request = $request;
        $this->currencyService = $currencyService;
        $this->channelManagerPropertyMappingService = $channelManagerPropertyMappingService;
        $this->propertyChannelCouponService = $propertyChannelCouponService;

        $payload = $this->request->getContent();
        parse_str(urldecode($payload), $payloadDecode);
        $this->param = $payloadDecode;

        $this->authorization = $request->header('authorization');

        $this->tax = 10;
        $this->cityTax = 2;


        $this->mealCodeMapping = [
            10 => 'AI',
            11 => 'BB',
            13 => 'RO',
            14 => 'FB',
            15 => 'HB',
        ];

        $this->paymentTypeMapping = [
            'CRD' => 'prepaid',
            'HTL' => 'postpaid'
        ];

        $this->CPA['TR'] = ["1" => 9.60, "2" => 10.80, "3" => 11.00, "4" => 11.20, "5" => 11.40, "6" => 11.60, "7" => 11.80, "8" => 12.00];
        $this->CPA['DE'] = ["1" => 10.80, "2" => 11.00, "3" => 11.20, "4" => 11.40, "5" => 11.60, "6" => 11.80, "7" => 12.00, "8" => 12.20];
        $this->CPA['UK'] = ["1" => 10.80, "2" => 11.00, "3" => 11.20, "4" => 11.40, "5" => 11.60, "6" => 11.80, "7" => 12.00, "8" => 12.20];
        $this->CPA['US'] = ["1" => 10.80, "2" => 11.00, "3" => 11.20, "4" => 11.40, "5" => 11.60, "6" => 11.80, "7" => 12.00, "8" => 12.20];

        $this->countryCodeCampaign = [
            'DE' => [
                'code' => 'DE',
                'campaignCode' => 7
            ],
            'TR' => [
                'code' => 'TR',
                'campaignCode' => 8
            ],
            'US' => [
                'code' => 'US',
                'campaignCode' => 7
            ],
            'UK' => [
                'code' => 'UK',
                'campaignCode' => 7
            ]
        ];

    }


    public function checkAuthentication($authorization)
    {

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

        $basicAuth = 'Basic ' . base64_encode($this->username . ':' . $this->password);

        if ($authorization != $basicAuth) {
            $response['message'] = 'Your username or password is incorrect.';
        } else {
            $response['status'] = true;
        }

        return $response;

    }


    public function responseError($errorMessage)
    {

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

        //channelManagerLogService
        if (!is_null($this->channelManagerLogId)) {
            $updateDataLog = [
                'response' => json_encode($response),
                'status' => 0
            ];

            if (!is_null($this->channelManagerRequestTime)) {
                $updateDataLog['response_time'] = microtime(true) - $this->channelManagerRequestTime;
            }

            $channelManagerLog = $this->channelManagerLogService->update($this->channelManagerLogId, $updateDataLog);
        }
        //channelManagerLogService


        return response()->json($response);

    }

    public function requestParamConverter($requestParam = [])
    {

        $searchRequestJson = [];

        $searchRequestJson['date']['checkIn'] = Carbon::parse($requestParam['start_date'])->toDateString();
        $searchRequestJson['date']['checkOut'] = Carbon::parse($requestParam['end_date'])->toDateString();

        $rooms = [];
        for ($i = 0; $i < $requestParam['num_rooms']; $i++) {

            $roomCounter = ($i + 1);

            if (isset($requestParam['room_adults_' . $roomCounter])) {
                $rooms[$i]['adults'] = $requestParam['room_adults_' . $roomCounter];
            }


            $rooms[$i]['children'] = 0;
            $rooms[$i]['age'] = null;
            if (isset($requestParam['room_childs_' . $roomCounter])) {

                $childAges = json_decode($requestParam['room_childs_' . $roomCounter]);

                $rooms[$i]['children'] = count($childAges);
                $rooms[$i]['age'] = $childAges;
            }

        }

        $searchRequestJson['rooms'] = $rooms;
        $searchRequestJson['property'] = json_decode($requestParam['hotels']);

        return $searchRequestJson;

    }

    public function roomOccupancy($requestParam)
    {

        $roomOccupancy = [];
        foreach ($requestParam as $room) {
            $adults = str_repeat('A', $room['adults']);

            $children = [];
            if ($room['children'] > 0 && !empty($room['age'])) {
                foreach ($room['age'] as $child) {
                    $children[] = 'C' . $child;
                }
            }

            $roomOccupancy[] = $adults . implode('', $children);

        }

        return $roomOccupancy;
    }

    public function deepLinkGenerator($token, $requestParam = [])
    {

        $deepLink = 'https://be.extranetwork.com/' . $token . '/en/search/';


        $deepLink .= Carbon::parse($requestParam['date']['checkIn'])->format('Ymd') . '/';
        $deepLink .= Carbon::parse($requestParam['date']['checkOut'])->format('Ymd') . '/';


        $roomOccupancy = $this->roomOccupancy($requestParam['rooms']);

        $deepLink .= implode(',', $roomOccupancy);;

        $deepLink .= '?utm_medium=trivago&utm_source=trivago&locale=' . $requestParam['locale'];

        return $deepLink;

    }

    public function couponCodeCheck($propertyId, $checkIn, $checkOut)
    {
        //$propertyChannelCoupon
        $propertyChannelCouponsCriteria = [
            'criteria' => [
                ['field' => 'property_id', 'condition' => '=', 'value' => $propertyId],
                ['field' => 'channel_id', 'condition' => '=', 'value' => 1],
                ['field' => 'start_date', 'condition' => '<=', 'value' => Carbon::now()->toDateString()],
                ['field' => 'end_date', 'condition' => '>=', 'value' => Carbon::now()->toDateString()],
                ['field' => 'status', 'condition' => '=', 'value' => 1],
            ],
            'orderBy' => [
                ['field' => 'id', 'value' => 'DESC']
            ],
        ];

        $propertyChannelCoupons = $this->propertyChannelCouponService->select($propertyChannelCouponsCriteria);

        if ($propertyChannelCoupons['status'] == 'success') {
            $propertyChannelCoupons = $propertyChannelCoupons['data'];

            foreach ($propertyChannelCoupons as $propertyChannelCouponKey => $propertyChannelCouponData) {

                //Reservation Date Check
                if (!is_null($propertyChannelCouponData['reservation_start_date']) && !is_null($propertyChannelCouponData['reservation_end_date'])) {
                    $reservationDateCheck = Carbon::parse($propertyChannelCouponData['reservation_start_date'])->lessThanOrEqualTo(Carbon::parse($checkIn))
                        && Carbon::parse($propertyChannelCouponData['reservation_end_date'])->greaterThanOrEqualTo(Carbon::parse($checkOut));
                    if (!$reservationDateCheck) {
                        unset($propertyChannelCoupons[$propertyChannelCouponKey]);
                    }

                }
            }

        } else {
            $propertyChannelCoupons = [];
        }

        $propertyChannelCoupon = !empty($propertyChannelCoupons) ? reset($propertyChannelCoupons) : null;

        return $propertyChannelCoupon;

    }

    public function availability(Request $request)
    {

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

        $checkAuthentication = $this->checkAuthentication($this->authorization);
        if (!$checkAuthentication['status']) {
            return $this->responseError($checkAuthentication['message']);
        }

        $searchController = App::make("App\Http\Controllers\BookingEngine\V1\SearchController");

        $requestTime = microtime(true);


        $hotelList['root'] = $this->param;
        unset($hotelList['root']['hotels']);
        $hotelList['root']['hotel_ids'] = json_decode($this->param['hotels']);
        $hotelList['root']['hotels'] = [];

        $hotelList['root']['api_version'] = (integer)$hotelList['root']['api_version'];
        $hotelList['root']['num_rooms'] = (integer)$hotelList['root']['num_rooms'];

        for ($i = 0; $i < $hotelList['root']['num_rooms']; $i++) {
            $roomCounter = ($i + 1);
            if (isset($hotelList['root']['room_adults_' . $roomCounter])) {
                $hotelList['root']['room_adults_' . $roomCounter] = (integer)$hotelList['root']['room_adults_' . $roomCounter];
            }
        }

        $requestCurrency = $this->param['currency'];

        try {


            //Hotels Check
            $channelManagerPropertyList = [];
            $channelManagerPropertyMappingCriteria['criteria'] = [
                ['field' => 'channel_manager_id', 'condition' => '=', 'value' => $this->channelManagerId],
                ['field' => 'channel_manager_property_id', 'condition' => '=', 'value' => null],
                ['field' => 'status', 'condition' => '=', 'value' => 1],
            ];
            $channelManagerPropertyMapping = $this->channelManagerPropertyMappingService->select($channelManagerPropertyMappingCriteria);
            if ($channelManagerPropertyMapping['status'] == 'success' && !empty($channelManagerPropertyMapping['data'])) {
                $channelManagerPropertyList = pickItemFromArray('property_id', $channelManagerPropertyMapping['data']);
            }

            $availableHotelIds = array_intersect($hotelList['root']['hotel_ids'], $channelManagerPropertyList);

            if (empty($availableHotelIds)) {
                throw new ApiErrorException('Hotel not found');
            }

            $this->param['hotels'] = json_encode($availableHotelIds);
            //Hotels Check


            $searchRequestJson = $this->requestParamConverter($this->param);

            $searchRequestJson['ipAddress'] = $request->getClientIp();
            $searchRequestJson['isMobile'] = null;
            $searchRequestJson['noneCacheSearch'] = true;
            $searchRequestJson['ipAddress'] = $request->getClientIp();
            $searchRequestJson['justPriceValues'] = true;


            $cacheKeyParam = $this->param;
            unset($cacheKeyParam['currency']);
            unset($cacheKeyParam['rate_model']);
            unset($cacheKeyParam['lang']);
            $cacheKey = 'TRV:' . md5(implode(',', $cacheKeyParam));

            //Cache::forget($cacheKey);

            if (Cache::has($cacheKey)) {
                $search = Cache::get($cacheKey);
            } else {
                $requestCreate = Request::create(null, null, [], [], [], [], json_encode($searchRequestJson));
                $requestCreate->headers->set('channelId', '1');
                //$requestCreate->headers->set('bookingEnginePropertyId', null);
                $requestCreate->headers->set('channelToken', 'ece3ef02-42e7-92b7-f379-08226ed7a0f3');//TODO: from DB
                $requestCreate->headers->set('bookingEngineToken', null);
                $search = $searchController->search($requestCreate);

                Cache::put($cacheKey, $search, 60 * 60);//1 Day 24 * 60 * 60
            }

            $search = json_decode(json_encode($search), 1);

            if ($search['original']['status'] != 200) {
                throw new ApiErrorException('Hotel not found');
            }

            $properties = $search['original']['data']['properties'];

            if (empty($properties)) {
                throw new ApiErrorException('Hotel not found');
            }

            $hotelCounter = 0;
            $numberOfStay = Carbon::parse($searchRequestJson['date']['checkIn'])->diffInDays(Carbon::parse($searchRequestJson['date']['checkOut']));

            foreach ($properties as $propertyId => $property) {

                if (!isset($property['currency'])) {
                    continue;
                }

                $currencyExchangeRate = 1;
                if ($requestCurrency != $property['currency']) {
                    $currencyExchangeRate = $this->currencyService->lastExchangeRate($property['currency'], $requestCurrency);
                    if ($currencyExchangeRate['status'] == 'success') {
                        $currencyExchangeRate = $currencyExchangeRate['data'];
                    }
                }


                $languageLocale = explode('_', $this->param['lang'], 2);
                $searchRequestJson['locale'] = $languageLocale[1];

                $token = $property['booking_engine_token'];
                $deepLinkGenerator = $this->deepLinkGenerator($token, $searchRequestJson);

                $property = reset($property['availabilities']);
                $propertyRooms = $property['rooms'];

                //Standard Room Room Only FreeCancellation - Pay at Hotel

                $requestedRoomPriceGroup = [];
                foreach ($propertyRooms as $propertyRoomId => $propertyRoom) {

                    foreach ($propertyRoom['rates'] as $propertyRoomRateId => $propertyRoomRate) {

                        foreach ($propertyRoomRate['requestedRoomPrice'] as $occupancyCode => $requestedRoomPrices) {

                            foreach ($requestedRoomPrices['prices'] as $requestedRoomPriceKey => $requestedRoomPrice) {

                                $roomRateKeyName = $occupancyCode . ' ' . $requestedRoomPrice['room']['name'] . ' ' . $requestedRoomPrice['rate']['boardName'] . ' ' . $requestedRoomPrice['name'];

                                $roomRateKeycode = $requestedRoomPrice['rate']['accommodationCode'] . '|' . (isset($requestedRoomPrice['cancellationPolicy']['id']) ? $requestedRoomPrice['cancellationPolicy']['id'] : 0) . '|' . $requestedRoomPrice['bookingPaymentType']['code'];

                                //$requestedRoomPriceGroup[$roomRateKeycode][$occupancyCode][] = $roomRateKeyName . '-' . $requestedRoomPrice['rateKeyCode'];
                                $requestedRoomPrice['dailyAverageDiscount'] = $requestedRoomPrices['dailyAverageDiscount'];
                                $requestedRoomPriceGroup[$roomRateKeycode][$occupancyCode][] = $requestedRoomPrice;

                            }


                        }

                    }
                }

                $roomOccupancy = $this->roomOccupancy($searchRequestJson['rooms']);


                $roomRateBoardGroup = [];
                foreach ($requestedRoomPriceGroup as $groupKey => $groupValue) {

                    $counter = 0;

                    foreach ($groupValue as $groupValueOccupancyCode => $groupValueOccupancy) {
                        foreach ($groupValueOccupancy as $groupValueOccupancyCodeX => $groupValueOccupancyVal) {

                            foreach ($roomOccupancy as $occupancyOrder => $occupancy) {

                                $occupancyCheckKey = $occupancy . '-' . $occupancyOrder;

                                if ($groupValueOccupancyCode == $occupancy && !isset($roomRateBoardGroup[$groupKey][$counter][$occupancyCheckKey])) {
                                    $roomRateBoardGroup[$groupKey][$counter][$occupancyCheckKey] = $groupValueOccupancyVal;
                                    if (count($roomRateBoardGroup[$groupKey][$counter]) == count($roomOccupancy)) {
                                        $counter++;
                                    }
                                }

                            }

                        }
                    }
                }


                $roomRateTypes = [];
                foreach ($roomRateBoardGroup as $boardGroups) {

                    foreach ($boardGroups as $boardGroups) {


                        $roomRateTypesGroup = [];
                        foreach ($boardGroups as $requestedRoomPrice) {

                            $roomRateKeyName = $requestedRoomPrice['room']['name'] . ' ' . $requestedRoomPrice['rate']['boardName'] . ' ' . $requestedRoomPrice['name'];

                            $total = $requestedRoomPrice['total'];
                            $totalBeforeDiscount = $requestedRoomPrice['total'];
                            $totalBeforeDiscountDailyAverage = ($totalBeforeDiscount / $numberOfStay);

                            $discounts = [];
                            if ($requestedRoomPrice['dailyAverageDiscount'] > 0) {

                                $totalBeforeDiscount = ($total / (100 - (double)$requestedRoomPrice['dailyAverageDiscount'])) * 100;
                                $totalBeforeDiscountDailyAverage = ($totalBeforeDiscount / $numberOfStay);
                                $totalDiscount = $totalBeforeDiscount - $total;
                                $dailyDiscountAverage = ($totalDiscount / $numberOfStay);


                                $netRate = $dailyDiscountAverage / (1 + ($this->tax / 100) + ($this->cityTax / 100));
                                $vat = $netRate * ($this->tax / 100);
                                $localTax = $netRate * ($this->cityTax / 100);


                                $finalRateDiscount = moneyDoubleFormatDecimal($localTax * $currencyExchangeRate) + moneyDoubleFormatDecimal($netRate * $currencyExchangeRate) + moneyDoubleFormatDecimal($vat * $currencyExchangeRate);

                                $discounts[] = [
                                    'booking_fee' => 0,
                                    'final_rate' => moneyDoubleFormatDecimal($finalRateDiscount), //moneyDoubleFormatDecimal($dailyDiscountAverage * $currencyExchangeRate),
                                    'hotel_fee' => 0,
                                    'local_tax' => moneyDoubleFormatDecimal($localTax * $currencyExchangeRate),
                                    'marketing_text' => $requestedRoomPrice['dailyAverageDiscount'] . '% Special Discount',
                                    'net_rate' => moneyDoubleFormatDecimal($netRate * $currencyExchangeRate),
                                    'resort_fee' => 0,
                                    'service_charge' => 0,
                                    'vat' => moneyDoubleFormatDecimal($vat * $currencyExchangeRate),
                                ];

                            }

                            $netRate = $totalBeforeDiscountDailyAverage / (1 + ($this->tax / 100) + ($this->cityTax / 100));
                            $vat = $netRate * ($this->tax / 100);
                            $localTax = $netRate * ($this->cityTax / 100);


                            $finalRate = moneyDoubleFormatDecimal($localTax * $currencyExchangeRate) + moneyDoubleFormatDecimal($netRate * $currencyExchangeRate) + moneyDoubleFormatDecimal($vat * $currencyExchangeRate);

                            $roomRateTypesGroup[][$roomRateKeyName] = [
                                'booking_fee' => 0,
                                'breakfast_included' => in_array($requestedRoomPrice['rate']['accommodationCode'], [10, 11, 14, 15]) ? true : false,
                                'currency' => $requestCurrency,
                                'discounts' => $discounts,
                                'final_rate' => moneyDoubleFormatDecimal($finalRate),//moneyDoubleFormatDecimal($totalBeforeDiscountDailyAverage * $currencyExchangeRate),
                                'free_cancellation' => $requestedRoomPrice['cancellationPolicy']['isFreeCancellation'] ? true : false,
                                //'free_cancellation_deadline' => '2018-04-25T16:00:00+00:00',
                                'hotel_fee' => 0,
                                'local_tax' => moneyDoubleFormatDecimal($localTax * $currencyExchangeRate),
                                'meal_code' => isset($this->mealCodeMapping[$requestedRoomPrice['rate']['accommodationCode']]) ? $this->mealCodeMapping[$requestedRoomPrice['rate']['accommodationCode']] : 'RO',
                                'net_rate' => moneyDoubleFormatDecimal($netRate * $currencyExchangeRate),
                                'payment_type' => isset($this->paymentTypeMapping[$requestedRoomPrice['bookingPaymentType']['code']]) ? $this->paymentTypeMapping[$requestedRoomPrice['bookingPaymentType']['code']] : 'postpaid',
                                'resort_fee' => 0,
                                'room_code' => $requestedRoomPrice['room']['name'],
                                'service_charge' => 0,
                                'url' => $deepLinkGenerator,
                                //'mobileURL' => null',
                                'vat' => moneyDoubleFormatDecimal($vat * $currencyExchangeRate),
                                'rate_type' => 'DEFAULT',
                                //'rateKeyCode' => $requestedRoomPrice['rateKeyCode'],
                                //'dailyAverageDiscount' => $requestedRoomPrice['dailyAverageDiscount'],
                            ];


                        }

                        $roomRateTypes[] = $roomRateTypesGroup;


                    }
                }

                if (!empty($roomRateTypes)) {

                    //if (in_array($propertyId, [1275,1325])) {

                    $propertyCouponCodeCheck = $this->couponCodeCheck($propertyId, $searchRequestJson['date']['checkIn'], $searchRequestJson['date']['checkOut']);

                    if (!empty($propertyCouponCodeCheck)) {
                        $roomRateTypesWithCoupon = [];
                        foreach ($roomRateTypes as $roomRateTypeKey => $roomRateType) {
                            foreach ($roomRateType as $roomRateTypeDetailKey => $roomRateTypeDetails) {

                                //dd($roomRateTypeKey, $roomRateTypeDetailKey, $propertyCouponCodeCheck, $roomRateTypeDetail, key($roomRateTypeDetail));

                                $roomRateTypeDetail = reset($roomRateTypeDetails);

                                $couponPercentageValue = (100 - $propertyCouponCodeCheck['value']) / 100;

                                $finalRateDiscountBeforeReward = collect($roomRateTypeDetail['discounts'])->sum('final_rate');
                                $localTaxDiscountBeforeReward = collect($roomRateTypeDetail['discounts'])->sum('local_tax');
                                $netRateDiscountBeforeReward = collect($roomRateTypeDetail['discounts'])->sum('net_rate');
                                $vatDiscountBeforeReward = collect($roomRateTypeDetail['discounts'])->sum('vat');

                                $finalRateDiscountReward = ($roomRateTypeDetail['final_rate'] - $finalRateDiscountBeforeReward) * $propertyCouponCodeCheck['value'] / 100;
                                $localTaxDiscountReward = ($roomRateTypeDetail['local_tax'] - $localTaxDiscountBeforeReward) * $propertyCouponCodeCheck['value'] / 100;
                                $netRateDiscountReward = ($roomRateTypeDetail['net_rate'] - $netRateDiscountBeforeReward) * $propertyCouponCodeCheck['value'] / 100;
                                $vatDiscountReward = ($roomRateTypeDetail['vat'] - $vatDiscountBeforeReward) * $propertyCouponCodeCheck['value'] / 100;

                                $discountReward = [
                                    'booking_fee' => 0,
                                    'final_rate' => moneyDoubleFormatDecimal($finalRateDiscountBeforeReward + $finalRateDiscountReward),
                                    'hotel_fee' => 0,
                                    'local_tax' => moneyDoubleFormatDecimal($localTaxDiscountBeforeReward + $localTaxDiscountReward),
                                    'marketing_text' => 'Special REWARD Discount',
                                    'net_rate' => moneyDoubleFormatDecimal($netRateDiscountBeforeReward + $netRateDiscountReward),
                                    'resort_fee' => 0,
                                    'service_charge' => 0,
                                    'vat' => moneyDoubleFormatDecimal($vatDiscountBeforeReward + $vatDiscountReward),
                                ];

                                $discountReward['marketing_text'] = number_format($discountReward['final_rate'] / $roomRateTypeDetail['final_rate'] * 100) . '% Special Popup Discount';

                                unset($roomRateTypeDetail['discounts']);

                                $roomRateTypeDetail['discounts'][] = $discountReward;

                                //$roomRateTypeDetail['rate_type'] = 'REWARD';
                                $roomRateTypeDetail['rate_type'] = 'DEFAULT';


                                $roomRateTypesWithCoupon[$roomRateTypeKey][$roomRateTypeDetailKey][key($roomRateTypeDetails)] = $roomRateTypeDetail;

                            }

                            unset($roomRateTypes[$roomRateTypeKey]);

                        }

                        $roomRateTypes = array_merge($roomRateTypes, $roomRateTypesWithCoupon);
                    }

                    //}


                    $hotelList['root']['hotels'][$hotelCounter] = [
                        'hotel_id' => $propertyId,
                        'room_types' => $roomRateTypes
                    ];

                    $hotelCounter++;

                }


            }


        } 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']) {
            $hotelList['root']['hotels'] = [];
        }

        $responseTime = microtime(true) - $requestTime;


        //Log::debug(json_encode($this->param) . ' - Response Time: ' . number_format($responseTime, 2) . ' - Status: ' . count($hotelList['root']['hotels']));


        return response()->json($hotelList);

    }

    public function hotel(Request $request)
    {

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


        $hotelList = [];

        $hotelList['api_version'] = 4;
        $hotelList['lang'] = 'en_GB';
        $hotelList['hotels'] = [];

        try {


            $channelManagerPropertyMappingCriteria['criteria'] = [
                ['field' => 'channel_manager_id', 'condition' => '=', 'value' => $this->channelManagerId],
                ['field' => 'channel_manager_property_id', 'condition' => '=', 'value' => null],
                ['field' => 'status', 'condition' => '=', 'value' => 1],
            ];
            $channelManagerPropertyMappingCriteria['with'] = [
                'property.propertyType', 'property.propertyContact', 'property.propertyWeb', 'property.country'
            ];
            $channelManagerPropertyMapping = $this->channelManagerPropertyMappingService->select($channelManagerPropertyMappingCriteria);

            if ($channelManagerPropertyMapping['status'] == 'success' && !empty($channelManagerPropertyMapping['data'])) {

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

                    if ($propertyMapping['status'] != 1) {
                        continue;
                    }

                    $metaAddress = json_decode($propertyMapping['property']['property_contact']['meta'], 1);


                    $hotelList['hotels'][] = [
                        'partner_reference' => $propertyMapping['property']['id'],
                        'name' => $propertyMapping['property']['name'],
                        'street' => fillOnUndefined($metaAddress, 'street'),
                        'city' => fillOnUndefined($metaAddress, 'city'),
                        'postal_code' => fillOnUndefined($metaAddress, 'zip_code'),
                        //'state' => null,
                        'country' => $propertyMapping['property']['country']['name'],
                        'latitude' => $propertyMapping['property']['property_contact']['latitude'],
                        'longitude' => $propertyMapping['property']['property_contact']['longitude'],
                        'desc' => $propertyMapping['property']['name'],
                        'amenities' => null,//['Beauty Center', 'Business Center', 'Café/ Bistro', 'Sauna'],
                        'url' => $propertyMapping['property']['property_web']['webProtocolUrl'],
                        'email' => $propertyMapping['property']['property_contact']['email'],
                        'phone' => $propertyMapping['property']['property_contact']['phone'],
                        'fax' => $propertyMapping['property']['property_contact']['fax']
                    ];

                    //dd(json_decode($propertyMapping['property']['property_contact']['meta'],1));

                    $addressExplode = explode('/', $propertyMapping['property']['property_contact']['address'], 2);
                    $street = isset($addressExplode[0]) ? $addressExplode[0] : $propertyMapping['property']['property_contact']['address'];
                    $cityExplode = isset($addressExplode[1]) ? explode(',', $addressExplode[1]) : (isset($addressExplode[0]) ? explode(',', $addressExplode[0]) : null);
                    $city = isset($cityExplode[0]) ? $cityExplode[0] : null;

                    $streetExplode = explode(', ', $street);
                    unset($streetExplode[count($streetExplode) - 1]);
                    $street = implode(', ', $streetExplode);

                    $metaUpdate = [
                        'street' => $street,
                        'city' => $city,
                        'zip_code' => $propertyMapping['property']['property_contact']['zip_code'],
                    ];

                    if (empty($propertyMapping['property']['property_contact']['meta'])) {
                        PropertyContact::where('id', $propertyMapping['property']['property_contact']['id'])->update(['meta' => json_encode($metaUpdate)]);
                    }


                    //dd($propertyMapping['property']['property_contact']['id'],$metaUpdate);

                }


            }


        } 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']) {
            $hotelList['root']['hotels'] = [];
        }


        return response()->json($hotelList);

    }

    public function campaign(Request $request)
    {


        $hotelList = [];

        $hotelExcludeList = [];
        $hotelExcludeList['TR'] = [721, 729];

        try {


            $channelManagerPropertyMappingCriteria['criteria'] = [
                ['field' => 'channel_manager_id', 'condition' => '=', 'value' => $this->channelManagerId],
                ['field' => 'channel_manager_property_id', 'condition' => '=', 'value' => null],
                ['field' => 'status', 'condition' => '=', 'value' => 1],
            ];
            $channelManagerPropertyMappingCriteria['with'] = [
                'property.propertyType', 'property.propertyContact', 'property.propertyWeb', 'property.country'
            ];
            $channelManagerPropertyMapping = $this->channelManagerPropertyMappingService->select($channelManagerPropertyMappingCriteria);


            if ($channelManagerPropertyMapping['status'] == 'success' && !empty($channelManagerPropertyMapping['data'])) {

                $hotelList[] = [
                    'partner_reference' => 'partner_reference',
                    'locale' => 'locale',
                    'campaign' => 'campaign'
                ];

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

                    foreach ($this->CPA as $countryCode => $countryValue) {
                        foreach ($countryValue as $campaignId => $campaignValue) {

                            if (isset($this->countryCodeCampaign[$countryCode]) && $this->countryCodeCampaign[$countryCode]['campaignCode'] == $campaignId) {

                                if (isset($hotelExcludeList[$countryCode])) {
                                    if (in_array($propertyMapping['property_id'], $hotelExcludeList[$countryCode])) {
                                        continue;
                                    }
                                }

                                $hotelList[] = [
                                    'partner_reference' => $propertyMapping['property']['id'],
                                    'locale' => $countryCode,
                                    'campaign' => $campaignId
                                ];
                            }

                        }
                    }


                }


            }


        } catch (ApiErrorException | Exception $e) {
            $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage();
            Log::error($message);
        }

        $out = "";
        foreach ($hotelList as $hotel) {
            $out .= implode(",", $hotel) . PHP_EOL;

        }

        header("Content-Type: application/csv");
        header("Content-Disposition: attachment; filename=Extranetwork-Campaign.csv");
        header('Pragma: no-cache');
        header("Expires: 0");

        echo $out;
        die();

        //return response()->json($hotelList);

    }

    public function cpa(Request $request)
    {


        $cpaList[] = [
            'locale' => 'locale',
            'campaign' => 'campaign',
            'cpa_value' => 'cpa_value'
        ];


        try {

            foreach ($this->CPA as $countryCode => $countryValue) {
                foreach ($countryValue as $campaignId => $campaignValue) {

                    $cpaList[] = [
                        'locale' => $countryCode,
                        'campaign' => $campaignId,
                        'cpa_value' => $campaignValue
                    ];

                }

            }

        } catch (ApiErrorException | Exception $e) {
            $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage();
            Log::error($message);
        }


        $out = "";
        foreach ($cpaList as $cpa) {
            $out .= implode(",", $cpa) . PHP_EOL;

        }

        header("Content-Type: application/csv");
        header("Content-Disposition: attachment; filename=Extranetwork-CPA.csv");
        header('Pragma: no-cache');
        header("Expires: 0");

        echo $out;
        die();

        //return response()->json($hotelList);

    }


}
