package com.izouma.nineth.web;

import cn.hutool.core.collection.CollUtil;
import com.izouma.nineth.domain.Collection;
import com.izouma.nineth.domain.NewsLike;
import com.izouma.nineth.domain.ShowCollection;
import com.izouma.nineth.domain.Showroom;
import com.izouma.nineth.domain.User;
import com.izouma.nineth.dto.PageQuery;
import com.izouma.nineth.enums.AuthStatus;
import com.izouma.nineth.exception.BusinessException;
import com.izouma.nineth.repo.CollectionRepo;
import com.izouma.nineth.repo.NewsLikeRepo;
import com.izouma.nineth.repo.ShowCollectionRepo;
import com.izouma.nineth.repo.ShowroomRepo;
import com.izouma.nineth.service.ShowroomService;
import com.izouma.nineth.utils.SecurityUtils;
import com.izouma.nineth.utils.excel.ExcelUtils;
import lombok.AllArgsConstructor;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.data.domain.Page;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/showroom")
@AllArgsConstructor
public class ShowroomController extends BaseController {
    private ShowroomService    showroomService;
    private ShowroomRepo       showroomRepo;
    private ShowCollectionRepo showCollectionRepo;
    private NewsLikeRepo       newsLikeRepo;
    private CollectionRepo     collectionRepo;

    @PostMapping("/save")
    public Showroom save(@RequestBody Showroom record) {
        return showroomService.save(SecurityUtils.getAuthenticatedUser().getId(), record);
    }

    @PostMapping("/update")
    public Showroom update(@RequestBody Showroom record) {
        return showroomService.update(SecurityUtils.getAuthenticatedUser().getId(), record);
    }

    @PostMapping("/create")
    public Showroom create(@RequestParam Long userId) {
        return showroomService.save(userId);
    }

    @PostMapping("/all")
    public Page<Showroom> all(@RequestBody PageQuery pageQuery) {
        Page<Showroom> all = showroomService.all(pageQuery);
        List<Long> ids = all.map(Showroom::getId).getContent();
        Map<Long, List<ShowCollection>> collect = showCollectionRepo.findAllByShowroomIdIn(ids)
                .stream()
                .collect(Collectors.groupingBy(ShowCollection::getShowroomId));
        showroomService.all(pageQuery);

        User user = SecurityUtils.getAuthenticatedUser();
        Map<Long, Long> likesMap = new HashMap<>();
        if (user != null && !user.isAdmin() && CollUtil.isNotEmpty(ids)) {
            List<NewsLike> likes = newsLikeRepo.findByUserIdAndShowroomIdIn(user
                    .getId(), ids);
            likesMap = likes.stream()
                    .collect(Collectors.groupingBy(NewsLike::getShowroomId, Collectors.counting()));

        }

        Map<Long, Long> finalLikesMap = likesMap;
        return all.map(showroom -> {
            List<ShowCollection> collections = collect.get(showroom.getId());
            List<ShowCollection> neo = new ArrayList<>();
            if (collections != null) {
                collections.forEach(orig -> {
                    Collection collection = collectionRepo.findById(orig.getCollectionId())
                            .orElseThrow(new BusinessException("暂无"));
                    orig.setStatus(showroomService.getStatus(collection));
                    orig.setPrice(collection.getPrice());
                    neo.add(orig);
                });
            }
            if (CollUtil.isNotEmpty(neo)) {
                neo.sort(Comparator.comparingInt(ShowCollection::getSort));
                showroom.setCollections(neo);
            }

            showroom.setLiked(ObjectUtils.isNotEmpty(finalLikesMap.get(showroom.getId())));
            return showroom;
        });
    }

    @GetMapping("/get/{id}")
    public Showroom get(@PathVariable Long id) {
        Showroom showroom = showroomRepo.findById(id).orElseThrow(new BusinessException("无记录"));
        List<ShowCollection> origin = showCollectionRepo.findAllByShowroomIdOrderBySort(id);
        List<ShowCollection> neo = new ArrayList<>();
        if (origin != null) {
            origin.forEach(orig -> {
                Collection collection = collectionRepo.findById(orig.getCollectionId())
                        .orElseThrow(new BusinessException("暂无"));
                orig.setStatus(showroomService.getStatus(collection));
                orig.setPrice(collection.getPrice());
                neo.add(orig);
            });
        }
        showroom.setCollections(neo);
        User user = SecurityUtils.getAuthenticatedUser();

        if (user != null && !user.isAdmin()) {
            List<NewsLike> likes = newsLikeRepo.findByUserIdAndShowroomId(user
                    .getId(), id);
            showroom.setLiked(CollUtil.isNotEmpty(likes));
        }
        return showroom;
    }

    @PreAuthorize("hasRole('ADMIN')")
    @PostMapping("/del/{id}")
    public void del(@PathVariable Long id) {
        showCollectionRepo.deleteAllByShowroomId(id);
        showroomRepo.softDelete(id);
    }

    @GetMapping("/excel")
    @ResponseBody
    public void excel(HttpServletResponse response, PageQuery pageQuery) throws IOException {
        List<Showroom> data = all(pageQuery).getContent();
        ExcelUtils.export(response, data);
    }

    @GetMapping("/{id}/share")
    public void addShare(@PathVariable Long id) {
        showroomRepo.addShare(id, 1);
    }

    @PostMapping("/pass")
    public void pass(@RequestParam Long id) {
        showroomService.audit(id, AuthStatus.SUCCESS, null);
    }

    @PostMapping("/deny")
    public void deny(@RequestParam Long id, String reason) {
        showroomService.audit(id, AuthStatus.FAIL, reason);
    }
}

