package org.cmh.backend.NewsManagement.service;

import jakarta.persistence.EntityManager;
import jakarta.persistence.EntityNotFoundException;
import jakarta.persistence.PersistenceContext;
import jakarta.persistence.criteria.CriteriaBuilder;
import jakarta.persistence.criteria.CriteriaQuery;
import jakarta.persistence.criteria.Predicate;
import jakarta.persistence.criteria.Root;
import org.cmh.backend.NewsManagement.dto.NewsRequest;
import org.cmh.backend.NewsManagement.dto.SearchNewsRequest;
import org.cmh.backend.NewsManagement.model.News;
import org.cmh.backend.NewsManagement.repository.NewsRepository;
import org.cmh.backend.Utils.JwtUtil;
import org.cmh.backend.authentication.model.UserHS;
import org.cmh.backend.authentication.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Service
public class NewsService {
    @Autowired
    private NewsRepository newsRepository;

    @Autowired
    private UserService userService;

    @PersistenceContext
    private EntityManager entityManager;

    public List<News> getNewsByRange(int start, int end, UserHS user) {
        if (start < 0 || end <= start) {
            throw new IllegalArgumentException("Invalid start or end range");
        }

        int pageSize = end - start; // 计算每页的大小
        int startPageNumber = start / pageSize; // 计算起始页码
        int endPageNumber = (end - 1) / pageSize; // 计算结束页码

        List<News> result = new ArrayList<>();

        for (int pageNumber = startPageNumber; pageNumber <= endPageNumber; pageNumber++) {
            Pageable pageable = PageRequest.of(pageNumber, pageSize);
            Page<News> newsPage = null;
            if (user.getSuperAdmin()) {
                newsPage = newsRepository.findAllByOrderByIdDesc(pageable);
            } else {
                newsPage = newsRepository.findByTenantOrderByIdDesc(user.getTenant(), pageable);
            }

            if (newsPage.hasContent()) {
                result.addAll(newsPage.getContent());
            } else {
                break; // 如果没有更多内容，提前退出
            }
        }

        int startIndex = start % pageSize;
        int endIndex = startIndex + (end - start);

        if (endIndex > result.size()) {
            endIndex = result.size();
        }

        return result.subList(startIndex, endIndex);
    }


    public void createNews(NewsRequest request) {
        String username = JwtUtil.extractUsername(request.getToken());
        UserHS user = userService.getUserByUsername(username);
        if (!user.getSuperAdmin() && !user.getTenant().equals(request.getTenant())){
            throw new IllegalArgumentException("只能在自己的租户的名下新增新闻！");
        }
        News news = new News();
        news.setTitle(request.getTitle());
        news.setSummary(request.getSummary());
        news.setContent(request.getContent());
        news.setAuthor(request.getAuthor());
        news.setImagePath(request.getImagePath());
        news.setTenant(request.getTenant());
        newsRepository.save(news);
    }

    public void updateNews(Long id, NewsRequest request) {
        News news = newsRepository.findById(id).orElse(null);
        if (news != null) {
            news.setTitle(request.getTitle());
            news.setSummary(request.getSummary());
            news.setContent(request.getContent());
            news.setAuthor(request.getAuthor());
            news.setImagePath(request.getImagePath());
            if (userService.getUserByUsername(JwtUtil.extractUsername(request.getToken())).getSuperAdmin()) {
                news.setTenant(request.getTenant());
            }
            newsRepository.save(news);
        }
    }

    public void deleteNews(Long id) {
        if (!newsRepository.existsById(id)) {
            throw new EntityNotFoundException();
        }
        newsRepository.deleteById(id);
    }

    public News getNewsById(Long id) {
        if (!newsRepository.existsById(id)) {
            throw new EntityNotFoundException();
        }
        return newsRepository.findById(id).orElse(null);
    }

    public long getNewsCount() {
        return newsRepository.count();
    }

    public List<News> searchNews(SearchNewsRequest request) {
        String username = JwtUtil.extractUsername(request.getToken());
        UserHS user = userService.getUserByUsername(username);

        // Create a list to hold predicates
        List<Predicate> predicates = new ArrayList<>();
        // Create the query
        CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
        CriteriaQuery<News> criteriaQuery = criteriaBuilder.createQuery(News.class);
        Root<News> root = criteriaQuery.from(News.class);

        // Build the query conditionally based on non-empty fields
        if (!request.getTitle().isEmpty()) {
            predicates.add(criteriaBuilder.like(root.get("title"), "%" + request.getTitle() + "%"));
        }
        if (!request.getSummary().isEmpty()) {
            predicates.add(criteriaBuilder.like(root.get("summary"), "%" + request.getSummary() + "%"));
        }
        if (!request.getAuthor().isEmpty()) {
            predicates.add(criteriaBuilder.like(root.get("author"), "%" + request.getAuthor() + "%"));
        }
        if (!request.getImagePath().isEmpty()) {
            predicates.add(criteriaBuilder.like(root.get("imagePath"), "%" + request.getImagePath() + "%"));
        }

        if (user.getSuperAdmin()) {
            // Combine predicates with OR
            criteriaQuery.where(criteriaBuilder.or(predicates.toArray(new Predicate[0])));
        } else {
            // Combine predicates with OR and add tenant condition
            Predicate tenantPredicate = criteriaBuilder.equal(root.get("tenant"), user.getUsername());
            predicates.add(tenantPredicate);
            criteriaQuery.where(criteriaBuilder.and(predicates.toArray(new Predicate[0])));
        }

        // Execute the query
        return entityManager.createQuery(criteriaQuery).getResultList();
    }
}
