<?php

namespace App\Core\Service;

use App\Core\Repository\PropertyWeb\PropertyWebComponentMappingRepository;
use App\Core\Repository\PropertyWeb\PropertyWebComponentRepository;
use App\Core\Repository\PropertyWeb\PropertyWebGroupRepository;
use App\Core\Repository\PropertyWeb\PropertyWebReviewRepository;
use App\Core\Service\PropertyPhotoService\PropertyPhotoService;
use App\Core\Repository\PropertyWeb\PropertyWebRepository;
use App\Core\Repository\PropertyWebPhotoMapping\PropertyWebPhotoMappingRepository;
use App\Core\Service\PropertyWebAboutUsService;
use App\Core\Service\PropertyWebMenuMappingService;
use App\Core\Service\PropertyWebMenuService;
use App\Core\Validator\PropertyWeb\PropertyWebCreateValidator;
use App\Core\Validator\PropertyWeb\PropertyWebUpdateContentValidator;
use App\Core\Validator\PropertyWeb\PropertyWebUpdateValidator;
use App\Core\Validator\PropertyWeb\PropertyWebPublishValidator;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Redis;
use Illuminate\Support\Str;
use App\Core\Service\PropertyAdditionalInfo\PropertyAdditionalInfoService;

use Illuminate\Support\Facades\Log;
use Exception;
use App\Exceptions\ApiErrorException;
use Illuminate\Support\Facades\Config;
use Carbon\Carbon;
use App\Core\Service\PropertyWebSetupService;
use App\Core\Service\PropertyWebLanguageMappingService;
use App\Core\Service\PropertyWebColorMappingService;

class PropertyWebService
{

    private $propertyWebRepository;
    private $propertyWebCreateValidator;
    private $propertyWebUpdateValidator;
    private $propertyWebPhotoMappingRepository;
    private $propertyPhotoService;
    private $propertyWebUpdateContentValidator;
    private $propertyWebPublishValidator;
    private $propertyWebMenuService;
    private $propertyWebMenuMappingService;
    private $propertyWebSetupService;
    private $propertyWebLanguageMappingService;
    private $propertyWebColorMappingService;
    private $propertyWebAboutUsService;
    private $propertyAdditionalInfoService;
    private $propertyWebRoomMappingService;
    private $propertyWebReviewRepository;

    public function __construct(
        PropertyWebRepository $propertyWebRepository,
        PropertyWebGroupRepository $propertyWebGroupRepository,
        PropertyWebPhotoMappingRepository $propertyWebPhotoMappingRepository,
        PropertyPhotoService $propertyPhotoService,
        PropertyWebCreateValidator $propertyWebCreateValidator,
        PropertyWebUpdateValidator $propertyWebUpdateValidator,
        PropertyWebUpdateContentValidator $propertyWebUpdateContentValidator,
        PropertyWebPublishValidator $propertyWebPublishValidator,
        PropertyWebMenuService $propertyWebMenuService,
        PropertyWebMenuMappingService $propertyWebMenuMappingService,
        PropertyWebSetupService $propertyWebSetupService,
        PropertyWebLanguageMappingService $propertyWebLanguageMappingService,
        PropertyWebColorMappingService $propertyWebColorMappingService,
        PropertyAdditionalInfoService $propertyAdditionalInfoService,
        PropertyWebAboutUsService $propertyWebAboutUsService,
        PropertyWebRoomMappingService $propertyWebRoomMappingService,
        PropertyWebPlaceMappingService $propertyWebPlaceMappingService,
        PropertyWebComponentRepository $propertyWebComponentRepository,
        PropertyWebComponentMappingRepository $propertyWebComponentMappingRepository,
        PropertyWebReviewRepository $propertyWebReviewRepository
    )
    {
        $this->propertyWebRepository = $propertyWebRepository;
        $this->propertyWebGroupRepository = $propertyWebGroupRepository;
        $this->propertyWebCreateValidator = $propertyWebCreateValidator;
        $this->propertyWebUpdateValidator = $propertyWebUpdateValidator;
        $this->propertyWebPhotoMappingRepository = $propertyWebPhotoMappingRepository;
        $this->propertyPhotoService = $propertyPhotoService;
        $this->propertyWebUpdateContentValidator = $propertyWebUpdateContentValidator;
        $this->propertyWebPublishValidator = $propertyWebPublishValidator;
        $this->propertyWebMenuService = $propertyWebMenuService;
        $this->propertyWebMenuMappingService = $propertyWebMenuMappingService;
        $this->propertyWebSetupService = $propertyWebSetupService;
        $this->propertyWebLanguageMappingService = $propertyWebLanguageMappingService;
        $this->propertyWebColorMappingService = $propertyWebColorMappingService;
        $this->propertyWebAboutUsService = $propertyWebAboutUsService;
        $this->propertyAdditionalInfoService = $propertyAdditionalInfoService;
        $this->propertyWebRoomMappingService = $propertyWebRoomMappingService;
        $this->propertyWebPlaceMappingService = $propertyWebPlaceMappingService;
        $this->propertyWebComponentRepository = $propertyWebComponentRepository;
        $this->propertyWebComponentMappingRepository = $propertyWebComponentMappingRepository;
        $this->propertyWebReviewRepository = $propertyWebReviewRepository;
    }

