<?php


namespace App\Http\Controllers\V1;


use App\Core\Mail\BookingTicketMail;
use App\Core\Service\BookingService;
use App\Core\Service\BookingTicketService;
use App\Core\Service\NotificationService;
use App\Core\Validator\PropertyBookingTicket\PropertyTicketCreateValidator;
use App\Core\Validator\PropertyBookingTicket\PropertyTicketGetValidator;
use App\Exceptions\ApiErrorException;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Mail\Mailer;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Validator;

class PropertyBookingTicketController extends Controller
{

    private $currencyService;


    public function __construct(
        Request $request,
        BookingService $bookingService,
        BookingTicketService $bookingTicketService,
        PropertyTicketGetValidator $propertyTicketGetValidator,
        PropertyTicketCreateValidator $propertyTicketCreateValidator,
        Mailer $mailer,
        NotificationService $notificationService
    )
    {
        $this->bookingService = $bookingService;
        $this->bookingTicketService = $bookingTicketService;
        $this->propertyTicketGetValidator = $propertyTicketGetValidator;
        $this->propertyTicketCreateValidator = $propertyTicketCreateValidator;
        $this->mailer = $mailer;
        $this->notificationService = $notificationService;
        $this->params = json_decode($request->getContent(), 1);
        $this->params = $this->params['params'];
    }

    public function createTicket(Request $request)
    {

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

            DB::beginTransaction();

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

            $params['ip_address'] = fillOnUndefined($params,'ip_address') ? $params['ip_address'] : $request->ip();

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

            $bookingRequest = [
                'criteria' => [
                    ['field' => 'booking_code', 'condition' => '=', 'value' => $params['booking_code']],
                ],
                'firstRow' => true
            ];

            $booking = $this->bookingService->select($bookingRequest);

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

            if (empty($booking['data'])) {
                throw new ApiErrorException('Booking not found.');
            }

            $booking = $booking['data'];

            $bookingTicketRequest = [
                'criteria' => [
                    ['field' => 'booking_id', 'condition' => '=', 'value' => $booking['id']],
                ],
                'firstRow' => true
            ];

            $bookingTicket = $this->bookingTicketService->select($bookingTicketRequest, ['id']);
            if ($bookingTicket['status'] != 'success') {
                throw new ApiErrorException($bookingTicket['message']);
            }

            $createParams = [];
            if (empty($bookingTicket['data'])) {

                $createParams = [
                    'booking_id' => $booking['id'],
                    'code' => getTicketCodeGenerate('TCK'),
                    'user_id' => $params['user_id'],
                    'message' => $params['message'],
                    'is_note' => fillOnUndefined($params, 'is_note') == false ? null : $params['is_note'],
                    'is_log' => fillOnUndefined($params, 'is_log'),
                    'ip_address' => fillOnUndefined($params,'ip_address'),
                    'status' => 1
                ];

            } else {

                $createParams = [
                    'parent_id' => $bookingTicket['data']['id'],
                    'booking_id' => $booking['id'],
                    'user_id' => $params['user_id'],
                    'message' => $params['message'],
                    'is_note' => fillOnUndefined($params, 'is_note') == false ? null : $params['is_note'],
                    'is_log' => fillOnUndefined($params, 'is_log'),
                    'ip_address' => fillOnUndefined($params,'ip_address'),
                    'status' => 1
                ];

            }

            $bookingTicketCreate = $this->bookingTicketService->create($createParams);

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

            //BookingTicketMail
            if(is_null($createParams['is_note'])) {
                $mailParams = [
                    'user' => $params['user_id'],
                    'booking_id' => $booking['id'],
                    //'locale' => 'en'
                ];

                $this->mailer->onQueue('bookingTicketMail', new BookingTicketMail($mailParams));
            }
            //BookingTicketMail

            //PUSH NOTIFICATION
            if(empty($params['user_id'])) {
                $notificationParam = ['booking_id' => $booking['id']];
                $this->notificationService->sendTicketNotification($notificationParam);
            }
            //PUSH NOTIFICATION

            if(empty($params['user_id'])) {
                $this->bookingService->update($booking['id'], ['is_viewed' => null]);
            }

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


    }

    public function getTicketList()
    {

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

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

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

            $bookingRequest = [
                'criteria' => [
                    ['field' => 'booking_code', 'condition' => '=', 'value' => $params['booking_code']],
                ],
                'with' => ['bookingContact'],
                'firstRow' => true
            ];

            $booking = $this->bookingService->select($bookingRequest);
            if ($booking['status'] != 'success') {
                throw new ApiErrorException($booking['message']);
            }

            $booking = $booking['data'];

            $bookingTicketRequest = [
                'criteria' => [
                    ['field' => 'booking_id', 'condition' => '=', 'value' => $booking['id']],
                    ['field' => 'is_log', 'condition' => '=', 'value' => null],
                    ['field' => 'status', 'condition' => '=', 'value' => 1],

                ],
                'with' => ['user'],
                'orderBy' => [
                    ['field' => 'created_at', 'value' => 'ASC']
                ]
            ];


            if (!isset($params['user_id']) || is_null($params['user_id'])) {
                $bookingTicketRequest['criteria'][] = ['field' => 'is_note', 'condition' => '=', 'value' => null];
            }

            $column = ['id', 'user_id', 'message', 'is_note', 'is_viewed', 'created_at'];
            $bookingTicket = $this->bookingTicketService->select($bookingTicketRequest, $column);
            if ($bookingTicket['status'] != 'success') {
                throw new ApiErrorException($bookingTicket['message']);
            }


            foreach ($bookingTicket['data'] as $key => $row) {

                if(is_null($row['user_id'])) {
                    $bookingTicket['data'][$key]['nameSurname'] =  $booking['booking_contact']['nameSurname'];
                } else {
                    $bookingTicket['data'][$key]['nameSurname'] =  $row['user']['nameSurname'];
                }

                unset($bookingTicket['data'][$key]['user']);
            }


            $updateCriteria = [
                'criteria' => [
                    ['field' => 'booking_id', 'condition' => '=', 'value' => $booking['id']],
                    ['field' => 'is_log', 'condition' => '=', 'value' => null],
                    ['field' => 'status', 'condition' => '=', 'value' => 1],
                ]
            ];


            if (!isset($params['user_id']) || is_null($params['user_id'])) {
                $updateCriteria['criteria'][] = ['field' => 'user_id', 'condition' => '!=', 'value' => null];
                $updateCriteria['criteria'][] = ['field' => 'is_viewed', 'condition' => '=', 'value' => null];
            } else {
                $updateCriteria['criteria'][] = ['field' => 'user_id', 'condition' => '=', 'value' => null];
                $updateCriteria['criteria'][] = ['field' => 'is_viewed', 'condition' => '=', 'value' => null];
            }


            $updateParam = [
                'is_viewed' => 1
            ];

            $this->bookingTicketService->updateWhere($updateCriteria, $updateParam);


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


    }


}

