package com.ai.da.controller;

import cn.hutool.core.collection.CollectionUtil;
import com.ai.da.common.config.exception.BusinessException;
import com.ai.da.common.context.UserContext;
import com.ai.da.common.response.PageBaseResponse;
import com.ai.da.common.response.Response;
import com.ai.da.common.utils.CopyUtil;
import com.ai.da.common.utils.MinioUtil;
import com.ai.da.mapper.primary.TDesignPythonOutfitMapper;
import com.ai.da.mapper.primary.entity.*;
import com.ai.da.model.dto.*;
import com.ai.da.model.vo.*;
import com.ai.da.service.*;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.base.Function;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.validation.Valid;
import javax.validation.constraints.Pattern;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;


@Api(tags = "History模块(saved Collection)")
@Slf4j
@RestController
@Validated
@RequestMapping("/api/history")
public class SavedCollectionController {
    @Resource
    private UserLikeGroupService userLikeGroupService;
    @Resource
    private UserLikeService userLikeService;
    @Resource
    private AccountService accountService;
    @Resource
    private TDesignPythonOutfitMapper designPythonOutfitMapper;
    @Resource
    private MinioUtil minioUtil;
    @Resource
    private ClassificationService classificationService;
    @Resource
    private PortfolioService portfolioService;

    @ApiOperation(value = "History用户分页分组列表")
    @PostMapping("/queryUserGroup")
    public Response<PageBaseResponse<UserLikeGroupVO>> queryUserGroup(@Valid @RequestBody QueryHistoryPageDTO query) {
        AuthPrincipalVo authPrincipalVo = UserContext.getUserHolder();
        // 分页数据
        QueryWrapper<UserLikeGroup> queryWrapper = new QueryWrapper<>();

        queryWrapper.eq("account_id", authPrincipalVo.getId());
        if (!StringUtils.isEmpty(query.getCollectionName())) {
            queryWrapper.like("name", query.getCollectionName());
        }
        if (Objects.nonNull(query.getStartDate())) {
            queryWrapper.ge("update_date", new Date(query.getStartDate()));
        }
        if (Objects.nonNull(query.getEndDate())) {
            queryWrapper.le("update_date", new Date(query.getEndDate()));
        }
        // 新增分类过滤
        if (CollectionUtil.isNotEmpty(query.getClassificationIdList())) {
            List<Long> historyIdList = new ArrayList<>();
            if (query.getIntersection() == 0) {
                for (Long classificationId : query.getClassificationIdList()) {
                    historyIdList.addAll(classificationService.getLibraryIdListByClassificationId(classificationId));
                }
                if (CollectionUtil.isNotEmpty(historyIdList)) {
                    queryWrapper.in("id", historyIdList);
                }else {
                    return Response.success(PageBaseResponse.success(new Page<>()));
                }
            }else {
                for (int i = 0; i < query.getClassificationIdList().size(); i++) {
                    List<Long> historyIdListByClassificationId = classificationService.getLibraryIdListByClassificationId(query.getClassificationIdList().get(i));
                    if (i == 0) {
                        historyIdList.addAll(historyIdListByClassificationId);
                    }else {
                        historyIdList.retainAll(historyIdListByClassificationId);
                    }
                    if (CollectionUtil.isEmpty(historyIdList)) {
                        return Response.success(PageBaseResponse.success(new Page<>()));
                    }
                }
                queryWrapper.in("id", historyIdList);
            }
        }
        queryWrapper.orderByDesc("update_date");
        IPage<UserLikeGroup> page = userLikeGroupService.getBaseMapper().selectPage(
                new Page<>(query.getPage(), query.getSize()), queryWrapper);
        if (CollectionUtils.isEmpty(page.getRecords())) {
            return Response.success(PageBaseResponse.success(new Page<>()));
        }
        List<Long> groupIds = page.getRecords().stream().map(UserLikeGroup::getId).collect(Collectors.toList());
        List<UserLikeVO> groupDetails = userLikeService.getGroupDetails(groupIds);
//        if (CollectionUtils.isEmpty(groupDetails)) {
//            throw new BusinessException("groupDetails.not.found");
//        }
        Map<Long, List<UserLikeVO>> groupDetailMap = groupDetails.stream()
                .collect(Collectors.groupingBy(UserLikeVO::getUserLikeGroupId));

        Account account = accountService.getById(authPrincipalVo.getId());
        IPage<UserLikeGroupVO> convert = page.convert((Function<UserLikeGroup, UserLikeGroupVO>) group -> {
            if (group != null) {
                UserLikeGroupVO userLikeGroupVO = CopyUtil.copyObject(group, UserLikeGroupVO.class);
                userLikeGroupVO.setUpdateDate(group.getUpdateDate().getTime());
                userLikeGroupVO.setAuthor(account.getUserName());
                //count 和detail
                if (groupDetailMap.keySet().contains(group.getId())) {
                    List<UserLikeVO> details = groupDetailMap.get(group.getId());
                    for (UserLikeVO detail : details) {
                        TDesignPythonOutfit tDesignPythonOutfit = designPythonOutfitMapper.selectById(detail.getDesignOutfitId());
                        detail.setUrl(minioUtil.getPreSignedUrl(tDesignPythonOutfit.getDesignUrl(), 24 * 60));
                    }
                    userLikeGroupVO.setGroupDetails(details);
                    userLikeGroupVO.setSketchCount(CollectionUtils.isEmpty(details) ? 0 : details.size());
                }else {
                    userLikeGroupVO.setSketchCount(0);
                }
                if (userLikeGroupVO.getOriginal() == 0) {
                    userLikeGroupVO.setOriginalAccountName(accountService.getById(userLikeGroupVO.getOriginalAccountId()).getUserName());
                    Portfolio byId = portfolioService.getByIdAll(userLikeGroupVO.getOriginalPortfolioId());
                    if (Objects.nonNull(byId)) {
                        String portfolioName = byId.getPortfolioName();
                        userLikeGroupVO.setOriginalPortfolioName(portfolioName);
                    }
                }
                return userLikeGroupVO;
            }
            return null;
        });
        return Response.success(PageBaseResponse.success(convert));
    }

