<?php 

namespace App\Service;

use App\Entity\LocationView;
use App\Entity\PriceList;
use App\Entity\Review;
use App\Repository\LocationViewRepository;
use App\Repository\PriceListRepository;
use App\Repository\ReviewRepository;
use App\Bundle\Utils\Logger;

class SpecialistMoreService
{
	public array $prices = [];
	private array $locations = [];
    public int $specialist;
    public ?array $kodopers = null;
    public ?array $reviews = null;
    public bool $onlineMode;

	public function __construct(
        private LocationViewRepository $locationViewRepository,
        private ReviewRepository $reviewRepository,
        private PriceListRepository $priceListRepository,
        bool $onlineMode = false
	) {	
        $this->onlineMode = $onlineMode;
    }

	public function setSpecialist(int $specialistId, ?array $kodopers): static
	{
		$this->specialistId = $specialistId;
        $this->kodopers = $kodopers;

		return $this;
	}

    public function getLocations(): array
    {
        if (empty($this->locations)) {
            $this->locations = $this
                ->locationViewRepository
                ->findBySpecialistId($this->specialistId, $this->onlineMode);
        }

    	return $this->locations;
    }

    public function locationsCount(): int
    {
        return count($this->getLocations());
    }

    public function defaultLocation(): ?array
    {
        $this->getLocations();
        
        usort($this->locations, function($a, $b) {
            return $a['nearestDate'] <=> $b['nearestDate'];
        });
        
        return !empty($this->locations) ? $this->locations[0] : null;
    }

    public function hasPrice(): bool
    {
        return !empty($this->getPrices());
    }

    public function getPrices(): ?array
    {
        if (empty($this->prices)) {
            if ($this->kodopers) {
                // Логируем входные данные
                Logger::send([
                    'method' => 'SpecialistMoreService::getPrices()',
                    'action' => 'Input kodopers',
                    'kodopers' => $this->kodopers
                ], 'dev.log');
                
                // Фильтр по актуальным записям (обновленным за последние 2 дня)
                $filters['actual'] = true;
                $filters['kodoper'] = $this->kodopers;
                $filters['filial'] = [];
                
                // Убеждаемся, что locations загружены перед использованием
                $locations = $this->getLocations();
                
                foreach ($locations as $location) {
                    if (isset($location['filial']) && $location['filial'] !== null) {
                        $filters['filial'][] = $location['filial'];
                    }
                }
                
                // Убираем дубликаты филиалов
                $filters['filial'] = array_values(array_unique($filters['filial']));
                
                // Если филиалы не найдены, не применяем фильтр по филиалам
                // чтобы показать все цены для данного специалиста
                if (empty($filters['filial'])) {
                    unset($filters['filial']);
                }
                
                $queryBuilder = $this->priceListRepository->createFilteredQueryBuilder($filters);
                
                // Логируем SQL запрос и параметры для отладки
                $query = $queryBuilder->getQuery();
                $sql = $query->getSQL();
                $params = [];
                foreach ($query->getParameters() as $param) {
                    $params[$param->getName()] = $param->getValue();
                }
                
                Logger::send([
                    'method' => 'SpecialistMoreService::getPrices()',
                    'action' => 'PriceList SQL params',
                    'params' => $params
                ], 'dev.log');
                
                // Выполняем запрос
                $allPrices = $queryBuilder->getQuery()->getResult();
                
                // Убираем дубликаты по комбинации kodoper + filial + schname
                $uniquePrices = [];
                $seenKeys = [];
                foreach ($allPrices as $price) {
                    $kodoper = $price->getKodoper();
                    $filial = $price->getFilial();
                    $schname = $price->getSchname();
                    // Создаем уникальный ключ
                    $key = md5($kodoper . '|' . $filial . '|' . $schname);
                    
                    if (!isset($seenKeys[$key])) {
                        $seenKeys[$key] = true;
                        $uniquePrices[] = $price;
                    }
                }
                
                $this->prices = $uniquePrices;
                
                // Логируем детальную информацию о найденных записях
                $foundKodopers = [];
                $foundRecords = [];
                foreach ($this->prices as $price) {
                    $kodoper = $price->getKodoper();
                    $foundKodopers[] = $kodoper;
                    $foundRecords[] = [
                        'id' => $price->getId(),
                        'kodoper' => $kodoper,
                        'schname' => $price->getSchname(),
                        'filial' => $price->getFilial(),
                        'price' => $price->getPriceInfo()['price'] ?? null,
                    ];
                }
                
                Logger::send([
                    'method' => 'SpecialistMoreService::getPrices()',
                    'action' => 'PriceList query result',
                    'kodoper' => $filters['kodoper'],
                    'filial' => $filters['filial'] ?? 'not set',
                    'found_records' => count($this->prices),
                    'before_dedup' => count($allPrices),
                    'found_kodopers' => $foundKodopers,
                    'records_details' => $foundRecords
                ], 'dev.log');
            }
        }

        return $this->prices;
    }

    public function minPrice(): ?PriceList
    {
        $minPriceRecord = null;
        $minPrice = PHP_INT_MAX;
        
        foreach ($this->getPrices() as $record) {
            $currentPrice = $record->getPriceInfo()['price'];
            if ($currentPrice < $minPrice) {
                $minPrice = $currentPrice;
                $minPriceRecord = $record;
            }
        }

        return $minPriceRecord;
    }

    public function getReviews(): ?array
    {
        if (empty($this->reviews)) {
            $this->reviews = $this
                ->reviewRepository
                ->findBy(['specialistId' => $this->specialistId]);
        }
        
        return $this->reviews;
    }   

    public function hasReviews(): bool
    {
        return !empty($this->getReviews());
    }
}
