<?php


namespace App\Http\Controllers\V1;

use App\Core\Service\PropertyChannelCouponService;
use App\Core\Service\PropertyChannelMappingService;
use App\Core\Validator\PropertyChannelCoupon\PropertyChannelCouponValidator;
use App\Exceptions\ApiErrorException;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Input;
use Illuminate\Support\Facades\Log;
use Exception;

class PropertyCouponController extends Controller
{

    private $params;
    private $propertyChannelCouponService;
    private $propertyChannelMappingService;
    private $propertyChannelCouponValidator;


    public function __construct(
        PropertyChannelCouponService $propertyChannelCouponService,
        PropertyChannelMappingService $propertyChannelMappingService,
        PropertyChannelCouponValidator $propertyChannelCouponValidator
    )
    {
        $this->params = Input::all();
        $this->params = $this->params['params'];
        $this->propertyChannelCouponService = $propertyChannelCouponService;
        $this->propertyChannelMappingService = $propertyChannelMappingService;
        $this->propertyChannelCouponValidator = $propertyChannelCouponValidator;
    }

    protected function propertyChannelMappingCheck($propertyId, $channelId)
    {

        $propertyChannelMappingCriteria = [
            'criteria' => [
                ['field' => 'property_id', 'condition' => '=', 'value' => $propertyId],
                ['field' => 'channel_id', 'condition' => '=', 'value' => $channelId],
                ['field' => 'status', 'condition' => '=', 'value' => 1],
            ],
            'firstRow' => true
        ];

        $propertyChannelMapping = $this->propertyChannelMappingService->select($propertyChannelMappingCriteria);

        if ($propertyChannelMapping['status'] == 'success') {
            if (empty($propertyChannelMapping['data'])) {
                return false;
            } else {
                return true;
            }
        } else {
            return false;
        }

    }

    public function getPropertyChannelCoupon(Request $request)
    {

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

        try {

            $propertyChannelMappingCheck = $this->propertyChannelMappingCheck($this->params['property_id'], $this->params['channel_id']);
            if (!$propertyChannelMappingCheck) {
                throw new ApiErrorException('Transactions cannot be made through a unconnected channel.');
            }

            $requestSelectCriteria = [
                'criteria' => [
                    ['field' => 'property_id', 'condition' => '=', 'value' => $this->params['property_id']],
                    ['field' => 'channel_id', 'condition' => '=', 'value' => $this->params['channel_id']],
                ],
            ];
            $columns = ['id', 'title', 'property_id', 'channel_id', 'code', 'start_date', 'end_date', 'reservation_start_date', 'reservation_end_date', 'type', 'value', 'is_notify', 'email', 'status'];
            $requestSelectResult = $this->propertyChannelCouponService->select($requestSelectCriteria, $columns);

            $propertyChannelCoupon = [];
            if ($requestSelectResult['status'] == 'success') {
                $propertyChannelCoupon = $requestSelectResult['data'];
            }

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

        } 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 syncPropertyChannelCoupon(Request $request)
    {

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

        try {

            $validationResult = $this->propertyChannelCouponValidator->validate($this->params);

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

            $propertyChannelMappingCheck = $this->propertyChannelMappingCheck($this->params['property_id'], $this->params['channel_id']);
            if (!$propertyChannelMappingCheck) {
                throw new ApiErrorException('Transactions cannot be made through a unconnected channel.');
            }

            $propertyChannelCoupon = [];
            if (isset($this->params['id'])) {
                $requestSelectCriteria = [
                    'criteria' => [
                        ['field' => 'id', 'condition' => '=', 'value' => $this->params['id']],
                        ['field' => 'property_id', 'condition' => '=', 'value' => $this->params['property_id']],
                        ['field' => 'channel_id', 'condition' => '=', 'value' => $this->params['channel_id']],
                    ],
                    'firstRow' => true
                ];
                $columns = ['id', 'property_id', 'channel_id', 'code', 'start_date', 'end_date', 'type', 'value', 'status'];
                $requestSelectResult = $this->propertyChannelCouponService->select($requestSelectCriteria, $columns);


                if ($requestSelectResult['status'] == 'success') {
                    $propertyChannelCoupon = $requestSelectResult['data'];
                }
            }

            DB::beginTransaction();

            if (empty($propertyChannelCoupon)) {

                $createParam = [
                    'title' => fillOnUndefined($this->params, 'title'),
                    'property_id' => $this->params['property_id'],
                    'channel_id' => $this->params['channel_id'],
                    'code' => $this->params['code'],
                    'start_date' => $this->params['start_date'],
                    'end_date' => $this->params['end_date'],
                    'reservation_start_date' => fillOnUndefined($this->params, 'reservation_start_date'),
                    'reservation_end_date' => fillOnUndefined($this->params, 'reservation_end_date'),
                    'type' => $this->params['type'],
                    'value' => $this->params['value'],
                    'is_notify' => fillOnUndefined($this->params, 'is_notify'),
                    'email' => fillOnUndefined($this->params, 'email'),
                    'status' => fillOnUndefined($this->params, 'status', 1),
                    'created_by' => $request->auth->id,
                    'updated_by' => $request->auth->id,
                ];

                $syncPropertyChannelCoupon = $this->propertyChannelCouponService->create($createParam);
            } else {
                $this->params['updated_by'] = $request->auth->id;
                $syncPropertyChannelCoupon = $this->propertyChannelCouponService->update($propertyChannelCoupon['id'], $this->params);

            }

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

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

        if ($response['status']) {
            DB::commit();
        } else {
            DB::rollBack();
        }

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

    }


}