    @ApiOperation(value = "History用户分组详情,目前弃用 ")
    @GetMapping("/getUserGroupDetail")
    public Response<List<UserLikeVO>> getUserGroupDetail(
            @ApiParam("用户分组id") @RequestParam("userGroupId") Long userGroupId) {
        return Response.success(userLikeService.getGroupDetail(userGroupId));
    }

    @ApiOperation(value = "History修改用户分组名")
    @PostMapping("/updateUserGroupName")
    public Response<HistoryUpdateVO> updateUserGroupName(@Valid @RequestBody HistoryUpdateDTO historyUpdateDTO) {
        return Response.success(userLikeGroupService.updateUserGroupName(historyUpdateDTO.getUserGroupId()
                , historyUpdateDTO.getUserGroupName(), historyUpdateDTO.getTimeZone()));
    }

    @ApiOperation(value = "History删除用户分组")
    @PostMapping("/deleteUserGroup")
    public Response<Boolean> deleteUserGroup(@Valid @RequestBody HistoryDeleteDTO deleteDTO) {
        userLikeGroupService.deleteUserGroup(deleteDTO.getUserGroupId());
        userLikeService.deleteByUserGroupId(deleteDTO.getUserGroupId());
        return Response.success(Boolean.TRUE);
    }

    @ApiOperation(value = "History choose")
    @GetMapping("/choose")
    public Response<UserLikeChooseVO> choose(
            @ApiParam("用户分组id") @RequestParam("userGroupId") Long userGroupId) {
        return Response.success(userLikeGroupService.choose(userGroupId));
    }

    @ApiOperation(value = "exportSave")
    @PostMapping("/exportSave")
    public Response<Long> exportSave(@RequestParam("file") MultipartFile file, @RequestParam(value = "projectId", required = false) Long projectId,
                                        @RequestParam("module") String module, @RequestParam(value = "designItemDetailId", required = false) Long designItemDetailId) {
        return Response.success(userLikeGroupService.exportSave(file, projectId, module, designItemDetailId));
    }

