<?php

namespace App\Core\Service;


use App\Exceptions\ApiErrorException;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Validator;
use App\Core\Repository\PropertyContact\PropertyContactRepository;
use App\Core\Validator\PropertyContact\PropertyContactCreateValidator;
use App\Core\Validator\PropertyContact\PropertyContactUpdateValidator;
use App\Core\Validator\Property\PropertyLocationUpdateValidator;


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

class PropertyContactService
{

    private $propertyContactRepository;
    private $propertyContactCreateValidator;
    private $propertyContactUpdateValidator;
    private $propertyLocationUpdateValidator;


    public function __construct(
        PropertyContactRepository $propertyContactRepository,
        PropertyContactCreateValidator $propertyContactCreateValidator,
        PropertyContactUpdateValidator $propertyContactUpdateValidator,
        PropertyLocationUpdateValidator $propertyLocationUpdateValidator
    )
    {

        $this->propertyContactRepository = $propertyContactRepository;
        $this->propertyContactCreateValidator = $propertyContactCreateValidator;
        $this->propertyContactUpdateValidator = $propertyContactUpdateValidator;
        $this->propertyLocationUpdateValidator = $propertyLocationUpdateValidator;

    }

    /**
     * @param array $param
     *
     * @return array
     */
    public function create($param = [])
    {
        $response = ['status' => -1, 'message' => '', 'data' => null];
        try {
            $propertyContactData =
                [
                    "property_id"    => fillOnUndefined($param, "property_id"),
                    "phone_code"     => fillOnUndefined($param, "phone_code"),
                    "phone"          => fillOnUndefined($param, "phone"),
                    "mobile_code"    => fillOnUndefined($param, "mobile_code"),
                    "mobile"         => fillOnUndefined($param, "mobile"),
                    "mobile2_code"    => fillOnUndefined($param, "mobile_code"),
                    "mobile2"         => fillOnUndefined($param, "mobile2"),
                    "fax_code"       => fillOnUndefined($param, "fax_code"),
                    "fax"            => fillOnUndefined($param, "fax"),
                    "email"          => fillOnUndefined($param, "email"),
                    "web"            => fillOnUndefined($param, "web"),
                    "social_media_addresses"  => fillOnUndefined($param, "social_media_addresses"),
                    "zip_code"       => fillOnUndefined($param, "zip_code"),
                    "address"        => fillOnUndefined($param, "address"),
                    "latitude"       => fillOnUndefined($param, "latitude"),
                    "longitude"      => fillOnUndefined($param, "longitude"),
                    "status"         => fillOnUndefined($param, "status", 0),
                    "created_by"     => fillOnUndefined($param, "created_by"),
                    "updated_by"     => fillOnUndefined($param, "updated_by"),
                    "created_at"     => time(),
                    "updated_at"     => time(),
                ];

            // todo: destination service will added for destination_id check
            $validationResult = $this->propertyContactCreateValidator->validate($propertyContactData);

            //todo: validation section will be updated
            Validator::make($propertyContactData,
                ['property_id' => 'required|integer|unique:property_contact,property_id'],
                ['property_id.property_contact' => '"property_id format must be unique"']);

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

            $propertyContactCreateResult = $this->propertyContactRepository->create($propertyContactData);

            if ($propertyContactCreateResult['status'] != 'success') {
                throw new Exception('api-unknown_error');
            }

            $contactData = $propertyContactCreateResult["data"];

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

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

    /**
     * @param array $param
     * @param array $column
     *
     * @return array
     */
    public function select($param = [], $column = ['*'])
    {

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

        try {

            $data = $this->propertyContentRepository->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 {


            if(!isset($param['address'])){

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

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

            if(isset($param['address']) || isset($param['latitude']) || isset($param['longitude'])){
                $validationResult = $this->propertyLocationUpdateValidator->validate($param);
                if ($validationResult->errors()->first()) {
                    $errors = $validationResult->errors()->all();
                    throw new ApiErrorException($errors);
                }
            }

            $updateResult = $this->propertyContactRepository->update($id,$param);

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


    /**
     * property contact data list
     *
     * @param $params
     *
     * @return array
     */
    public function propertyContact($params)
    {
        $response = ['status' => -1, 'message' => '', 'data' => null];

        try {

            $contactRequest = [
                'criteria' => [
                    ['field' => 'status', 'condition' => '=', 'value' => 1],
                    ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']],
                ]
            ];
            $contactData = $this->propertyContactRepository->findByCriteria($contactRequest);

            $contactData = $contactData ? $contactData : [] ;

            $data = [];
            foreach ($contactData as $contact) {
                $data = Arr::except($contact,['id','status','created_by','updated_by','created_at','updated_at']);
                $data["social_media_addresses"] = json_decode($data["social_media_addresses"], 1) ;
            }

            if(!isset($data["social_media_addresses"])){
                $data["social_media_addresses"] = ['facebook'=>'', 'twitter'=>'',  'instagram'=>''] ;
            }

            $response = [
                'status' => 1,
                'message' => '',
                'data' => ['property_contact' => $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 output($response);
    }


    /**
     * contact update or create
     *
     * @param $params
     *
     * @return array
     */
    public function propertyContactUpdateOrCreate($params)
    {
        $response = ['status' => false, 'message' => '', 'data' => null, 'statusCode' => 500];
        try {
            $contactCriteria = [
                'criteria' => [
                    ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']],
                ]
            ];
            $contactData = $this->propertyContactRepository->findByCriteria($contactCriteria);
            if (!$contactData) {
                $addData = [
                    'property_id'    => $params['property_id'],
                    'status' => 1,
                    'created_by' => $params[ 'user_id' ],
                    'updated_by' => $params[ 'user_id' ],
                ];
                $saveData   = array_merge($addData,$params['contact']);

                if(isset($saveData['social_media_addresses'])){
                    $saveData['social_media_addresses'] = json_encode($this->clearSocialMediaAddresses($saveData['social_media_addresses']));
                }

                $createResult = $this->create($saveData);
                if($createResult['status'] != 'success'){
                    throw new ApiErrorException(lang('Not saved'));
                }
                $data = Arr::except($createResult['data'],['id','status','created_by','updated_by','created_at','updated_at']);
                $data["social_media_addresses"] = json_decode($data["social_media_addresses"], 1) ;
                $response = [
                    'status' => true,
                    'data' => $data,
                ];
            }else {
                $saveData = $params['contact'];
                if(isset($saveData['social_media_addresses'])){
                    $saveData['social_media_addresses'] = json_encode($this->clearSocialMediaAddresses($saveData['social_media_addresses']));
                }

                $saveData['updated_by'] = $params['user_id'];
                $updateResult = $this->update($contactData[0]['id'], $saveData) ;

                if($updateResult['status'] != 'success'){
                    throw new ApiErrorException(lang('Not updated'));
                }
                $data = Arr::except($updateResult['data'],['id','status','created_by','updated_by','created_at','updated_at']);
                $data["social_media_addresses"] = json_decode($data["social_media_addresses"], 1) ;
                $response = [
                    'status' => true,
                    'data' => ['property_contact' => $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 output($response);
    }

    public function clearSocialMediaAddresses($params){
        $newAddressArray = [];
        foreach ($params as $key => $value) {
            $addressToArray = explode('/', $value) ;
            $address = end($addressToArray);
            if(!$address){
                array_pop($addressToArray);
                $address = end($addressToArray);
            }
            $address = str_replace('@','',$address);
            $newAddressArray[$key] = $address ;
        }
        return $newAddressArray;
    }
}
