<?php

namespace App\Http\Controllers\V1;

use App\Http\Controllers\Controller;
use App\Core\Service\PropertyChannelMappingService;
use App\Core\Service\PropertyChannelService ;
use App\Core\Service\PropertyBookingEngineService;

use Illuminate\Http\Request;

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

class PropertyChannelMappingController
{


    private $request;
    private $propertyChannelMappingService;
    private $propertyChannelService;
    private $propertyBookingEngineService;

    const CHANNEL_MANAGER = 4;
    const PARENT_ID = 5;


    public function __construct(
        Request $request,
        PropertyChannelService $propertyChannelService,
        PropertyChannelMappingService $propertyChannelMappingService,
        PropertyBookingEngineService $propertyBookingEngineService
    )
    {
        $this->request = $request;
        $this->propertyChannelMappingService = $propertyChannelMappingService;
        $this->propertyChannelService = $propertyChannelService ;
        $this->propertyBookingEngineService = $propertyBookingEngineService;

    }



    public function getPropertyChannelMapping(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'),
                'user_id' => $this->request->auth->id,
            ];

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

            $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyChannelMapping['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 addPropertyChannelMapping(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 = [
                'property_id' => fillOnUndefined($params, 'property_id'),
                'channels' => fillOnUndefined($params, 'channels', []),
                'user_id' => $this->request->auth->id,
            ];

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

            $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyChannelMapping['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 removePropertyChannelMapping(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 = [
                'property_id' => fillOnUndefined($params, 'property_id'),
                'channels' => fillOnUndefined($params, 'channels', []),
                'user_id' => $this->request->auth->id,
            ];

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