    public function create($param = [])
    {
        $response = ['status' => -1, 'message' => '', 'data' => null];
        try {


            $validationResult = $this->propertyWebCreateValidator->validate($param);

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

            $insertData =
                [
                    "property_id" => fillOnUndefined($param, "property_id"),
                    "domain" => fillOnUndefined($param, "domain"),
                    "default_language" => fillOnUndefined($param, "default_language"),
                    "template_id" => fillOnUndefined($param, "template_id"),
                    "token" => getGuid(),
                    "status" => 1,
                    "is_published" => 0,
                    "is_dns_checked" => 0,
                    "created_by" => fillOnUndefined($param, "user_id"),
                    "updated_by" => fillOnUndefined($param, "user_id"),
                    "created_at" => time(),
                    "updated_at" => time(),
                ];

            $userCreateResult = $this->propertyWebRepository->create($insertData);
            if ($userCreateResult['status'] != 'success') {
                throw new Exception('api-unknown_error');
            }
            $userData = $userCreateResult["data"];
            $response = [
                'status' => true,
                'data' => $userData,
            ];

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

        return output($response);
    }

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

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

        try {

            $data = $this->propertyWebRepository->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 selectWebGroup($param = [], $column = ['*'])
    {

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

        try {

            $data = $this->propertyWebGroupRepository->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 update($id, $param = [])
    {

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


            $propertyRequest = [
                'criteria' => [
                    ['field' => 'property_id', 'condition' => '=', 'value' => fillOnUndefined($param, 'property_id')],
                    ['field' => 'id', 'condition' => '=', 'value' => fillOnUndefined($param, 'property_web_id')],
                    ['field' => 'status', 'condition' => '=', 'value' => 1],
                ]
            ];
            $propertyWebData = $this->propertyWebRepository->findByCriteria($propertyRequest, ['id', 'domain']);

            if (!$propertyWebData) {
                throw new ApiErrorException(lang('Property - Web mapping not found.'));
            }

            $updateData =
                [
                    "domain" => fillOnUndefined($param, "domain"),
                    "default_language" => fillOnUndefined($param, "default_language"),
                    "template_id" => fillOnUndefined($param, "template_id"),
                    "updated_by" => fillOnUndefined($param, "user_id"),
                    "updated_at" => time(),
                ];

            $validationResult = $this->propertyWebUpdateValidator->validate($param);

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

            $updateResult = $this->propertyWebRepository->update($id, $updateData);

            if ($updateResult['status'] != 'success') {
                throw new Exception('api-unknown_error');
            }
            $updateData = $updateResult["data"];
            $response = [
                'status' => true,
                'data' => $updateData,
            ];

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

        return output($response);
    }

    public function updateLanguages($param = [])
    {


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

            $propertyRequest = [
                'criteria' => [
                    ['field' => 'property_id', 'condition' => '=', 'value' => fillOnUndefined($param, 'property_id')],
                    ['field' => 'id', 'condition' => '=', 'value' => fillOnUndefined($param, 'property_web_id')],
                    ['field' => 'status', 'condition' => '=', 'value' => 1],
                ],
                'firstRow' => true
            ];
            $propertyWebData = $this->propertyWebRepository->findByCriteria($propertyRequest, ['id', 'domain']);

            if (!$propertyWebData) {
                throw new ApiErrorException(lang('Property - Web updateLanguage data not found.'));
            }

            $updateData =
                [
                    "languages" => fillOnUndefined($param, "languages"),
                    "updated_by" => fillOnUndefined($param, "user_id"),
                    "updated_at" => time(),
                ];

            $updateResult = $this->propertyWebRepository->update($propertyWebData['id'], $updateData);

            if ($updateResult['status'] != 'success') {
                throw new Exception('api-unknown_error');
            }
            $updateData = $updateResult["data"];
            $response = [
                'status' => true,
                'data' => $updateData,
            ];

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

        return output($response);

    }

    public function getPropertyWeb($params = [])
    {
        $response = ['status' => -1, 'message' => '', 'data' => null];
        try {


            $propertyRequest = [
                'criteria' => [
                    ['field' => 'property_id', 'condition' => '=', 'value' => fillOnUndefined($params, 'property_id')],
                    ['field' => 'id', 'condition' => '=', 'value' => fillOnUndefined($params, 'id')],
                ],
                "with" => ['propertyWebTemplate', 'propertyWebLanguage'],
                "firstRow" => 1
            ];
            $propertyWebs = $this->select($propertyRequest, ['id', 'domain', 'default_language', 'template_id', 'token', 'status', 'is_published', 'is_dns_checked', 'weather_active', 'cover_video_id']);
            if ($propertyWebs['status'] != 'success' || !$propertyWebs['data']) {
                throw new ApiErrorException('Property Web Data not found');
            }

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

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

        return output($response);
    }

    public function insertAllPropertyWebPhotosToMapping($params = [])
    {
        $response = ['status' => -1, 'message' => '', 'data' => null];
        try {

            $propertyPhotoRequest = [
                'criteria' => [
                    ['field' => 'property_id', 'condition' => '=', 'value' => fillOnUndefined($params, 'property_id')],
                    ['field' => 'status', 'condition' => '=', 'value' => 1],
                ],
            ];

            $propertyPhotos = $this->propertyPhotoService->select($propertyPhotoRequest, ['*']);
            if ($propertyPhotos['status'] != 'success') {
                throw new ApiErrorException('Property Photo Data not found');
            }

            $propertyPhotos = $propertyPhotos['data'] ? $propertyPhotos['data'] : [];
            $insertPhotos = [];

            foreach ($propertyPhotos as $propertyPhoto) {
                $insertPhotos[] = [
                    'property_id' => fillOnUndefined($params, 'property_id'),
                    'property_web_id' => fillOnUndefined($params, 'id'),
                    'property_photo_id' => $propertyPhoto['id'],
                    'is_cover' => 0,
                    'status' => 1,
                    "created_by" => fillOnUndefined($params, "user_id"),
                    "updated_by" => fillOnUndefined($params, "user_id"),
                    "created_at" => time(),
                    "updated_at" => time(),
                ];
            }

            $propertyWebPhotos = $this->propertyWebPhotoMappingRepository->insert($insertPhotos);
            if ($propertyWebPhotos['status'] != 'success') {
                throw new Exception('api-unknown_error');
            }

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

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

        return output($response);
    }

    public function getPropertyWebPhotos($params = [])
    {
        $response = ['status' => -1, 'message' => '', 'data' => null];
        try {
            $propertyPhotoRequest = [
                'property_id' => fillOnUndefined($params, 'property_id')
            ];

            $propertyPhotos = $this->propertyPhotoService->getPropertyPhotos($propertyPhotoRequest);
            if ($propertyPhotos['status'] != 'success') {
                throw new ApiErrorException('Property Photo Data not found');
            }
            $propertyPhotos = $propertyPhotos['data'];
            $propertyWebPhotoMappingRequest = [
                'criteria' => [
                    ['field' => 'property_id', 'condition' => '=', 'value' => fillOnUndefined($params, 'property_id')],
                    ['field' => 'property_web_id', 'condition' => '=', 'value' => fillOnUndefined($params, 'id')],
                    ['field' => 'status', 'condition' => '=', 'value' => 1],
                ],
            ];
            $propertyWebMappingPhotos = $this->propertyWebPhotoMappingRepository->findByCriteria($propertyWebPhotoMappingRequest);

            $propertyWebMappingPhotos = $propertyWebMappingPhotos ? $propertyWebMappingPhotos : [];
            $propertyWebPhotos = collect($propertyWebMappingPhotos)->keyBy('property_photo_id')->toArray();
            $propertyWebCover = collect($propertyWebMappingPhotos)->where('is_cover', '=', 1)->keyBy('property_photo_id')->toArray();

            $photoArray = [];
            foreach ($propertyPhotos as $propertyPhoto) {
                $propertyWebCoverPhoto = isset($propertyWebCover[$propertyPhoto['id']]) ? $propertyWebCover[$propertyPhoto['id']] : null;
                $photoArray[] = [
                    'photo_id' => $propertyPhoto['id'],
                    'photo_url_thump' => $propertyPhoto['photo_url_thump'],
                    'is_cover' => isset($propertyWebCover[$propertyPhoto['id']]),
                    'cover_order' => fillOnUndefined($propertyWebCoverPhoto,'cover_order'),
                    'is_selected' => isset($propertyWebPhotos[$propertyPhoto['id']]),
                    'is_compatible_with_myweb_slider' => $propertyPhoto['is_compatible_with_myweb_slider']

                ];
            }

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

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

        return output($response);
    }


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

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

        try {

            $data = $this->propertyWebPhotoMappingRepository->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 updatePropertyWebContent($params = [])
    {
        $response = ['status' => -1, 'message' => '', 'data' => null];
        try {
            DB::beginTransaction();
            $validationResult = $this->propertyWebUpdateContentValidator->validate($params);
            if ($validationResult->errors()->first()) {
                $errors = $validationResult->errors()->all();
                throw new ApiErrorException($errors);
            }


            $updateData = [
                "weather_active" => fillOnUndefined($params, "weather_active", null),
                "cover_video_id" => fillOnUndefined($params, "cover_video_id", null),
                "updated_at" => time(),
            ];

            $this->propertyWebRepository->update($params['property_web_id'], $updateData);


            $languagesUpdateData = [
                "property_id" => fillOnUndefined($params, "property_id"),
                "property_web_id" => fillOnUndefined($params, "property_web_id"),
                "user_id" => fillOnUndefined($params, "user_id")
            ];
            $languagesUpdateData['languages'] = NULL;

            if (!empty($params['languages'])) {
                $languagesUpdateData['languages'] = json_encode($params['languages']);
            }


            $updatePropertyWebLanguageMappingResult = $this->propertyWebLanguageMappingService->updatePropertyWebLanguageMapping($params);
            if ($updatePropertyWebLanguageMappingResult['status'] != 'success') {
                throw new ApiErrorException($updatePropertyWebLanguageMappingResult['message']);
            }

            $updatePropertyWebColorMappingResult = $this->propertyWebColorMappingService->updatePropertyWebColorMapping($params);
            if ($updatePropertyWebColorMappingResult['status'] != 'success') {
                throw new ApiErrorException($updatePropertyWebColorMappingResult['message']);
            }

            $updatePropertyWebMenuMappingResult = $this->propertyWebMenuMappingService->updatePropertyWebMenuMapping($params);
            if ($updatePropertyWebMenuMappingResult['status'] != 'success') {
                throw new ApiErrorException($updatePropertyWebMenuMappingResult['message']);
            }

            $updatePropertyWeAboutUsResult = $this->propertyWebAboutUsService->updatePropertyWebAboutUs($params);
            if ($updatePropertyWeAboutUsResult['status'] != 'success') {
                throw new ApiErrorException($updatePropertyWeAboutUsResult['message']);
            }

            $updatePropertyWebRoomMappingResult = $this->propertyWebRoomMappingService->updatePropertyWebRooomMapping($params);
            if ($updatePropertyWebRoomMappingResult['status'] != 'success') {
                throw new ApiErrorException($updatePropertyWebRoomMappingResult['message']);
            }


            $updatePropertyWebPlaceMappingResult = $this->propertyWebPlaceMappingService->updatePropertyWebPlaceMapping($params);
            if ($updatePropertyWebPlaceMappingResult['status'] != 'success') {
                throw new ApiErrorException($updatePropertyWebPlaceMappingResult['message']);
            }

            $updateAdditionalInfoData = [
                'locale' => fillOnUndefined($params, 'locale'),
                'additional_info' => fillOnUndefined($params, 'additional_info'),
                'property_id' => fillOnUndefined($params, 'property_id'),
                'user_id' => $params['user_id'],
                'country_code' => fillOnUndefined($params, 'property_country_code'),
            ];

            if ($params['action'] == "publish") {
                $updateAdditionalInfo = $this->propertyAdditionalInfoService->updateOrCreatePropertyAdditionalInfo($updateAdditionalInfoData);

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

            if ($params['action'] == "preview") {
                $updatePhotoPreview = $this->updatePhotoPreview($params);
                if ($updatePhotoPreview['status'] != 'success') {
                    throw new ApiErrorException($updatePhotoPreview['message']);
                }
            } elseif ($params['action'] == "publish") {
                $updatePhotoPublish = $this->updatePhotoPublish($params);
                if ($updatePhotoPublish['status'] != 'success') {
                    throw new ApiErrorException($updatePhotoPublish['message']);
                }
            }


            //Domain Cache Clean
            //if ($params['action'] == "publish") {
                $propertyRequest = [
                    'criteria' => [
                        ['field' => 'property_id', 'condition' => '=', 'value' => fillOnUndefined($params, 'property_id')],
                        ['field' => 'id', 'condition' => '=', 'value' => fillOnUndefined($params, 'property_web_id')],
                        ['field' => 'status', 'condition' => '=', 'value' => 1],
                    ], 'firstRow' => true
                ];
                $propertyWebData = $this->propertyWebRepository->findByCriteria($propertyRequest, ['id', 'domain']);

                if ($propertyWebData) {
                    $checkDomainStatusCacheKey = 'myweb:' . 'checkDomainStatus'.md5('checkDomainStatus-' . $propertyWebData['domain']);
                    if (!empty(Redis::executeRaw(['KEYS', $checkDomainStatusCacheKey]))) {
                        Redis::executeRaw(['DEL', $checkDomainStatusCacheKey]);
                    }
                }
            //}
            //Domain Cache Clean

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

            DB::commit();
        } catch (ApiErrorException $e) {
            $response['message'] = implode(', ', $e->getMessageArr());
            DB::rollBack();

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

        }

        return output($response);
    }

    public function updatePhotoPreview($params = [])
    {
        $response = ['status' => -1, 'message' => '', 'data' => null];
        try {

            // delete preview photos ;
            $getDeletePhotosRequest = [
                'criteria' => [
                    ['field' => 'property_id', 'condition' => '=', 'value' => fillOnUndefined($params, 'property_id')],
                    ['field' => 'property_web_id', 'condition' => '=', 'value' => fillOnUndefined($params, 'property_web_id')],
                    ['field' => 'status', 'condition' => '=', 'value' => 2],
                ],
            ];

            $deleteWebMappingPhotos = $this->propertyWebPhotoMappingRepository->findByCriteria($getDeletePhotosRequest, ['id']);
            $deleteWebMappingPhotos = $deleteWebMappingPhotos ? $deleteWebMappingPhotos : [];
            $deleteMappingIds = array_column($deleteWebMappingPhotos, 'id');
            if ($deleteMappingIds) {
                $destroyStatus = $this->propertyWebPhotoMappingRepository->destroy($deleteMappingIds);
                if ($destroyStatus['status'] != 'success') {
                    throw new Exception('api-unknown_error');
                }
            }


            $coverPhotos = $params['cover_photos'];
            $photoMapping = $params['photo_mapping'];
            $insertPhotos = [];

            $coverOrder = 1;
            foreach ($coverPhotos as $photoId) {
                $insertPhotos[] = [
                    'property_id' => fillOnUndefined($params, 'property_id'),
                    'property_web_id' => fillOnUndefined($params, 'property_web_id'),
                    'property_photo_id' => $photoId,
                    'is_cover' => 1,
                    'cover_order' => $coverOrder,
                    'status' => 2,
                    "created_by" => fillOnUndefined($params, "user_id"),
                    "updated_by" => fillOnUndefined($params, "user_id"),
                    "created_at" => time(),
                    "updated_at" => time(),
                ];
                $coverOrder++;
            }

            foreach ($photoMapping as $photoId) {
                $insertPhotos[] = [
                    'property_id' => fillOnUndefined($params, 'property_id'),
                    'property_web_id' => fillOnUndefined($params, 'property_web_id'),
                    'property_photo_id' => $photoId,
                    'is_cover' => 0,
                    'cover_order' => null,
                    'status' => 2,
                    "created_by" => fillOnUndefined($params, "user_id"),
                    "updated_by" => fillOnUndefined($params, "user_id"),
                    "created_at" => time(),
                    "updated_at" => time(),
                ];
            }

            $propertyWebPhotos = $this->propertyWebPhotoMappingRepository->insert($insertPhotos);
            if ($propertyWebPhotos['status'] != 'success') {
                throw new Exception('api-unknown_error');
            }

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

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

        }

        return output($response);
    }

    public function updatePhotoPublish($params = [])
    {
        $response = ['status' => -1, 'message' => '', 'data' => null];
        try {

            // delete preview photos ;
            $getDeletePhotosRequest = [
                'criteria' => [
                    ['field' => 'property_id', 'condition' => '=', 'value' => fillOnUndefined($params, 'property_id')],
                    ['field' => 'property_web_id', 'condition' => '=', 'value' => fillOnUndefined($params, 'property_web_id')],
                ],
            ];

            $deleteWebMappingPhotos = $this->propertyWebPhotoMappingRepository->findByCriteria($getDeletePhotosRequest, ['id']);
            $deleteWebMappingPhotos = $deleteWebMappingPhotos ? $deleteWebMappingPhotos : [];
            $deleteMappingIds = array_column($deleteWebMappingPhotos, 'id');
            if ($deleteMappingIds) {
                $destroyStatus = $this->propertyWebPhotoMappingRepository->destroy($deleteMappingIds);
                if ($destroyStatus['status'] != 'success') {
                    throw new Exception('api-unknown_error');
                }
            }

            $coverPhotos = $params['cover_photos'];
            $photoMapping = $params['photo_mapping'];
            $insertPhotos = [];

            $coverPhotosCollect = collect($coverPhotos);
            $photoMappingCollect = collect($photoMapping);
            $photoMapping = $photoMappingCollect->diff($coverPhotosCollect)->toArray();

            $coverOrder = 1;
            foreach ($coverPhotos as $photoId) {
                $insertPhotos[] = [
                    'property_id' => fillOnUndefined($params, 'property_id'),
                    'property_web_id' => fillOnUndefined($params, 'property_web_id'),
                    'property_photo_id' => $photoId,
                    'is_cover' => 1,
                    'cover_order' => $coverOrder,
                    'status' => 1,
                    "created_by" => fillOnUndefined($params, "user_id"),
                    "updated_by" => fillOnUndefined($params, "user_id"),
                    "created_at" => time(),
                    "updated_at" => time(),
                ];
                $coverOrder++;
            }

            foreach ($photoMapping as $photoId) {
                $insertPhotos[] = [
                    'property_id' => fillOnUndefined($params, 'property_id'),
                    'property_web_id' => fillOnUndefined($params, 'property_web_id'),
                    'property_photo_id' => $photoId,
                    'is_cover' => 0,
                    'cover_order' => null,
                    'status' => 1,
                    "created_by" => fillOnUndefined($params, "user_id"),
                    "updated_by" => fillOnUndefined($params, "user_id"),
                    "created_at" => time(),
                    "updated_at" => time(),
                ];
            }

            $propertyWebPhotos = $this->propertyWebPhotoMappingRepository->insert($insertPhotos);
            if ($propertyWebPhotos['status'] != 'success') {
                throw new Exception('api-unknown_error');
            }

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

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

        }

        return output($response);
    }

    public function setPublishWeb($param = [])
    {

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


            $validationResult = $this->propertyWebPublishValidator->validate($param);

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

            $propertyRequest = [
                'criteria' => [
                    ['field' => 'property_id', 'condition' => '=', 'value' => fillOnUndefined($param, 'property_id')],
                    ['field' => 'id', 'condition' => '=', 'value' => fillOnUndefined($param, 'property_web_id')],
                    ['field' => 'status', 'condition' => '=', 'value' => 1],
                ]
            ];
            $propertyWebData = $this->propertyWebRepository->findByCriteria($propertyRequest, ['id', 'domain']);

            if (!$propertyWebData) {
                throw new ApiErrorException(lang('Property - Web mapping not found.'));
            }

            $updateData =
                [
                    "is_published" => fillOnUndefined($param, "is_publish", 0),
                    "updated_by" => fillOnUndefined($param, "user_id"),
                    "updated_at" => time(),
                ];


            $updateResult = $this->propertyWebRepository->update($param['property_web_id'], $updateData);

            if ($updateResult['status'] != 'success') {
                throw new Exception('api-unknown_error');
            }
            $updateData = $updateResult["data"];
            $response = [
                'status' => true,
                'data' => $updateData,
            ];

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

        return output($response);
    }

    public function checkDnsStatus()
    {

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

            $propertyRequest = [
                'criteria' => [

                    ['field' => 'status', 'condition' => '=', 'value' => 1],
                    ['field' => 'is_dns_checked', 'condition' => '=', 'value' => 0],
                ]
            ];
            $propertyWebData = $this->propertyWebRepository->findByCriteria($propertyRequest, ['id', 'domain']);

            if (!$propertyWebData) {
                throw new ApiErrorException(lang('Property - Web mapping not found.'));
            }

            foreach ($propertyWebData as $web) {

                $checkHostName = $web['domain'];
                $domainStatus = 0;
                $hostNameArray = parse_url($checkHostName);

                if (isset($hostNameArray['host'])) {
                    $hostName = $hostNameArray['host'];
                } else {
                    $pathArray = explode('/', $hostNameArray['path']);
                    $hostName = $pathArray[0];
                }

                $recordsArray = [];
                $checkRecords = dns_get_record($hostName, DNS_CNAME, $authns_cname, $addtl_cname);
                $recordsArray = array_merge($recordsArray, $checkRecords);
                $recordsCollection = collect($recordsArray);

                if ($recordsCollection->where('type', 'CNAME')->where('target', '=', Config::get('app.getMyWebCNAME'))->isNotEmpty() === true) {
                    $domainStatus = 1;
                }

                if ($domainStatus == 1) {
                    $updateData =
                        [
                            "is_dns_checked" => 1,
                            "updated_by" => 1,
                            "updated_at" => time(),
                        ];
                    $updateResult = $this->propertyWebRepository->update($web['id'], $updateData);
                    if ($updateResult['status'] != 'success') {
                        throw new Exception('api-unknown_error');
                    }
                }
            }
            $response = [
                'status' => true,
            ];

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

        return output($response);
    }


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

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

        try {

            $data = $this->propertyWebComponentRepository->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 selectPropertyWebComponentMapping($param = [], $column = ['*'])
    {

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

        try {

            $data = $this->propertyWebComponentMappingRepository->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 createPropertyWebComponentMapping($param = [])
    {
        $response = ['status' => -1, 'message' => '', 'data' => null];
        try {

            $insertData = [
                'property_id' => fillOnUndefined($param, 'property_id'),
                'channel_id' => fillOnUndefined($param, 'channel_id'),
                'component_id' => fillOnUndefined($param, 'component_id'),
                'parameter' => fillOnUndefined($param, 'parameter'),
                'language' => fillOnUndefined($param, 'language'),
                'status' => 1,
                'created_by' => fillOnUndefined($param, 'created_by'),
                'updated_by' => fillOnUndefined($param, 'updated_by'),
                'created_at' => time(),
                'updated_at' => time(),
            ];

            $createResult = $this->propertyWebComponentMappingRepository->create($insertData);
            if ($createResult['status'] != 'success') {
                throw new Exception('api-unknown_error');
            }

            //Domain Cache Clean
            $propertyRequest = [
                'criteria' => [
                    ['field' => 'property_id', 'condition' => '=', 'value' => fillOnUndefined($param, 'property_id')],
                    ['field' => 'status', 'condition' => '=', 'value' => 1],
                ], 'firstRow' => true
            ];
            $propertyWebData = $this->propertyWebRepository->findByCriteria($propertyRequest, ['id', 'domain']);

            if ($propertyWebData) {
                $checkDomainStatusCacheKey = 'myweb:' . 'checkDomainStatus'.md5('checkDomainStatus-' . $propertyWebData['domain']);
                if (!empty(Redis::executeRaw(['KEYS', $checkDomainStatusCacheKey]))) {
                    Redis::executeRaw(['DEL', $checkDomainStatusCacheKey]);
                }
            }
            //Domain Cache Clean

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

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

        return output($response);
    }

    public function updatePropertyWebComponentMapping($id, $param = [])
    {
        $response = ['status' => -1, 'message' => '', 'data' => null];
        try {

            $updateData = [
                'property_id' => fillOnUndefined($param, 'property_id'),
                'channel_id' => fillOnUndefined($param, 'channel_id'),
                'component_id' => fillOnUndefined($param, 'component_id'),
                'parameter' => fillOnUndefined($param, 'parameter'),
                'language' => fillOnUndefined($param, 'language'),
                'updated_by' => fillOnUndefined($param, 'updated_by'),
                'updated_at' => time(),
            ];

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

            //Domain Cache Clean
            $propertyRequest = [
                'criteria' => [
                    ['field' => 'property_id', 'condition' => '=', 'value' => fillOnUndefined($param, 'property_id')],
                    ['field' => 'status', 'condition' => '=', 'value' => 1],
                ], 'firstRow' => true
            ];
            $propertyWebData = $this->propertyWebRepository->findByCriteria($propertyRequest, ['id', 'domain']);

            if ($propertyWebData) {
                $checkDomainStatusCacheKey = 'myweb:' . 'checkDomainStatus'.md5('checkDomainStatus-' . $propertyWebData['domain']);
                if (!empty(Redis::executeRaw(['KEYS', $checkDomainStatusCacheKey]))) {
                    Redis::executeRaw(['DEL', $checkDomainStatusCacheKey]);
                }
            }
            //Domain Cache Clean

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

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

        return output($response);
    }

    public function deletePropertyWebComponentMapping($id)
    {
        $response = ['status' => -1, 'message' => '', 'data' => null];
        try {

            $deleteCriteria = [
                'criteria' => [
                    ['field' => 'id', 'condition' => '=', 'value' => $id]
                ]
            ];

            $deleteResult = $this->propertyWebComponentMappingRepository->delete($deleteCriteria);
            if (empty($deleteResult)) {
                throw new Exception('api-unknown_error');
            }

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

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

        return output($response);
    }


    /*** Property Web Review ***/

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

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

        try {

            $data = $this->propertyWebReviewRepository->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 createPropertyWebReview($param = [])
    {
        $response = ['status' => -1, 'message' => '', 'data' => null];
        try {

            $insertData = [
                'property_id' => fillOnUndefined($param, 'property_id'),
                'channel_id' => fillOnUndefined($param, 'channel_id'),
                'channel' => fillOnUndefined($param, 'channel'),
                'code' => fillOnUndefined($param, 'code'),
                'language_code' => fillOnUndefined($param, 'language_code'),
                'author' => fillOnUndefined($param, 'author'),
                'profile_photo' => fillOnUndefined($param, 'profile_photo'),
                'rating' => fillOnUndefined($param, 'rating'),
                'review' => fillOnUndefined($param, 'review'),
                'time' => fillOnUndefined($param, 'time'),
                'status' => 1,
                'created_by' => fillOnUndefined($param, 'created_by'),
                'updated_by' => fillOnUndefined($param, 'updated_by'),
                'created_at' => time(),
                'updated_at' => time(),
            ];


            $createResult = $this->propertyWebReviewRepository->create($insertData);
            if ($createResult['status'] != 'success') {
                throw new ApiErrorException($createResult['message']);
            }

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

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

        return output($response);
    }

    /*** Property Web Review ***/


}