    @ApiOperation(value = "exportSearch")
    @PostMapping("/exportSearch")
    public Response<JSONObject> exportSearch(@Valid @RequestBody ExportSearchDTO exportSearchDTO) {
        return Response.success(userLikeGroupService.exportSearch(exportSearchDTO));
    }

    @ApiOperation(value = "toProduct")
    @PostMapping("/toProduct")
    public Response<List<ToProductImageResultVO>> toProduct(@Valid @RequestBody ToProductImageDTO toProductImageDTO) {
        return Response.success(userLikeGroupService.toProduct(toProductImageDTO));
    }

    @ApiOperation(value = "toProductImageElementUpload")
    @PostMapping("/toProductImageElementUpload")
    public Response<ToProductElementVO> toProductImageElementUpload(@RequestParam("file") MultipartFile file,
                                                                    @RequestParam(value = "projectId", required = false) Long projectId,
                                                                    @ApiParam(value = "首尾帧", example = "first",
                                                                            allowableValues = "first,last")
                                                                    @RequestParam(value = "type", required = false) String type) {
        return Response.success(userLikeGroupService.toProductImageElementUpload(file, projectId, type));
    }

    @ApiOperation(value = "toProductImageElementDelete")
    @PostMapping("/toProductImageElementDelete")
    public Response<Boolean> toProductImageElementDelete(@RequestParam(value = "id") Long id) {
        return Response.success(userLikeGroupService.toProductImageElementDelete(id));
    }

    @ApiOperation(value = "productImageLike")
    @PostMapping("/productImageLike")
    public Response<CollectionSort> productImageLike(@Valid @RequestBody ProductImageLikeDTO productImageLikeDTO) {
        CollectionSort collectionSort = userLikeGroupService.productImageLike(productImageLikeDTO);
        return Response.success(collectionSort);
    }

    @ApiOperation(value = "collectionLikeUpdate")
    @PostMapping("/collectionLikeUpdate")
    public Response<Boolean> collectionLikeUpdate(@Valid @RequestBody CollectionLikeUpdateDTO collectionLikeUpdateDTO) {
        return Response.success(userLikeGroupService.collectionLikeUpdate(collectionLikeUpdateDTO));
    }

    @ApiOperation(value = "productImageUnLike")
    @PostMapping("/productImageUnLike")
    public Response<Boolean> productImageUnLike(@Valid @RequestBody ProductImageLikeDTO productImageLikeDTO) {
        return Response.success(userLikeGroupService.productImageUnLike(productImageLikeDTO));
    }

    @ApiOperation(value = "获取生成结果")
    @PostMapping("/toProductImageResult")
    public Response<List<MagicToolResultVO>> getToProductImageResult(@Valid @RequestBody List<String> taskIdList) {
        List<MagicToolResultVO> magicToolResultVOList = userLikeGroupService.getToProductImageResultList(taskIdList);
        return Response.success(magicToolResultVOList);
    }

    @ApiOperation(value = "画布用户上传元素")
    @PostMapping("/canvasElementUpload")
    public Response<CanvasElementUpload> canvasElementUpload(@RequestParam("file") MultipartFile file) {
        return Response.success(userLikeGroupService.canvasElementUpload(file));
    }

    @ApiOperation("productImageLikeList")
    @PostMapping("/productImageLikeList")
    public Response<List<ToProductImageResultVO>> productImageLikeList(@Valid @RequestBody ToProductImageDTO toProductImageDTO) {
        return Response.success(userLikeGroupService.productImageLikeList(toProductImageDTO));
    }

    @ApiOperation(value = "relight")
    @PostMapping("/relight")
    public Response<List<ToProductImageResultVO>> relight(@Valid @RequestBody ToProductImageDTO toProductImageDTO) {
        return Response.success(userLikeGroupService.relight(toProductImageDTO));
    }

    @ApiOperation(value = "转relight元素")
    @PostMapping("/convertRelightElement")
    public Response<ToProductElementVO> convertRelightElement(@RequestParam("id") Long id) {
        return Response.success(userLikeGroupService.convertRelightElement(id));
    }