            $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyChannelMapping['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 updatePropertyChannelMapping(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;

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

            $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $propertyChannelMapping['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 addPropertyChannelSetup(Request $request)
    {

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

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

            $params =
                [
                    "property_id" => $request->input('property_id'),
                    "channel_id" => $request->input('channel_id'),
                    "booking_type_id" => $request->input('booking_type_id') != 'null' ? $request->input('booking_type_id') : null,
                    "availability_type_id" => $request->input('availability_type_id') != 'null' ? $request->input('availability_type_id') : null,
                    "room_pricing_type_id" => $request->input('room_pricing_type_id') != 'null' ? $request->input('room_pricing_type_id') : null,
                    "currency_code" => $request->input('currency_code') != 'null' ? $request->input('currency_code') : null,
                    "connected_channel_id" => $request->input('connected_channel_id') != 'null' ? $request->input('connected_channel_id') : null,
                    "connected_channel_action" => $request->input('connected_channel_action') != 'null' ? $request->input('connected_channel_action') : null,
                    "contract_file" => $request->file('contract_file')
                ];

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

            $getChannelRequest = [
                'criteria' => [
                    ['field' => 'id', 'condition' => '=', 'value' => $params['channel_id']],
                    ['field' => 'status', 'condition' => '=', 'value' => 1],
                ],
                'firstRow' => 1
            ];
            $getChannelResponse = $this->propertyChannelService->select($getChannelRequest, ['id', 'parent_id', 'channel_category_id']) ;
            if($getChannelResponse['status'] != 'success' && !empty($getChannelResponse['data'])){
                throw new ApiErrorException($getChannelResponse['message']);
            }


            if($getChannelResponse['data']['channel_category_id'] === self::CHANNEL_MANAGER && $getChannelResponse['data']['parent_id'] === self::PARENT_ID
                && !$requestParams['booking_type_id'] && !$requestParams['availability_type_id'] && !$requestParams['room_pricing_type_id'] ){

                $propertyChannelMapping = $this->propertyChannelMappingService->addPropertyChannelSetupWithMissingParameters($requestParams);

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

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

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

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

            $getChannelRequest = [
                'criteria' => [
                    ['field' => 'id', 'condition' => '=', 'value' => $params['channel_id']],
                    ['field' => 'status', 'condition' => '=', 'value' => 1],
                ],
                'with' => ['parentChannel', 'propertyChannelCategory'],
                'firstRow' => 1
            ];
            $getChannelResponse = $this->propertyChannelService->select($getChannelRequest, ['id', 'parent_id', 'name', 'official_name', 'description', 'channel_category_id', 'default_currency', 'country_code', 'currency_code', 'logo', 'address', 'zip_code', 'email', 'phone', 'phone2', 'fax', 'score', 'status']) ;
            if($getChannelResponse['status'] != 'success'){
                throw new ApiErrorException($getChannelResponse['message']);
            }
            $channelData['channel'] = $getChannelResponse['data'] ;


            $getChannelMappingRequest = [
                'criteria' => [
                    ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']],
                    ['field' => 'channel_id', 'condition' => '=', 'value' => $params['channel_id']],
                    ['field' => 'status', 'condition' => '=', 'value' => 1],
                ],
                'firstRow' => 1
            ];
            $getChannelMappingResponse = $this->propertyChannelMappingService->select($getChannelMappingRequest) ;

            if($getChannelMappingResponse['status'] != 'success'){
                throw new ApiErrorException($getChannelMappingResponse['message']);
            }
            $channelData['channel']['currency_list'] = json_decode($channelData['channel']['currency_code'] , 1);
            $channelData['channel']['currency'] = isset($getChannelMappingResponse['data']['currency_code']) ? $getChannelMappingResponse['data']['currency_code'] : $channelData['channel']['default_currency'] ;
            $channelData['channel']['is_connected'] = $getChannelMappingResponse['data'] ? true : false ;


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

            $channelData = array_merge($channelData, $propertyChannelMapping['data']) ;
            $response = ['status' => 1, 'statusCode' => 200, 'message' => null, 'data' => $channelData];

        } 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 getPropertyChannelSetup(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 = $params ;
            $requestParams['user_id'] =  $this->request->auth->id;

            $getChannelRequest = [
                'criteria' => [
                    ['field' => 'id', 'condition' => '=', 'value' => $params['channel_id']],
                    ['field' => 'status', 'condition' => '=', 'value' => 1],
                ],
                'with' => ['parentChannel', 'propertyChannelCategory'],
                'firstRow' => 1
            ];
            $getChannelResponse = $this->propertyChannelService->select($getChannelRequest, ['id', 'parent_id', 'name', 'official_name', 'default_currency', 'description', 'channel_category_id', 'country_code', 'currency_code', 'logo', 'address', 'zip_code', 'email', 'phone', 'phone2', 'fax', 'score', 'status']) ;
            if($getChannelResponse['status'] != 'success'){
                throw new ApiErrorException($getChannelResponse['message']);
            }
            $channelData['channel'] = $getChannelResponse['data'] ;

            $childChannels = [];
            if(!empty($channelData['channel']) && $channelData['channel']['parent_id'] === NULL
                 && $channelData['channel']['property_channel_category']['id'] == 4 ){

                $childChannels = $this->propertyChannelMappingService->getPropertyChildChannel(['property_id' => $params['property_id']]);

                $childChannels = $childChannels['data'];

            }


            $getChannelMappingRequest = [
                'criteria' => [
                    ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']],
                    ['field' => 'channel_id', 'condition' => '=', 'value' => $params['channel_id']],
                ],
                'with' => ['channelBookingType', 'channelAvailabilityType', 'channelRoomPricingType'] ,
                'firstRow' => 1
            ];
            $getChannelMappingResponse = $this->propertyChannelMappingService->select($getChannelMappingRequest);

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

            $getChannelMappingRequestData = [
                'criteria' => [
                    ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']],
                    ['field' => 'channel_id', 'condition' => '=', 'value' => $params['channel_id']],
                ],
                'firstRow' => 1
            ];
            $getChannelMappingResponseData = $this->propertyChannelMappingService->select($getChannelMappingRequestData) ;

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

            $isPending = false;
            if(isset($getChannelMappingResponse['data']['status'])){
                $isPending = $getChannelMappingResponse['data']['status'] === 2 ? true : false ;
            }


            $isConnected = false ;
            if(isset($getChannelMappingResponse['data']['status'])){
                $isConnected = $getChannelMappingResponse['data']['status'] ? true : false ;
            }

            $channelData['channel']['is_connected'] = $isConnected ;
            $channelData['channel']['is_pending'] = $isPending ;
            $channelData['channel']['currency_list'] = json_decode($channelData['channel']['currency_code'] , 1);
            $channelData['channel']['currency'] = isset($getChannelMappingResponse['data']['currency_code']) ? $getChannelMappingResponse['data']['currency_code'] : $channelData['channel']['default_currency'] ;
            $channelData['channel']['channel_booking_type'] = isset($getChannelMappingResponse['data']['channel_booking_type']) ? $getChannelMappingResponse['data']['channel_booking_type'] : null;
            $channelData['channel']['channel_availability_type'] = isset($getChannelMappingResponse['data']['channel_availability_type']) ? $getChannelMappingResponse['data']['channel_availability_type'] : null ;
            $channelData['channel']['channel_room_pricing_type'] = isset($getChannelMappingResponse['data']['channel_room_pricing_type'] ) ? $getChannelMappingResponse['data']['channel_room_pricing_type']  : null;
            $channelData['channel']['connected_channel_id'] =  isset($getChannelMappingResponse['data']['connected_channel_id'] ) ? $getChannelMappingResponse['data']['connected_channel_id']  : null;
            $channelData['channel']['connected_channel_action'] =  isset($getChannelMappingResponse['data']['connected_channel_action'] ) ? $getChannelMappingResponse['data']['connected_channel_action']  : null;

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

            $channelData = array_merge($channelData, $propertyChannelMapping['data']) ;
            $channelData['mapping_child_channels'] = $childChannels;


            $channelData['channel']['bookingEngineUrl'] = null;
            $channelData['channel']['bookingEngineToken'] = null;
            $propertyBookingEngineRequest = [
                'criteria' => [
                    ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']],
                    ['field' => 'channel_id', 'condition' => '=', 'value' => $params['channel_id']],
                    ['field' => 'status', 'condition' => '=', 'value' => 1],
                ],
                'firstRow' => 1
            ];
            $propertyBookingEngine = $this->propertyBookingEngineService->select($propertyBookingEngineRequest);

            $bookingEngineUrl = null;
            $bookingEngineToken = null;
            if($propertyBookingEngine['status'] == 'success' && !empty($propertyBookingEngine['data'])) {
                $bookingEngineToken = $propertyBookingEngine['data']['token'];
                $bookingEngineUrl = Config::get('app.bookingEngineUrl').'/'.$propertyBookingEngine['data']['token'];
            }

            $channelData['channel']['bookingEngineUrl'] = $bookingEngineUrl;
            $channelData['channel']['bookingEngineToken'] = $bookingEngineToken;

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

        } 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']);


    }




}
