package com.ai.da.controller;

import com.ai.da.common.config.FileProperties;
import com.ai.da.common.config.exception.BusinessException;
import com.ai.da.common.context.UserContext;
import com.ai.da.common.enums.LibraryLevel1TypeEnum;
import com.ai.da.common.response.PageBaseResponse;
import com.ai.da.common.response.Response;
import com.ai.da.common.utils.*;
import com.ai.da.mapper.primary.entity.Library;
import com.ai.da.mapper.primary.entity.LibraryModelPoint;
import com.ai.da.model.dto.*;
import com.ai.da.model.vo.*;
import com.ai.da.service.LibraryModelPointService;
import com.ai.da.service.LibraryService;
import com.alibaba.fastjson.JSON;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
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 java.io.File;
import java.text.ParseException;
import java.util.*;


@Api(tags = "library模块")
@Slf4j
@RestController
@RequestMapping("/api/library")
public class LibraryController {

    @Resource
    private LibraryService libraryService;
    @Resource
    private LibraryModelPointService libraryModelPointService;
    @Resource
    private FileProperties fileProperties;
    @Resource
    private MinioUtil minioUtil;

    @Value("${minio.bucketName.sysImage}")
    private String sysImage;

    @ApiOperation(value = "Library分页列表")
    @PostMapping("/queryLibraryPage")
    public Response<PageBaseResponse<QueryLibraryPageVO>> queryLibraryPage(@Valid @RequestBody QueryLibraryPageDTO query) {
        return Response.success(libraryService.queryLibraryPage(CopyUtil.copyObject(query, QueryLibraryPageServiceDTO.class)));
    }

    @ApiOperation(value = "Library分页列表(查询top和bottom)")
    @PostMapping("/queryLibraryTopAndBottomPage")
    public Response<PageBaseResponse<QueryLibraryPageVO>> queryLibraryTopAndBottomPage(@Valid @RequestBody QueryLibraryTopPageDTO query) {
        return Response.success(libraryService.queryLibraryPage(CopyUtil.copyObject(query, QueryLibraryPageServiceDTO.class)));
    }

    @ApiOperation(value = "Library文件上传")
    @PostMapping("/upload")
    public Response<LibraryUpdateVo> upload(@RequestParam("file") MultipartFile file,
                                            @ApiParam("一级类型 Moodboard Printboard  Sketchboard MarketingSketch Models")
                                            @RequestParam(value = "level1Type") String level1Type,
                                            @ApiParam("二级类型 争对 Sketchboard; 有 Outwear Dress Blouse  Skirt Trousers")
                                            @RequestParam(value = "level2Type", required = false) String level2Type,
                                            @ApiParam("本地时区,比如 'Asia/Tokyo' 东京时间 , 'Asia/Shanghai' 北京时间 由js本地获取")
                                            @RequestParam(value = "timeZone") String timeZone,
                                            @RequestParam(value = "modelType") String modelType,
                                            @RequestParam(value = "sex") String sex,
                                            @RequestParam(value = "ageGroup") String ageGroup,
                                            @RequestParam(value = "checkMd5") Integer checkMd5) {
        if (null == file || StringUtils.isEmpty(file.getOriginalFilename())) {
            throw new BusinessException("file.cannot.be.empty");
        }
        Integer high = null;
        Integer width = null;
        if (level1Type.equals(LibraryLevel1TypeEnum.MODELS.getRealName())) {
            if (StringUtils.isEmpty(modelType)) {
                throw new BusinessException("modelType.cannot.be.empty");
            }
            if (StringUtils.isEmpty(sex)) {
                throw new BusinessException("modelSex.cannot.be.empty");
            }
            FileVO fileVO = FileUtil.getFileSize(file);
            high = fileVO.getHigh();
            width = fileVO.getWidth();
        }
        String md5 = MD5Utils.encryptFile(file);
        if (checkMd5 == null || checkMd5 == 1) {
            if (!libraryService.checkMd5(level1Type, level2Type, sex, md5)) {
                LibraryUpdateVo libraryUpdateVo = new LibraryUpdateVo();
                libraryUpdateVo.setCheckMd5(Boolean.FALSE);
                return Response.success(libraryUpdateVo);
            }
        }
        return Response.success(libraryService.upload(new LibraryUploadDTO(file, level1Type, level2Type,
                timeZone, md5, high, width, modelType, sex, ageGroup)));
    }