    @ApiOperation(value = "获取relight结果")
    @PostMapping("/relightResult")
    public Response<List<MagicToolResultVO>> getRelightResult(@Valid @RequestBody List<String> taskIdList) {
        List<MagicToolResultVO> magicToolResultVOList = userLikeGroupService.getRelightResult(taskIdList);
        return Response.success(magicToolResultVOList);
    }

    @ApiOperation(value = "删除toProduct Relight的结果")
    @GetMapping("/deleteResult")
    public Response<String> deleteResult(@RequestParam("id") Long id,
                                                         @RequestParam("projectId") Long projectId,
                                                         @RequestParam("type") @Pattern(regexp =  "^(Relight|ToProductImage)$", message = "Please choose type from 'Relight|ToProductImage'") String type){
        try{
            userLikeGroupService.deleteToProductRelightResult(id, projectId, type);
            return Response.success();
        }catch (Exception e){
            return Response.fail(e.getMessage());
        }
    }

    @ApiOperation(value = "likeHistoryRelSketch")
    @PostMapping("/likeHistoryRelSketch")
    public Response<String> likeHistoryRelSketch() {
        return Response.success(userLikeGroupService.likeHistoryRelSketch());
    }

    @ApiOperation(value = "download")
    @PostMapping("/download")
    public Response<String> download() {
        return Response.success(userLikeGroupService.download());
    }

    @ApiOperation(value = "productImageInitialize")
    @PostMapping("/productImageInitialize")
    public Response<Boolean> productImageUpload(@Valid @RequestBody ProductImageInitializeDTO productImageInitializeDTO) {
        return Response.success(userLikeGroupService.productImageInitialize(productImageInitializeDTO));
    }

    @ApiOperation(value = "getInitializeProgress")
    @PostMapping("/getInitializeProgress")
    public Response<InitializeProgressVO> getInitializeProgress(@Valid @RequestBody ProductImageInitializeDTO productImageInitializeDTO) {
        return Response.success(userLikeGroupService.getInitializeProgress(productImageInitializeDTO));
    }

    @ApiOperation(value = "brandDNASaveOrUpdate")
    @PostMapping("/brandDNASaveOrUpdate")
    public Response<Boolean> brandDNASaveOrUpdate(@Valid @RequestBody BrandDNADTO brandDNADTO) {
        return Response.success(userLikeGroupService.brandDNASaveOrUpdate(brandDNADTO));
    }

    @ApiOperation(value = "brandDNADelete")
    @PostMapping("/brandDNADelete")
    public Response<Boolean> brandDNADelete(@Valid @RequestBody BrandDNADTO brandDNADTO) {
        return Response.success(userLikeGroupService.brandDNADelete(brandDNADTO));
    }

    @ApiOperation(value = "brandDNAPage")
    @PostMapping("/brandDNAPage")
    public Response<PageBaseResponse<BrandDNAVO>> brandDNAPage(@Valid @RequestBody BrandDNAQueryDTO brandDNAQueryDTO) {
        return Response.success(userLikeGroupService.brandDNAPage(brandDNAQueryDTO));
    }

    @ApiOperation(value = "brandLogoUpload")
    @PostMapping("/brandLogoUpload")
    public Response<BrandLogoUploadVO> brandDNASaveOrUpdate(@RequestParam("file") MultipartFile file) {
        return Response.success(userLikeGroupService.brandLogoUpload(file));
    }

    @ApiOperation(value = "brandDNAUpload")
    @PostMapping("/brandDNAUpload")
    public Response<LibraryUpdateVo> brandDNAUpload(@RequestParam("file") MultipartFile file, @RequestParam("brandId") Long brandId) throws IOException {
        return Response.success(userLikeGroupService.brandDNAUpload(file, brandId));
    }

    @ApiOperation(value = "brandDNAGenerate")
    @PostMapping("/brandDNAGenerate")
    public Response<BrandDNAGenerateVO> brandDNAGenerate(@RequestParam("prompt") String prompt) {
        return Response.success(userLikeGroupService.brandDNAGenerate(prompt));
    }
}
