<?php


namespace App\Core\Service\ChannelManager;


use App\Core\Mail\LogMail;
use App\Core\Service\BookingService;
use App\Core\Service\ChannelManagerMappingService;
use App\Core\Service\ChannelManagerPropertyMappingService;
use App\Exceptions\ApiErrorException;
use Carbon\Carbon;
use GuzzleHttp\Client;
use Illuminate\Mail\Mailer;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Log;
use Exception;


class Trivago
{

    private $statusMapping;
    private $paymentTypeMapping;
    private $channelManagerId;
    private $channelManagerName;
    private $mailer;

    public function __construct(
        Client $restClient,
        Mailer $mailer,
        ChannelManagerPropertyMappingService $channelManagerPropertyMappingService,
        ChannelManagerMappingService $channelManagerMappingService,
        BookingService $bookingService
    )
    {
        $this->restClient = $restClient;
        $this->mailer = $mailer;
        $this->reservationPushUrl = 'https://secde.trivago.com/tracking/booking';


        $this->typeMapping = [
            'Booking' => 'Booking',
            'Modify' => 'Modify',
            'Cancel' => 'Cancel'
        ];

        $this->channelManagerId = 11;
        $this->channelManagerName = 'Trivago';
        $this->xTrvAnaKey = '1fe8a527-cbcb-4e01-9a3c-31444d47c422';
        $this->advertiserId = 3698;

        $this->channelManagerPropertyMappingService = $channelManagerPropertyMappingService;
        $this->channelManagerMappingService = $channelManagerMappingService;
        $this->bookingService = $bookingService;

    }

    public function requestPostReservationPushParam($propertyId, $bookingId, $type, $param = [])
    {

        $type = $this->typeMapping[$type];
        $bookingDetail = $param['booking_detail'];

        $jsonResponse = [];

        $extraParam = json_decode($bookingDetail['extra_param'], 1);
        if (!isset($extraParam['trv_reference'])) {
            return $jsonResponse;
        }

        $locale = 'TR';
        if(isset($extraParam['locale'])) {
            $locale = $extraParam['locale'];
        }

        if($bookingDetail['total'] > 0) {
            $bookingDetail['total'] = $bookingDetail['total'];
        } else {
            $bookingDetail['total'] = $bookingDetail['booking_payment']['total'];
        }

        $jsonResponse['trv_reference'] = $extraParam['trv_reference'];
        $jsonResponse['advertiser_id'] = $this->advertiserId;
        $jsonResponse['hotel'] = $bookingDetail['property_id'];
        $jsonResponse['arrival'] = Carbon::parse($bookingDetail['checkin_date'])->format('Ymd');
        $jsonResponse['departure'] = Carbon::parse($bookingDetail['checkout_date'])->format('Ymd');
        $jsonResponse['date_format'] = 'Ymd';
        $jsonResponse['volume'] = $bookingDetail['total'];
        $jsonResponse['currency'] = $bookingDetail['currency_code'];
        $jsonResponse['locale'] = mb_strtoupper($locale);
        $jsonResponse['booking_id'] = $bookingDetail['booking_code'];
        //$jsonResponse['margin'] = $bookingDetail['booking_code'];
        $jsonResponse['booking_date'] = Carbon::createFromTimestamp($bookingDetail['created_at'])->subHours(3)->format('YmdHisP');
        $jsonResponse['booking_date_format'] = 'YmdHisP';
        $jsonResponse['number_of_rooms'] = count($bookingDetail['booking_room']);

        if ($type == 'Modify') {
            $jsonResponse['update_date'] = Carbon::createFromTimestamp($param['created_at'])->subHours(3)->format('YmdHisP');
            $jsonResponse['update_date_format'] = 'YmdHisP';
            $jsonResponse['update_origin'] = 'user';
        }

        if ($type == 'Cancel') {
            $jsonResponse['refund_amount'] = $bookingDetail['total'];
            $jsonResponse['cancellation_date'] = Carbon::createFromTimestamp($param['created_at'])->subHours(3)->format('YmdHisP');
            $jsonResponse['cancellation_date_format'] = 'YmdHisP';
        }

        $jsonResponse['params']['type'] = $type;

        return json_encode($jsonResponse);

    }

    public function requestPostReservationPush($jsonPayload)
    {
        $response = ['status' => false, 'message' => ''];


        $getResponse = [];
        $this->restClient = new Client(['http_errors' => false]);

        try {



            $jsonData = json_decode($jsonPayload, 1);
            $jsonDataParams = $jsonData['params'];
            unset($jsonData['params']);
            $jsonPayload = json_encode($jsonData);


            switch ($jsonDataParams['type']) {
                case 'Booking':

                    $request = $this->restClient->post($this->reservationPushUrl,
                        [
                            'headers' => [
                                'X-Trv-Ana-Key' => $this->xTrvAnaKey,
                                'Content-Type' => 'application/json'
                            ],
                            'body' => $jsonPayload,
                        ]
                    );

                    break;
                case 'Modify':

                    $request = $this->restClient->put($this->reservationPushUrl,
                        [
                            'headers' => [
                                'X-Trv-Ana-Key' => $this->xTrvAnaKey,
                                'Content-Type' => 'application/json'
                            ],
                            'body' => $jsonPayload,
                        ]
                    );

                    break;
                case 'Cancel':

                    $request = $this->restClient->delete($this->reservationPushUrl,
                        [
                            'headers' => [
                                'X-Trv-Ana-Key' => $this->xTrvAnaKey,
                                'Content-Type' => 'application/json'
                            ],
                            'body' => $jsonPayload,
                        ]
                    );

                    break;
                case 'default':
                    throw new ApiErrorException('Reservation push type not found.');
                    break;

            }

            $getResponseBody = $request->getBody();
            $getResponseJsonBase = $getResponseBody->getContents();

            $getResponse = json_decode($getResponseJsonBase, 1);

            Log::debug($jsonPayload);
            Log::debug(json_encode($getResponse));

            //dd($getResponse);

            if ($getResponse['state'] != 'OK') {
                throw new ApiErrorException($getResponse['errorMessage']);
            }

            $response = ['status' => true, 'message' => '', 'response' => json_encode($getResponse)];

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


        return $response;

    }


}
