<?php

namespace App\Console\Commands\ChannelManager;

use App\Core\Mail\LogMail;
use App\Core\Service\ChannelManager\Reseliva;
use App\Core\Service\ChannelManagerPropertyMappingService;
use App\Core\Service\ChannelManagerService;
use App\Core\Service\PropertyRoomAvailabilityQueueService;
use App\Core\Service\PropertyRoomRatePriceQueueService;
use App\Exceptions\ApiErrorException;
use App\Models\PropertyRoomRatePriceQueue;
use Carbon\Carbon;
use GuzzleHttp\Client;
use Illuminate\Console\Command;
use Illuminate\Mail\Mailer;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Log;

class RoomRatePushService extends Command
{
    protected $signature = 'cron:roomrate-push-service';

    protected $description = '';
    protected $mailer;
    protected $channelService;
    protected $propertyRoomRatePriceQueueService;
    protected $channelManagerService;
    protected $propertyRoomAvailabilityQueueService;

    public function __construct(
        Mailer $mailer,
        PropertyRoomRatePriceQueueService $propertyRoomRatePriceQueueService,
        ChannelManagerService $channelManagerService,
        PropertyRoomAvailabilityQueueService $propertyRoomAvailabilityQueueService,
        ChannelManagerPropertyMappingService $channelManagerPropertyMappingService
    )
    {
        parent::__construct();
        $this->mailer = $mailer;
        $this->propertyRoomRatePriceQueueService = $propertyRoomRatePriceQueueService;
        $this->channelManagerService = $channelManagerService;
        $this->propertyRoomAvailabilityQueueService = $propertyRoomAvailabilityQueueService;
        $this->channelManagerPropertyMappingService = $channelManagerPropertyMappingService;
    }

