<?php


namespace App\Http\Controllers\MetaSearch\Google\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 GoogleController 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 = 'google';
        $this->password = 'P8MUQtNP6TkKMz3E';

        $this->channelManagerId = 14;//Google

        $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->mealCodeMapping = [
            10 => 'AI',
            11 => 'BB',
            13 => 'RO',
            14 => 'FB',
            15 => 'HB',
        ];

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


    }


    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['Checkin'])->toDateString();
        $searchRequestJson['date']['checkOut'] = Carbon::parse($requestParam['Checkin'])->addDays($requestParam['Nights'])->toDateString();


        $rooms = [];
        $rooms[0]['adults'] = (integer)$requestParam['Context']['OccupancyDetails']['NumAdults'];
        $rooms[0]['children'] = (integer)($requestParam['Context']['Occupancy'] - $requestParam['Context']['OccupancyDetails']['NumAdults']);

        $rooms[0]['age'] = [];
        if (isset($requestParam['Context']['OccupancyDetails']['Children']['Child'])) {
            $requestParam['Context']['OccupancyDetails']['Children']['Child'] = singleElementXMLArray($requestParam['Context']['OccupancyDetails']['Children']['Child']);
        } else {
            $requestParam['Context']['OccupancyDetails']['Children']['Child'] = [];
        }

        foreach ($requestParam['Context']['OccupancyDetails']['Children']['Child'] as $child) {
            $rooms[0]['age'][] = $child['@attributes']['age'];
        }

        $searchRequestJson['rooms'] = $rooms;

        if (isset($requestParam['PropertyList']['Property'])) {
            $requestParam['PropertyList']['Property'] = singleElementXMLArray($requestParam['PropertyList']['Property']);
        } else {
            $requestParam['PropertyList']['Property'] = [];
        }


        $searchRequestJson['property'] = $requestParam['PropertyList']['Property'];

        return $searchRequestJson;

    }

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

        $deepLink = 'https://be.extranetwork.com/' . $token . '/' . fillOnUndefined($requestParam, 'locale', '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_source=google';

        return $deepLink;

    }


    public function hotel(Request $request)
    {

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


        $listings = new \SimpleXMLElement('<?xml version="1.0" encoding="UTF-8"?><listings xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://www.gstatic.com/localfeed/local_feed.xsd"></listings>');

        $listings->addChild('language', 'en');


        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',
                'property.propertyRooms', 'property.propertyPhotos', 'property.propertyAdditionalInfos', 'property.propertyBrand'
            ];
            $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);

                    $listing = $listings->addChild('listing');

                    $listing->addChild('id', $propertyMapping['property']['id']);
                    $listing->addChild('name', htmlspecialchars($propertyMapping['property']['name'], ENT_XML1, 'UTF-8'));

                    $address = $listing->addChild('address');
                    $address->addAttribute('format', 'simple');

                    $component = $address->addChild('component', htmlspecialchars(fillOnUndefined($metaAddress, 'street'), ENT_XML1, 'UTF-8'));
                    $component->addAttribute('name', 'addr1');

                    //$component = $address->addChild('component');
                    //$component->addAttribute('name', 'addr2');

                    $component = $address->addChild('component', fillOnUndefined($metaAddress, 'city'));
                    $component->addAttribute('name', 'city');

                    //$component = $address->addChild('component', $propertyMapping['property']['country']['name']);
                    //$component->addAttribute('name','region');

                    $component = $address->addChild('component', fillOnUndefined($metaAddress, 'zip_code'));
                    $component->addAttribute('name', 'postal_code');

                    $listing->addChild('country', $propertyMapping['property']['country']['country_code']);
                    $listing->addChild('latitude', $propertyMapping['property']['property_contact']['latitude']);
                    $listing->addChild('longitude', $propertyMapping['property']['property_contact']['longitude']);

                    if (!empty($propertyMapping['property']['property_contact']['view_full_phone'])) {
                        $phone = $listing->addChild('phone');
                        $phone->addAttribute('number', $propertyMapping['property']['property_contact']['view_full_phone']);
                    }

                    $listing->addChild('category', 'hotel');

                    if (!empty($propertyMapping['property']['property_brand']['name'])) {
                        $listing->addChild('brand', htmlspecialchars($propertyMapping['property']['property_brand']['name'], ENT_XML1, 'UTF-8'));
                    }

                    if (!empty($propertyMapping['property']['property_web']['webProtocolUrl'])) {
                        $listing->addChild('website', $propertyMapping['property']['property_web']['webProtocolUrl']);
                    }

                    $content = $listing->addChild('content');

                    $text = $content->addChild('text');
                    $text->addAttribute('type', 'description');
                    $text->addChild('body', htmlspecialchars($propertyMapping['property']['name'], ENT_XML1, 'UTF-8'));

                    $attributes = $content->addChild('attributes');
                    $clientAttrCountry = $attributes->addChild('client_attr', $propertyMapping['property']['country']['country_code']);
                    $clientAttrCountry->addAttribute('name', 'country');

                    $clientAttrMaxNightStay = $attributes->addChild('client_attr', '0');
                    $clientAttrMaxNightStay->addAttribute('name', 'max_night_stay');

                    $clientAttrMinNightStay = $attributes->addChild('client_attr', '1');
                    $clientAttrMinNightStay->addAttribute('name', 'minimum_night_stay');

                    $roomCountTotal = 0;
                    if (!empty($propertyMapping['property']['property_additional_infos'])) {
                        foreach ($propertyMapping['property']['property_additional_infos'] as $info) {
                            if ($info['additional_info_key_id'] == 3) {
                                $roomCountTotal = $info['value'];
                                break;
                            }
                        }
                    }

                    $clientAttrRooms = $attributes->addChild('client_attr', $roomCountTotal);
                    $clientAttrRooms->addAttribute('name', 'number_of_rooms');

                    $clientAttrLatLong = $attributes->addChild('client_attr', $propertyMapping['property']['property_contact']['latitude'] . ', ' . $propertyMapping['property']['property_contact']['longitude']);
                    $clientAttrLatLong->addAttribute('name', 'latlong');

                    if (!empty($propertyMapping['property']['property_photos'])) {
                        $photos = $propertyMapping['property']['property_photos'];

                        // Filter photos with status 1
                        $photos = array_filter($photos, function ($p) {
                            return isset($p['status']) && $p['status'] == 1;
                        });

                        // Sort photos by is_default (desc), photo_order (asc), and created_at (desc)
                        usort($photos, function ($a, $b) {
                            return ($b['is_default'] ?? 0) <=> ($a['is_default'] ?? 0)
                                ?: ($a['photo_order'] ?? 0) <=> ($b['photo_order'] ?? 0)
                                ?: ($b['created_at'] ?? 0) <=> ($a['created_at'] ?? 0);
                        });

                        // Limit to first 10 photos
                        $photos = array_slice($photos, 0, 10);

                        foreach ($photos as $photo) {
                            $imageUrl = $photo['photoUrl']['default'] ?? $photo['photo_url']['default'] ?? null;

                            if ($imageUrl) {
                                $image = $content->addChild('image');
                                $image->addAttribute('type', 'ad');
                                $image->addAttribute('url', $imageUrl);

                                $width = '1440';
                                $height = '959';

                                if (!empty($photo['photo_resolution'])) {
                                    $resolution = explode('x', $photo['photo_resolution']);
                                    if (count($resolution) == 2) {
                                        $width = trim($resolution[0]);
                                        $height = trim($resolution[1]);
                                    }
                                }

                                $image->addAttribute('width', $width);
                                $image->addAttribute('height', $height);

                                $image->addChild('link', $imageUrl);
                                $image->addChild('title', 'Unknown title');

                                $date = $image->addChild('date');
                                if (!empty($photo['created_at'])) {
                                    $photoCreatedAt = Carbon::createFromTimestamp($photo['created_at']);
                                } else {
                                    $photoCreatedAt = Carbon::now();
                                }

                                $date->addAttribute('day', $photoCreatedAt->day);
                                $date->addAttribute('month', $photoCreatedAt->month);
                                $date->addAttribute('year', $photoCreatedAt->year);
                            }
                        }
                    }


                }

            }


        } 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();
        }

        header('Content-Type: application/xml; charset=UTF-8');
        echo $listings->asXML();
        exit;


    }

}
