<?php

namespace App\Console\Commands\ChannelManager;

use App\Core\Mail\LogMail;
use App\Core\Service\ChannelManager\Reseliva;
use App\Core\Service\ChannelManagerService;
use App\Core\Service\PropertyRoomAvailabilityQueueService;
use App\Core\Service\PropertyRoomRatePriceService;
use App\Core\Service\PropertyRoomService;
use App\Exceptions\ApiErrorException;
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\DB;
use Illuminate\Support\Facades\Log;

class PropertyChannelSyncService extends Command
{
    protected $signature = 'cron:propertychannel-sync-service';

    protected $description = '';
    protected $mailer;

    public function __construct(
        Mailer $mailer,
        PropertyRoomService $propertyRoomService,
        PropertyRoomRatePriceService $propertyRoomRatePriceService
    )
    {
        parent::__construct();
        $this->mailer = $mailer;
        $this->propertyRoomService = $propertyRoomService;
        $this->propertyRoomRatePriceService = $propertyRoomRatePriceService;
    }

    public function handle()
    {

        $sourceChannelId = 1; //Booking Engine
        $targetChannelId = 5; //Channel Manager

        $propertyIdList = [1098];

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


        foreach ($propertyIdList as $propertyId) {


            $this->info(date('Y-m-d H:i:s') . ' - AVAILABILITY START : Property: ' . $propertyId . ' : SourceChannelId: ' . $sourceChannelId . ' : TargetChannelId: ' . $targetChannelId);

            $isPropertyRoomAvailabilityUpdate = false;

            DB::beginTransaction();

            try {

                $propertyRoomAvailabilityUpdateQuery = <<<BUR
                UPDATE property_room_availability SET status = 1 WHERE property_id  = {$propertyId} AND date >= curdate() AND channel_id IS NULL AND status = 1;
BUR;

                $propertyRoomAvailabilityUpdate = DB::select(DB::raw($propertyRoomAvailabilityUpdateQuery));

                $isPropertyRoomAvailabilityUpdate = true;

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


            if ($isPropertyRoomAvailabilityUpdate) {
                DB::commit();
                $this->info(date('Y-m-d H:i:s') . ' - AVAILABILITY SUCCESS : Property: ' . $propertyId . ' : SourceChannelId: ' . $sourceChannelId . ' : TargetChannelId: ' . $targetChannelId);
            } else {
                DB::rollBack();
                $this->info(date('Y-m-d H:i:s') . ' - AVAILABILITY ERROR : Property: ' . $propertyId . ' : SourceChannelId: ' . $sourceChannelId . ' : TargetChannelId: ' . $targetChannelId);
            }

            $this->info(date('Y-m-d H:i:s') . ' - AVAILABILITY FINISHED : Property: ' . $propertyId . ' : SourceChannelId: ' . $sourceChannelId . ' : TargetChannelId: ' . $targetChannelId);


            $this->info(date('Y-m-d H:i:s') . ' - RATE START : Property: ' . $propertyId . ' : SourceChannelId: ' . $sourceChannelId . ' : TargetChannelId: ' . $targetChannelId);

            $requestParams = [
                'property_id' => $propertyId,
                'channel_id' => $sourceChannelId,
                'start_date' => Carbon::now()->toDateString(),
                'end_date' => Carbon::now()->addMonths(6)->subDay()->toDateString(),
                //'start_date' => '2023-03-01',
                //'end_date' => '2024-01-01',
            ];

            $propertyRoomType = $this->propertyRoomService->getPropertyRoomInventory($requestParams);

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

            $propertyRoomType = $propertyRoomType['data'];
            $propertyRoomRateAvailability = collect($propertyRoomType);

            $roomRates = [];
            foreach ($propertyRoomRateAvailability as $room) {

                foreach ($room['property_room_rate_mapping'] as $roomRateMapping) {


                    foreach ($room['room_availability'] as $date => $roomAvailability) {
                        $roomRates[$room['id']]['availability'][$date] = $roomAvailability['value'];
                    }

                    $roomRates[$room['id']]['rate'][$roomRateMapping['id']] = [
                        'roomName' => $room['name'],
                        'roomRateName' => $roomRateMapping['name'],
                        'currencyCode' => $roomRateMapping['currency_code'],
                    ];


                    $roomRatePrices = reset($roomRateMapping['prices']);
                    foreach ($roomRatePrices['price'] as $date => $roomRatePrice) {
                        $roomRates[$room['id']]['rate'][$roomRateMapping['id']]['price'][$date] = $roomRatePrice['value'];
                        $roomRates[$room['id']]['rate'][$roomRateMapping['id']]['stopSell'][$date] = $roomRatePrice['stop_sell'];
                    }

                    foreach ($roomRatePrices['stop_sell'] as $date => $stopSell) {
                        $roomRates[$room['id']]['rate'][$roomRateMapping['id']]['stopSell'][$date] = $stopSell['value'];
                    }

                    foreach ($roomRatePrices['min_stay'] as $date => $minStay) {
                        $roomRates[$room['id']]['rate'][$roomRateMapping['id']]['minStay'][$date] = $minStay['value'];
                    }

                }
            }


            $roomRateFormatted = [];
            foreach ($roomRates as $roomId => $roomRateMapping) {
                foreach ($roomRateMapping['rate'] as $roomRateMappingId => $roomRate) {

                    foreach ($roomRate['price'] as $date => $price) {

                        $roomRateKey = '1|' . $roomId . '|' . $roomRateMappingId . '|' . $date;

                        $roomRateFormatted[$roomRateKey] = [
                            'setup_type_id' => '1',
                            'room_id' => $roomId,
                            'room_rate_mapping_id' => $roomRateMappingId,
                            'date' => $date,
                            'amount' => is_null($price) ? 0 : $price,
                            'min_stay' => $roomRate['minStay'][$date],
                            'stop_sell' => $roomRate['stopSell'][$date],
                        ];

                    }

                }

            }

            $isPropertyRoomRateUpdate = false;

            DB::beginTransaction();

            try {

                $roomRateFormattedChunked = array_chunk($roomRateFormatted, 1000);

                foreach ($roomRateFormattedChunked as $roomRateFormattedParsed) {

                    $requestParams = [
                        'property_id' => $propertyId,
                        'channel_id' => $targetChannelId,
                        'rates' => $roomRateFormattedParsed
                    ];

                    $roomRateUpdate = $this->propertyRoomRatePriceService->roomRateUpdate($requestParams);

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

                }

                $isPropertyRoomRateUpdate = true;

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


            if ($isPropertyRoomRateUpdate) {
                DB::commit();
                $this->info(date('Y-m-d H:i:s') . ' - RATE SUCCESS : Property: ' . $propertyId . ' : SourceChannelId: ' . $sourceChannelId . ' : TargetChannelId: ' . $targetChannelId);
            } else {
                DB::rollBack();
                $this->info(date('Y-m-d H:i:s') . ' - RATE ERROR : Property: ' . $propertyId . ' : SourceChannelId: ' . $sourceChannelId . ' : TargetChannelId: ' . $targetChannelId);
            }

            $this->info(date('Y-m-d H:i:s') . ' - RATE FINISHED : Property: ' . $propertyId . ' : SourceChannelId: ' . $sourceChannelId . ' : TargetChannelId: ' . $targetChannelId);


        }


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


    }
}