    @ApiOperation(value = "保存或者编辑template打点")
    @PostMapping("/saveOrEditTemplatePoint")
    public Response<LibraryModelPointVO> saveOrEditTemplatePoint(@Valid @RequestBody LibraryModelPointDTO libraryModelPoint) {
        return Response.success(libraryModelPointService.saveOrEditTemplatePoint(libraryModelPoint));
    }

    @ApiOperation(value = "批量Library修改用户文件名")
    @PostMapping("/batchUpdateLibraryName")
    public Response<Boolean> batchUpdateLibraryName(@Valid @RequestBody LibraryUpdateDTO libraryUpdateDTO) {
        libraryService.updateLibraryName(libraryUpdateDTO);
        return Response.success(Boolean.TRUE);
    }

    @ApiOperation(value = "批量删除library")
    @PostMapping("/batchDeleteLibrary")
    public Response<Boolean> batchDeleteLibrary(@Valid @RequestBody LibraryDeleteDTO deleteDTO) {
        libraryService.batchDeleteLibrary(deleteDTO);
        return Response.success(Boolean.TRUE);
    }


    @ApiOperation(value = "Models打点预览")
    @PostMapping("/modelsDot")
    public Response<String> modelsDot(@ApiParam("file") @RequestPart(value = "file", required = false) MultipartFile file,
                                      @ApiParam("models对象") @RequestPart("models") ModelsDotDTO modelsDotDTO) {
        if (Objects.nonNull(file)) {
            if (StringUtils.isEmpty(file.getOriginalFilename())) {
                throw new BusinessException("file.cannot.be.empty");
            }
            AuthPrincipalVo userInfo = UserContext.getUserHolder();
            //需要宽高和地址参数design
            FileVO fileVO = FileUtil.getFileSize(file);
            modelsDotDTO.setHigh(fileVO.getHigh());
            modelsDotDTO.setWidth(fileVO.getWidth());
            //存储template临时地址
            String path = calculateTempFileUrlNew(userInfo.getId());
            String uploadPath = minioUtil.upload("aida-tmp", path, file);
            String minioPath = libraryService.processMannequins(uploadPath);
            modelsDotDTO.setTemplateUrl(minioPath);
        } else {
            if (null == modelsDotDTO.getLibraryId()) {
                throw new BusinessException("libraryId.cannot.be.empty");
            }
            if (null == modelsDotDTO.getTemplateId()) {
                throw new BusinessException("templateId.cannot.be.empty");
            }
            LibraryModelPoint modelPoint = libraryModelPointService.getById(modelsDotDTO.getTemplateId());
            if (Objects.isNull(modelPoint)) {
                throw new BusinessException("modelPoint.not.found");
            }
            Library library = libraryService.getById(modelsDotDTO.getLibraryId());
            if (Objects.isNull(library)) {
                throw new BusinessException("library.not.found");
            }
            modelsDotDTO.setHigh(library.getHigh());
            modelsDotDTO.setWidth(library.getWidth());
            modelsDotDTO.setTemplateUrl(library.getUrl());
        }
        Response<String> response = new Response();
        log.info("Models打点预览入参####{}", JSON.toJSONString(modelsDotDTO));
        String url = libraryModelPointService.modelsDot(modelsDotDTO);
        response.setData(minioUtil.getPreSignedUrl(url, 24 * 60));
        return response;
    }