    public function handle()
    {
        //$request = $this->channelService->productList(14480);

        try {

            $this->info(date('Y-m-d H:i:s') . ' : Start');

            //Queue Check
            $this->info(date('Y-m-d H:i:s') . ' : Queue Check');
            $roomRatePriceQueueCountCriteria = ['criteria' => [['field' => 'status', 'condition' => '=', 'value' => 1]],'count' => true];
            $roomRatePriceQueueCount = $this->propertyRoomRatePriceQueueService->select($roomRatePriceQueueCountCriteria);
            if($roomRatePriceQueueCount['status'] == 'success') {
                $roomRatePriceQueueCount = $roomRatePriceQueueCount['data'];

                if($roomRatePriceQueueCount > 1000) {

                    $this->error(date('Y-m-d H:i:s') . ' : Queue Alarm: '. $roomRatePriceQueueCount);

                    //Clear Test Property Data
                    PropertyRoomRatePriceQueue::where('property_id',1)->delete();

                    //$logMessage
                    $mailParams = [
                        'title' => 'RoomRatePushService Error - Queue Error',
                        'logMessage' => 'Queue: '.$roomRatePriceQueueCount
                    ];

                    $this->mailer->onQueue('logMail', new LogMail($mailParams));
                    //$logMessage
                }
            }
            //Queue Check

            $channelManagerCriteria =
                [
                    'criteria' =>
                        [
                            ['field' => 'status', 'condition' => '=', 'value' => 1],
                        ],
                    /*'whereIn' =>
                        [
                            ['field' => 'id', "value" => [7]]
                        ],*/
                    'orderBy' => [
                        ['field' => 'id', 'value' => 'ASC']
                    ]
                ];

            $channelManager = $this->channelManagerService->select($channelManagerCriteria);

            $channelManagerList = [];
            if ($channelManager['status'] == 'success' && !empty($channelManager['data'])) {
                $channelManagerList = $channelManager['data'];
            }

            $roomRatePriceQueueCriteria =
                [
                    'criteria' =>
                        [
                            ['field' => 'status', 'condition' => '=', 'value' => 1],
                        ],
                    'with' => ['property'/*, 'propertyChannelManager.channelManagerRoomRate'*/],
                    'orderBy' => [
                        ['field' => 'id', 'value' => 'ASC']
                    ],
                    'take' => 500
                ];

            $roomRatePriceQueue = $this->propertyRoomRatePriceQueueService->select($roomRatePriceQueueCriteria);

            if ($roomRatePriceQueue['status'] == 'success' && !empty($roomRatePriceQueue['data'])) {


                foreach ($roomRatePriceQueue['data'] as $data) {
                    $roomRatePriceQueueData[$data['property_id']][] = $data;
                }

                $channelManagerPushedIdsList = [];
                $channelManagerNoneMappingIdsList = [];

                //PROPERTY
                foreach ($roomRatePriceQueueData as $roomRatePriceQueuePropertyId => $roomRatePriceQueueProperty) {


                    //CHANNEL MANAGER
                    $channelManagerCheckList = [];
                    foreach ($channelManagerList as $channelKey => $channel) {

                        if(in_array($channel['id'],[7,10, 13])) {
                            continue;
                        }

                        $this->info(date('Y-m-d H:i:s') . ' : Channel Start: ' . $channel['name']);

                        if(!class_exists("App\Core\Service\ChannelManager\\{$channel['name']}")) {
                            $this->error(date('Y-m-d H:i:s') . ' : Channel: ' . $channel['name'].' Class does not exist!');
                            continue;
                        }

                        $channelService = App::make("App\Core\Service\ChannelManager\\{$channel['name']}");


                        $channelManagerPropertyMappingCriteria = [
                            'criteria' =>
                                [
                                    ['field' => 'status', 'condition' => '=', 'value' => 1],
                                    ['field' => 'property_id', 'condition' => '=', 'value' => $roomRatePriceQueuePropertyId],
                                    ['field' => 'channel_manager_id', 'condition' => '=', 'value' => $channel['id']],
                                    ['field' => 'channel_manager_property_id', 'condition' => '!=', 'value' => null],
                                ],
                            'firstRow' => true,
                        ];

                        $channelManagerPropertyMapping = $this->channelManagerPropertyMappingService->select($channelManagerPropertyMappingCriteria);


                        if ($channelManagerPropertyMapping['status'] != 'success' || ($channelManagerPropertyMapping['status'] == 'success' && empty($channelManagerPropertyMapping['data']))) {
                            $this->info(date('Y-m-d H:i:s') . ' : Channel: ' . $channel['name'] . ' PropertyID: ' . $roomRatePriceQueuePropertyId . ' : PASS');
                            continue;
                        }

                        $channelManagerCheckList[$channel['id']] = true;


                        $roomRatePricePush = $channelService->roomRatePricePush($roomRatePriceQueuePropertyId, $roomRatePriceQueueProperty);


                        if ($roomRatePricePush['status']) {

                            if (!empty($roomRatePricePush['data']['channelManagerPushedIds']) || !empty($roomRatePricePush['data']['channelManagerNoneMappingIds'])) {
                                $channelManagerPushedIdsList[$channel['id']] = $roomRatePricePush['data']['channelManagerPushedIds'];
                                $channelManagerNoneMappingIdsList[$channel['id']] = $roomRatePricePush['data']['channelManagerNoneMappingIds'];
                            }

                            $this->info(date('Y-m-d H:i:s') . ' : Channel Success: ' . $channel['name']);

                        } else {

                            $channelManagerCheckList[$channel['id']] = false;

                            //$logMessage
                            $mailParams = [
                                'title' => $channel['name'] . ' - RoomRatePushService Error - InventoryRoomRateUpdate Error',
                                'logMessage' => '<pre>' . print_r($roomRatePricePush, true) . '</pre>'
                            ];

                            $this->mailer->onQueue('logMail', new LogMail($mailParams));
                            //$logMessage

                            $this->error(date('Y-m-d H:i:s') . ' : Error: ' . $channel['name'] . ' - ' . $roomRatePricePush['message']);


                        }

                        $this->info(date('Y-m-d H:i:s') . ' : Channel Finished: ' . $channel['name']);

                    }

                    /*foreach ($channelManagerPushedIdsList as $key => $channelManagerPushedIds) {
                        if(empty($channelManagerPushedIds)) {
                            unset($channelManagerPushedIdsList[$key]);
                        }
                    }*/

                    if (in_array(false, $channelManagerCheckList)) {
                        $this->error(date('Y-m-d H:i:s') . ' : Error Break: ' . var_export($channelManagerCheckList));
                        continue;
                    }

                    if (count($channelManagerPushedIdsList) > 1) {
                        $channelManagerPushedIdIntersect = call_user_func_array('array_intersect', $channelManagerPushedIdsList);
                        if (!empty($channelManagerPushedIdIntersect)) {
                            $this->propertyRoomRatePriceQueueService->delete($channelManagerPushedIdIntersect);
                            $this->info(date('Y-m-d H:i:s') . ' : $channelManagerPushedIdsList Deleted: ' . var_export($channelManagerPushedIdIntersect));
                        }
                    } elseif (!empty($channelManagerPushedIdsList)) {
                        $this->propertyRoomRatePriceQueueService->delete(reset($channelManagerPushedIdsList));
                        $this->info(date('Y-m-d H:i:s') . ' : $channelManagerPushedIdsList Deleted: ' . var_export($channelManagerPushedIdsList));
                    }

                    if (!empty($channelManagerNoneMappingIdsList)) {
                        $channelManagerNoneMappingIdsListMerge = call_user_func_array('array_merge', $channelManagerNoneMappingIdsList);
                        if (!empty($channelManagerNoneMappingIdsListMerge)) {
                            $this->propertyRoomRatePriceQueueService->delete($channelManagerNoneMappingIdsListMerge);
                            $this->info(date('Y-m-d H:i:s') . ' : $channelManagerNoneMappingIdsListMerge Deleted: ' . var_dump($channelManagerNoneMappingIdsListMerge));
                        }
                    }


                }

            }


            $this->info(date('Y-m-d H:i:s') . ' : Finished');

        } catch (ApiErrorException $e) {
            $this->error(date('Y-m-d H:i:s') . ' : Error: ' . $e->getMessage());
        } catch (Exception $e) {
            $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage();
            Log::error($message);
            $this->error(date('Y-m-d H:i:s') . ' : Error: ' . $message);
        }

    }

}
