<?php

namespace App\Console\Commands\Jobs;

use App\Exceptions\ApiErrorException;
use App\Models\ChannelManagerPropertyMapping;
use App\Models\CurrencyRates;
use App\Models\PropertyPriceComparison;
use App\Models\PropertyRoomRatePrice;
use App\Models\vwActiveProperty;
use Carbon\Carbon;
use GuzzleHttp\Client;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Exception;

class PriceComparisonService extends Command
{
    protected $signature = 'cron:price-comparison-service';

    protected $description = '';

    private $bookingService;

    public function __construct()
    {
        parent::__construct();
    }

    public function handle()
    {

        //$today = '2025-06-05';
        $today = Carbon::now()->toDateString();

        $today = Carbon::parse($today)->startOfWeek(Carbon::MONDAY);

        $year = Carbon::parse($today)->format('Y');
        $week = Carbon::parse($today)->isoWeek();

        $daysCount = [1, 15, 45, 90];
        $exchangeCurrency = 'EUR';
        //'BookingEngine'
        $comparisonChannels = ['Agoda.com', 'etstur.com', 'Booking.com'];

        $exchangeRateUSD = CurrencyRates::where('currency_code', 'USD')->where('exc_currency_code', $exchangeCurrency)->orderBy('date', 'DESC')->first()->toArray();
        $exchangeRateUSD = $exchangeRateUSD['rate'];

        $competitorPriceAnalysisController = App::make('App\Http\Controllers\V1\CompetitorPriceAnalysisController');


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

        $queryWeekPrices = [];
        $queryWeekPricesDaily = [];
        $queryKeyHash = md5($year . '-' . $week);


        $propertyList = vwActiveProperty::where('commission', '>', 1)
            //->whereIn('id', [1433,1441,1551,1574])
            ->get()->toArray();

        foreach ($propertyList as $property) {

            try {

                $channelManagerProperty = ChannelManagerPropertyMapping::where('channel_manager_id', 12)
                    ->where('property_id', $property['id'])->first();
                $channelManagerProperty = $channelManagerProperty ? $channelManagerProperty->toArray() : null;
                $channelManagerPropertyId = $channelManagerProperty ? $channelManagerProperty['channel_manager_property_id'] : null;

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

                if (empty($channelManagerPropertyId)) {
                    $this->error(date('Y-m-d H:i:s') . ' ' . $property['name'] . ': channelManagerPropertyId!');
                    continue;
                }


                foreach ($daysCount as $day) {


                    //Booking Engine
                    $queryDate = Carbon::parse($today)->addDays($day)->toDateString();

                    //FIRST Trigger
                    $paramCompetitorPrice = ['date' => $queryDate, 'competitor_property_key' => $channelManagerPropertyId, 'currency' => $exchangeCurrency,];
                    $getPropertyCompetitorPrice = $competitorPriceAnalysisController->getPropertyCompetitorPrice($paramCompetitorPrice);

                    $this->info(date('Y-m-d H:i:s') . ' ' . $property['id'] . ' - ' . $queryDate);

                    sleep(1);


                    $bestPriceOfDay = 0;
                    $queryWeekPrices[$queryKeyHash][$property['id']]['BookingEngine'][$day] = [
                        'channel' => 'BookingEngine',
                        'date' => $queryDate,
                        'amount' => null,
                        'currency' => null
                    ];

                    $propertyPrices = PropertyRoomRatePrice::where('property_id', $property['id'])
                        ->where('channel_id', 5)
                        ->where('stop_sell', 0)
                        ->where('status', 1)
                        ->where('amount', '<>', 0)
                        ->where('amount', '<>', null)
                        ->where('date', $queryDate)
                        ->with('roomRateMapping.propertyRoomRate')
                        ->get();

                    $propertyPrices = $propertyPrices ? $propertyPrices->toArray() : null;

                    if (empty($propertyPrices)) {
                        //continue;
                    }

                    $bestPrice = collect($propertyPrices)
                        ->where('room_rate_mapping.property_room_rate.name', 'Best Available Rate')
                        ->sortBy('amount')->first();



                    if (empty($bestPrice)) {
                        //continue;
                    } else {


                        if ($bestPrice['currency'] != $exchangeCurrency) {
                            $exchangeRate = CurrencyRates::where('currency_code', $bestPrice['currency'])
                                ->where('exc_currency_code', $exchangeCurrency)
                                ->orderBy('date', 'DESC')->first()->toArray();
                            $exchangeRate = $exchangeRate['rate'];

                            $bestPrice['amount'] = $bestPrice['amount'] * $exchangeRate;
                        }

                        $bestPrice['amount'] = moneyDoubleFormatDecimal($bestPrice['amount']);
                        $queryWeekPrices[$queryKeyHash][$property['id']]['BookingEngine'][$day] = [
                            'channel' => 'BookingEngine',
                            'date' => $queryDate,
                            'amount' => $bestPrice['amount'],
                            'currency' => $exchangeCurrency,
                        ];

                        $queryWeekPricesDaily[$queryKeyHash][$property['id']][$day] = $bestPrice['amount'];
                    }
                    //Booking Engine


                    //OTHER Channels

                    $paramCompetitorPrice = ['date' => $queryDate, 'competitor_property_key' => $channelManagerPropertyId, 'currency' => $exchangeCurrency];
                    $getPropertyCompetitorPrice = $competitorPriceAnalysisController->getPropertyCompetitorPrice($paramCompetitorPrice);

                    foreach ($comparisonChannels as $comparisonChannel) {

                        $queryWeekPrices[$queryKeyHash][$property['id']][$comparisonChannel][$day] = [
                            'channel' => $comparisonChannel,
                            'date' => $queryDate,
                            'amount' => null,
                            'currency' => null
                        ];

                        if(!isset($queryWeekPricesDaily[$queryKeyHash][$property['id']][$day])) {
                            $queryWeekPricesDaily[$queryKeyHash][$property['id']][$day] = $queryWeekPrices[$queryKeyHash][$property['id']][$comparisonChannel][$day]['amount'];
                        }

                        if ($getPropertyCompetitorPrice['status'] && !empty($getPropertyCompetitorPrice['data']['all'])) {

                            $getPropertyCompetitorPriceChannel = $getPropertyCompetitorPrice['data']['all'];
                            $getPropertyCompetitorPriceChannelCheck = collect($getPropertyCompetitorPriceChannel)->where('provider', $comparisonChannel)->first();

                            if ($getPropertyCompetitorPriceChannelCheck) {
                                $queryWeekPrices[$queryKeyHash][$property['id']][$comparisonChannel][$day]['amount'] = moneyDoubleFormatDecimal($getPropertyCompetitorPriceChannelCheck['amount'] * $exchangeRateUSD);
                                $queryWeekPrices[$queryKeyHash][$property['id']][$comparisonChannel][$day]['currency'] = 'EUR';

                                //BestPriceCheck


                                if(empty($queryWeekPricesDaily[$queryKeyHash][$property['id']][$day])) {
                                    $queryWeekPricesDaily[$queryKeyHash][$property['id']][$day] = $queryWeekPrices[$queryKeyHash][$property['id']][$comparisonChannel][$day]['amount'];
                                }elseif ($queryWeekPrices[$queryKeyHash][$property['id']][$comparisonChannel][$day]['amount'] < $queryWeekPricesDaily[$queryKeyHash][$property['id']][$day]) {
                                    $queryWeekPricesDaily[$queryKeyHash][$property['id']][$day] = $queryWeekPrices[$queryKeyHash][$property['id']][$comparisonChannel][$day]['amount'];
                                }

                            }

                        }

                    }
                }

                //dd($queryWeekPrices[$queryKeyHash][$property['id']],$queryWeekPricesDaily[$queryKeyHash][$property['id']]);

                foreach ($queryWeekPrices[$queryKeyHash][$property['id']] as $channelKey => $channelDays) {
                    foreach ($channelDays as $channelDayKey => $channelDay) {

                        //dd($channelDay,$queryWeekPricesDaily[$queryKeyHash][$property['id']][$channelDayKey]);


                        if ($queryWeekPricesDaily[$queryKeyHash][$property['id']][$channelDayKey] == $channelDay['amount'] && !is_null($channelDay['amount'])) {
                            $queryWeekPrices[$queryKeyHash][$property['id']][$channelKey][$channelDayKey]['bestPrice'] = true;
                        } else {
                            $queryWeekPrices[$queryKeyHash][$property['id']][$channelKey][$channelDayKey]['bestPrice'] = false;
                        }

                    }
                }

                $this->info(date('Y-m-d H:i:s') . ' ' . $property['id'] . ' - ' . $property['name'] . ' OK!');


                $propertyComparisonPrice = [
                    'property_id' => $property['id'],
                    'week_key' => $queryKeyHash,
                    'year' => $year,
                    'week' => $week,
                    'date' => $today,
                    'data' => json_encode($queryWeekPrices[$queryKeyHash][$property['id']]),
                    'status' => 1,
                    'created_at' => Carbon::now()->unix(),
                    'updated_at' => Carbon::now()->unix(),

                ];

                $propertyPriceComparisonCheck = PropertyPriceComparison::where('week_key', $queryKeyHash)->where('property_id', $property['id'])->first();

                if ($propertyPriceComparisonCheck) {
                    $propertyPriceComparisonCheck = $propertyPriceComparisonCheck->toArray();
                    $propertyPriceComparison = PropertyPriceComparison::where('id', $propertyPriceComparisonCheck['id'])->update($propertyComparisonPrice);
                } else {
                    $propertyPriceComparison = PropertyPriceComparison::insert($propertyComparisonPrice);
                }

                unset($queryWeekPrices[$queryKeyHash]);

            } catch (ApiErrorException|Exception $e) {
                $this->error(date('Y-m-d H:i:s') . ' ERROR: L: ' . $e->getLine() . ' - ' . $e->getMessage());
            }

        }


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


    }
}
