<?php

namespace App\Core\Service;

use App\Core\Repository\Booking\BookingRepository;
use App\Core\Repository\Booking\BookingRoomRepository;
use App\Core\Repository\PropertyChannelMapping\PropertyChannelMappingRepository;
use App\Core\Repository\PropertyPromotion\PropertyPromotionRepository;


use App;
use Carbon\Carbon;
use Carbon\CarbonPeriod;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Config;
use Exception;
use App\Exceptions\ApiErrorException;

class PropertyNetworkService
{

    private $bookingRepository;
    private $propertyChannelMappingRepository;
    private $propertyPromotionRepository;


    public function __construct(

        BookingRepository $bookingRepository,
        BookingRoomRepository $bookingRoomRepository,
        PropertyChannelMappingRepository $propertyChannelMappingRepository,
        PropertyPromotionRepository $propertyPromotionRepository
    )
    {
        $this->bookingRepository = $bookingRepository;
        $this->bookingRoomRepository = $bookingRoomRepository;
        $this->propertyChannelMappingRepository = $propertyChannelMappingRepository;
        $this->propertyPromotionRepository = $propertyPromotionRepository;
    }

    public function select($param = [], $column = ['*'])
    {

        $response = ['status' => -1, 'message' => '', 'data' => null];

        try {

            $data = $this->propertyRoomBedRepository->findByCriteria($param, $column);

            $response = [
                'status' => true,
                'data' => $data,
            ];

        } catch (ApiErrorException $e) {
            $response['message'] = $e->getMessage();
        } catch (Exception $e) {
            $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage();
            Log::error($message);
            $response['message'] = $e->getMessage();
        }

        return output($response);
    }

    public function getAllDashboardData($params = [])
    {
        $response = ['status' => -1, 'message' => '', 'data' => null];
        try {

            if (fillOnUndefined($params, 'property_id', null) == null) {
                throw new ApiErrorException(lang('property_id is required'));
            }

            $criteria = [
                'criteria' => [
                    ['field' => 'status', 'condition' => '=', 'value' => 1],
                    ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']],
                    ['field' => 'checkin_date', 'condition' => '>', 'value' => Carbon::now()->subWeek(2)->toDate()],
                    ['field' => 'checkout_date', 'condition' => '<', 'value' => Carbon::now()->addWeek(2)->toDate()]
                ],
                'with' => ['bookingRoom'],
                'orderBy' => [["field" => "checkin_date", "value" => "ASC"]],
            ];

            $data = $this->bookingRepository->findByCriteria($criteria);
            $data = $data ? $data : [];


            $dailyRoomCounts = [];
            foreach ($data as $perData) {

                $dates = [];
                $perDataDatePeriod = CarbonPeriod::create($perData['checkin_date'], Carbon::parse($perData['checkout_date'])->subDay()->toDateString());
                $dates = $perDataDatePeriod->toArray();

                foreach ($dates as $date) {

                    if (!isset($dailyRoomCounts[$date->toDateString()])) {
                        $dailyRoomCounts[$date->toDateString()] = 0;
                    }

                    $dailyRoomCounts[$date->toDateString()] += count($perData['booking_room']);

                }
            }

            $dayLanguages = [
                "Monday" => 'day-short-monday',
                "Tuesday" => 'day-short-tuesday',
                "Wednesday" => 'day-short-wednesday',
                "Thursday" => 'day-short-thursday',
                "Friday" => 'day-short-friday',
                "Saturday" => 'day-short-saturday',
                "Sunday" => 'day-short-sunday'
            ];

            $bookingWeeklyCount = [];
            for ($i = 0; $i < 7; $i++) {

                $iterDay = Carbon::now()->addDay($i)->format('l');
                $iterDate = Carbon::now()->addDay($i)->format('Y-m-d');


                if (isset($dailyRoomCounts[$iterDate])) {

                    $bookingWeeklyCount[$iterDay] = [
                        'date' => $iterDate,
                        'day' => $iterDay,
                        'abbreviation_day' => $dayLanguages[$iterDay],
                        'count' => $dailyRoomCounts[$iterDate],
                    ];
                } else {

                    $bookingWeeklyCount[$iterDay] = [
                        'date' => $iterDate,
                        'day' => $iterDay,
                        'abbreviation_day' => $dayLanguages[$iterDay],
                        'count' => 0
                    ];

                }
            }


            $propertyChannelMappingCriteria = [
                'criteria' => [
                    ['field' => 'status', 'condition' => '=', 'value' => 1],
                    ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']]
                ],
                'count' => true
            ];

            $propertyChannelMappingCount = $this->propertyChannelMappingRepository->findByCriteria($propertyChannelMappingCriteria);

            $propertyPromotionCriteria = [
                'criteria' => [
                    ['field' => 'status', 'condition' => '=', 'value' => 1],
                    ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']]
                ],
                'count' => true
            ];
            $propertyPromotionCount = $this->propertyPromotionRepository->findByCriteria($propertyPromotionCriteria);

            $exportData = [
                'reservation_count' => $bookingWeeklyCount,
                'channel_count' => $propertyChannelMappingCount,
                'promotion_count' => $propertyPromotionCount
            ];


            $response = [
                'status' => true,
                'data' => $exportData,
            ];

        } catch (ApiErrorException $e) {
            $response['message'] = $e->getMessage();
        } catch (Exception $e) {
            $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage();
            Log::error($message);
            $response['message'] = $e->getMessage();
        }

        return output($response);
    }


}