    @ApiOperation(value = "更新sketchboard level2type")
    @PostMapping("/updateLibraryLevel2Type")
    public Response<Boolean> updateLibraryLevel2Type(@Validated @RequestBody LibraryLevel2TypeUpdateDTO libraryLevel2TypeUpdateDTO) {
        return Response.success(libraryService.updateLibraryLevel2Type(libraryLevel2TypeUpdateDTO));
    }

    private String calculateTempFileUrl(Long userId) {
        String rootPath = fileProperties.getSys().getPath();
        String day = DateUtil.dateToStr(new Date(), DateUtil.YYYYMM);
        return rootPath + day + File.separator + "tmp" + File.separator + userId + File.separator + UUID.randomUUID();
    }

    private String calculateTempFileUrlNew(Long userId) {
        return userId.toString();
    }

    private String calculateTemplateUrl(File uploadFile) {
        String linuxDomain = fileProperties.getLinuxDomain();
        if (!StringUtils.isEmpty(linuxDomain)) {
            //linux 系统
            String oldPath = fileProperties.getSys().getPath();
            return uploadFile.getAbsolutePath().replace(oldPath, linuxDomain);
        }
        //本地用
//        return "/home/pangkaicheng/python_code/Multi-layer-Virtual-Try-on/dataset_for_test/Img_model.png";
        return "/workspace/python_code/Multi-layer-Virtual-Try-on/dataset_for_test/Img_model.png";
    }

    @PostMapping("moveLibraryData")
    @ApiOperation(value = "用户library数据迁移")
    public Response<Boolean> moveLibraryDate() throws ParseException {
        libraryService.moveLibraryDate();
        return Response.success(true);
    }

    @ApiOperation(value = "将系统模特添加到个人library")
    @GetMapping("addSysModelToLib")
    public Response<Map<String, String>> addSysModelToLib(@ApiParam("系统模特id") @RequestParam("sysModelId")long sysModelId){
        return Response.success(libraryService.addSysModelToLib(sysModelId));
    }

    @ApiOperation(value = "将个人library元素添加到公共库")
    @GetMapping("addToPublicLibrary")
    public Response<String> addToPublicLibrary(@ApiParam("元素的libraryId") @RequestParam("libraryId") Long libraryId){
        boolean b = libraryService.saveToOrganizationLibrary(libraryId);
        if (b){
            return Response.success("success");
        }else {
            return Response.success("fail");
        }
    }

    @ApiOperation(value = "将个人library元素从公共库中删除")
    @GetMapping("deleteFromPublicLib")
    public Response<String> deleteFromPublicLib(@ApiParam("元素的libraryId") @RequestParam("libraryId") Long libraryId){
        libraryService.deleteFromPublicLib(libraryId);
        return Response.success("success");
    }

    @ApiOperation(value = "获取公共库")
    @GetMapping("getPublicLib")
    public Response<PageBaseResponse<Library>> getPublicLib(@ApiParam("排序" ) @RequestParam(value = "order", defaultValue = "DESC", required = false) String order,
                                                @ApiParam("page") @RequestParam(value = "page", defaultValue = "1", required = false) Long page,
                                                @ApiParam("size") @RequestParam(value = "size", defaultValue = "20", required = false) Long size){

        return Response.success(libraryService.getPublicLib(order, page, size));
    }

    @ApiOperation(value = "管理员获取所有子账号lib元素")
    @GetMapping("getAllSubAccLib")
    public Response<PageBaseResponse<Library>> getAllSubAccLib(@ApiParam("排序") @RequestParam(value = "order", defaultValue = "DESC", required = false) String order,
                                                   @ApiParam("page") @RequestParam(value = "page", defaultValue = "1", required = false) Long page,
                                                   @ApiParam("size") @RequestParam(value = "size", defaultValue = "20", required = false) Long size){
        return Response.success(libraryService.getAllSubAccLib(order, page, size));
    }

    @ApiOperation(value = "将系统sketch添加到library")
    @GetMapping("addSysSketchToLibrary")
    public Response<String> addSysSketchToLibrary(Long clothId, String path) {
        return Response.success(libraryService.addSysSketchToLibrary(clothId, path));
    }

}
