package kz.konturai.parser.service;

import kz.konturai.parser.model.MarketItem;
import kz.konturai.parser.repository.MarketItemRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;

@Service
public class MarketItemService {

    private static final Logger logger = LoggerFactory.getLogger(MarketItemService.class);

    @Autowired
    private MarketItemRepository marketItemRepository;

    @Autowired
    private MongoTemplate mongoTemplate;

    /**
     * Получение всех записей с пагинацией и сортировкой
     */
    public Page<MarketItem> getAllItems(Pageable pageable) {
        logger.debug("Получение всех записей с пагинацией: page={}, size={}, sort={}",
                pageable.getPageNumber(), pageable.getPageSize(), pageable.getSort());

        return marketItemRepository.findAll(pageable);
    }

    /**
     * Получение записей с фильтрацией по источнику
     */
    public Page<MarketItem> getItemsBySource(String sourceName, Pageable pageable) {
        logger.debug("Получение записей по источнику: sourceName={}, page={}, size={}",
                sourceName, pageable.getPageNumber(), pageable.getPageSize());

        return marketItemRepository.findBySourceName(sourceName, pageable);
    }

    /**
     * Получение записей с фильтрацией по диапазону дат
     */
    public Page<MarketItem> getItemsByDateRange(LocalDateTime startDate, LocalDateTime endDate, Pageable pageable) {
        logger.debug("Получение записей по диапазону дат: startDate={}, endDate={}, page={}, size={}",
                startDate, endDate, pageable.getPageNumber(), pageable.getPageSize());

        return marketItemRepository.findByPublishedAtBetween(startDate, endDate, pageable);
    }

    /**
     * Получение записей с комплексной фильтрацией
     */
    public Page<MarketItem> getItemsWithFilters(String sourceName, LocalDateTime startDate,
            LocalDateTime endDate, Pageable pageable) {
        logger.debug("Получение записей с фильтрацией: sourceName={}, startDate={}, endDate={}, page={}, size={}",
                sourceName, startDate, endDate, pageable.getPageNumber(), pageable.getPageSize());

        Query query = new Query();

        // Фильтр по источнику
        if (sourceName != null && !sourceName.trim().isEmpty()) {
            query.addCriteria(Criteria.where("sourceName").is(sourceName));
        }

        // Фильтр по диапазону дат
        if (startDate != null && endDate != null) {
            query.addCriteria(Criteria.where("publishedAt").gte(startDate).lte(endDate));
        } else if (startDate != null) {
            query.addCriteria(Criteria.where("publishedAt").gte(startDate));
        } else if (endDate != null) {
            query.addCriteria(Criteria.where("publishedAt").lte(endDate));
        }

        // Подсчет общего количества записей
        long totalCount = mongoTemplate.count(query, MarketItem.class);

        // Применение пагинации и сортировки
        query.with(pageable);

        // Выполнение запроса
        List<MarketItem> items = mongoTemplate.find(query, MarketItem.class);

        // Создание объекта Page
        return new org.springframework.data.domain.PageImpl<>(items, pageable, totalCount);
    }

    /**
     * Получение общего количества записей
     */
    public long getTotalItemsCount() {
        return marketItemRepository.count();
    }

    /**
     * Получение количества записей по источнику
     */
    public long getItemsCountBySource(String sourceName) {
        return marketItemRepository.countBySourceName(sourceName);
    }

    /**
     * Получение всех уникальных источников
     */
    public List<String> getAllSourceNames() {
        List<MarketItem> items = marketItemRepository.findDistinctSourceNames();
        return items.stream()
                .map(MarketItem::getSourceName)
                .distinct()
                .collect(java.util.stream.Collectors.toList());
    }

    /**
     * Получение статистики по источникам
     */
    public java.util.Map<String, Long> getSourceStatistics() {
        List<String> sources = getAllSourceNames();
        java.util.Map<String, Long> statistics = new java.util.HashMap<>();

        for (String source : sources) {
            statistics.put(source, getItemsCountBySource(source));
        }

        return statistics;
    }

    /**
     * Парсинг даты из строки
     */
    public LocalDateTime parseDate(String dateString) {
        if (dateString == null || dateString.trim().isEmpty()) {
            return null;
        }

        try {
            // Поддерживаем несколько форматов даты
            String[] formats = {
                    "yyyy-MM-dd",
                    "yyyy-MM-dd'T'HH:mm:ss",
                    "yyyy-MM-dd'T'HH:mm:ss.SSS",
                    "yyyy-MM-dd HH:mm:ss"
            };

            for (String format : formats) {
                try {
                    DateTimeFormatter formatter = DateTimeFormatter.ofPattern(format);
                    return LocalDateTime.parse(dateString, formatter);
                } catch (Exception e) {
                    // Пробуем следующий формат
                }
            }

            logger.warn("Не удалось распарсить дату: {}", dateString);
            return null;

        } catch (Exception e) {
            logger.error("Ошибка при парсинге даты: {}", dateString, e);
            return null;
        }
    }
}
