<?php

namespace App\Core\Service;

use App\Core\Repository\PropertyBookingEngine\PropertyBookingEngineRepository;
use App\Core\Repository\PropertyChannel\PropertyChannelRepository;
use App\Core\Service\PropertyChannelService;
use App\Core\Repository\PropertyChannelMapping\PropertyChannelMappingRepository;
use App\Core\Validator\BookingEngine\ContractUploadValidator;

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

class PropertyBookingEngineService
{

    private $propertyBookingEngineRepository;
    private $propertyChannelRepository;
    private $propertyChannelService;
    private $propertyChannelMappingRepository;
    private $contractUploadValidator;


    public function __construct(
        PropertyBookingEngineRepository $propertyBookingEngineRepository,
        PropertyChannelRepository $propertyChannelRepository,
        PropertyChannelMappingRepository $propertyChannelMappingRepository,
        PropertyChannelService $propertyChannelService,
        ContractUploadValidator $contractUploadValidator
    )
    {
        $this->propertyBookingEngineRepository = $propertyBookingEngineRepository;
        $this->propertyChannelRepository = $propertyChannelRepository;
        $this->propertyChannelService = $propertyChannelService;
        $this->propertyChannelMappingRepository = $propertyChannelMappingRepository;
        $this->contractUploadValidator = $contractUploadValidator;
    }

    public function select($param = [], $column = ['*'])
    {

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

        try {

            $data = $this->propertyBookingEngineRepository->findByCriteria($param, $column);

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

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

        return output($response);
    }




    public function createBookingEngineToken($params = []){

        $response = ['status' => "success", 'message' => '', 'data' => null];

        try {
            if($this->propertyChannelService->checkChannelCategory($params["channel_id"],3)) {

                $data = [
                    "property_id" => $params['property_id'],
                    "channel_id" => $params['channel_id'],
                    "token" => getGuid(),
                    "status" => 1,
                    "created_by" => $params['created_by'],
                    "updated_by" => $params['updated_by'],
                    "created_at" => time(),
                    "updated_at" => time(),
                ];

                $create = $this->propertyBookingEngineRepository->create($data);
                if ($create['status'] != 'success') {
                    throw new Exception('api-unknown_error');
                }
            }
        } catch (ApiErrorException $e) {
            $response['status'] = 0;
            $response['message'] = implode(', ', $e->getMessageArr());
        } catch (Exception $e) {
            $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage();
            Log::error($message);
            $response['message'] = $e->getMessage();
        }

        log:info("createBookingEngineToken",[$response]);
        return output($response);

    }

    public function reactivateBookingEngineToken($params = []){

        log:info("reactivateBookingEngineToken",[]);
        $response = ['status' => "success", 'message' => '', 'data' => null];

        try {

            if($this->propertyChannelService->checkChannelCategory($params["channel_id"],3)) {
                $updateCriteria = [
                    'criteria' => [
                        ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']],
                        ['field' => 'channel_id', 'condition' => '=', 'value' => $params['channel_id']],
                    ]
                ];

                $updateData = [
                    "status" => 1,
                    'updated_by' => $params["updated_by"],
                    'updated_at' => time(),
                ];

                $update = $this->propertyBookingEngineRepository->updateWhere($updateCriteria, $updateData);
                if ($update['status'] != 'success') {
                    throw new Exception('api-unknown_error');
                }
            }
        } catch (ApiErrorException $e) {
            $response['status'] = 0;
            $response['message'] = implode(', ', $e->getMessageArr());
        } catch (Exception $e) {
            $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage();
            Log::error($message);
            $response['message'] = $e->getMessage();
        }

        return output($response);
    }

    public function deactivateBookingEngineToken($params = []){

        log:info("reactivateBookingEngineToken",[]);
        $response = ['status' => "success", 'message' => '', 'data' => null];

        try {

            if($this->propertyChannelService->checkChannelCategory($params["channel_id"],3)) {
                $updateCriteria = [
                    'criteria' => [
                        ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']],
                        ['field' => 'channel_id', 'condition' => '=', 'value' => $params['channel_id']],
                    ]
                ];

                $updateData = [
                    "status" => 0,
                    'updated_by' => $params["updated_by"],
                    'updated_at' => time(),
                ];

                $update = $this->propertyBookingEngineRepository->updateWhere($updateCriteria, $updateData);
                if ($update['status'] != 'success') {
                    throw new Exception('api-unknown_error');
                }
            }

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

        return output($response);
    }

    public function bookEngineDashboard($params){

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

        try {

            $propertyRequest = [
                'criteria' => [
                    ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']],
                    ['field' => 'status', 'condition' => '=', 'value' => 1],
                ],
                'with' => ['channel', 'property.propertyBookingEngineGroupMapping.propertyGroup.propertyGroupMapping.property.propertyBookingEngineToken', 'propertyWeb'],
                'firstRow' => 1
            ] ;
            $propertyBookingEngine = $this->select($propertyRequest, ['id', 'property_id', 'channel_id', 'token']);
            if ($propertyBookingEngine['status'] != 'success') {
                throw new ApiErrorException($propertyBookingEngine['message']);
            }

            $propertyBookingEngine = $propertyBookingEngine['data'] ;

            $channelMappingRequest = [
                'criteria' => [
                    ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']],
                    ['field' => 'channel_id', 'condition' => '=', 'value' => 1],
                    ['field' => 'status', 'condition' => '=', 'value' => 1],
                ],
                'firstRow' => 1
            ] ;
            $propertyChannelMapping = $this->propertyChannelMappingRepository->findByCriteria($channelMappingRequest, ['id', 'property_id', 'channel_id']);

            $response = [
                'is_booking_engine_active' => isset($propertyBookingEngine['token'] ) && $propertyChannelMapping ,
                'booking_engine_url' => isset($propertyBookingEngine['token'] ) ? Config::get('app.bookingEngineUrl').'/'.$propertyBookingEngine['token'] : null,
                'token' => isset($propertyBookingEngine['token']) ? $propertyBookingEngine['token'] : null,

            ];





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

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

        return output($response);

    }

    public function contractFileUpload($params = []){

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

        try {

            $validationResult = $this->contractUploadValidator->validate($params);
            if ($validationResult->errors()->first()) {
                $errors = $validationResult->errors()->all();
                throw new ApiErrorException($errors);
            }

            $uploadResponse = [] ;
            if($params['contract_file']){

                $public_dir = Config::get('app.fileSystemDriver');
                $filePath = $public_dir . '/property-files/'.$params['property_id'].'/be';
                $filePathResponse = $params['property_id'].'/be/';

                $contractFile = $params['contract_file'];
                $newFileName = $params['property_id'] . '_'.$params['channel_id'].'_contract.pdf';

                $propertyFilesUrl = Config::get('app.propertyFilesUrl');

                $createFile = $contractFile->move($filePath, $newFileName);
                if($createFile){
                    $uploadResponse['contract_file_url'] = $propertyFilesUrl.$filePathResponse.$newFileName;
                    $uploadResponse['contract_file_path'] = $filePathResponse.$newFileName;
                }
            }

            $response = ['status' => 1, 'data' => $uploadResponse];

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

        return output($response);

    }

}
