package com.ai.da.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.ai.da.common.config.exception.BusinessException;
import com.ai.da.common.constant.CommonConstant;
import com.ai.da.common.enums.SingleOverallEnum;
import com.ai.da.common.utils.CopyUtil;
import com.ai.da.common.utils.DateUtil;
import com.ai.da.common.utils.MD5Utils;
import com.ai.da.common.utils.MinioUtil;
import com.ai.da.mapper.primary.LibraryModelPointMapper;
import com.ai.da.mapper.primary.entity.*;
import com.ai.da.model.dto.LibraryModelPointDTO;
import com.ai.da.model.dto.ModelsDotDTO;
import com.ai.da.model.enums.ModelType;
import com.ai.da.model.enums.Sex;
import com.ai.da.model.vo.LibraryModelPointVO;
import com.ai.da.python.PythonService;
import com.ai.da.python.vo.DesignPythonObjects;
import com.ai.da.service.LibraryModelPointService;
import com.ai.da.service.LibraryService;
import com.ai.da.service.PythonTAllInfoService;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.netty.util.internal.StringUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * 服务实现类
 *
 * @author yanglei
 * @since 2022-11-30
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class LibraryModelPointServiceImpl extends ServiceImpl<LibraryModelPointMapper, LibraryModelPoint> implements LibraryModelPointService {
    private final LibraryModelPointMapper libraryModelPointMapper;
    private final LibraryService libraryService;
    private final MinioUtil minioUtil;
    private final PythonService pythonService;
    private final PythonTAllInfoService pythonTAllInfoService;

    @Override
    public LibraryModelPointVO saveOrEditTemplatePoint(LibraryModelPointDTO libraryModelPointDTO) {
        LibraryModelPointVO libraryModelPointVO = CopyUtil.copyObject(libraryModelPointDTO, LibraryModelPointVO.class);

        // 不管是保存还是另存为，都需要传模特的libraryId
        Library libModel = libraryService.getById(libraryModelPointDTO.getLibraryId());
        if (Objects.isNull(libModel)) {
            throw new BusinessException("model.not.found");
        }

        // 当前模特路径
        String url = libraryModelPointDTO.getModelPath();
        // 标志是否有更改过模特比例（即更换模特图）
        boolean flag = !url.equals(libModel.getUrl());

        if (libraryModelPointDTO.getIsCovered()) {
            // 更新模特图片
            if (flag) {
                libModel.setUrl(url);
                libModel.setMd5(MD5Utils.encryptFile(minioUtil.getPreSignedUrl(url, CommonConstant.MINIO_IMAGE_EXPIRE_TIME), false));
                List<Integer> imagesWidthAndHeight = minioUtil.getImagesWidthAndHeight(url);
                libModel.setWidth(imagesWidthAndHeight.get(0));
                libModel.setHigh(imagesWidthAndHeight.get(1));
                libModel.setUpdateDate(DateUtil.getByTimeZone(libraryModelPointDTO.getTimeZone()));
                libraryService.updateById(libModel);
            }

            if (Objects.nonNull(libraryModelPointDTO.getTemplateId())) {
                // 覆盖保存，即更新原有数据（点位数据和模特图片）
                LibraryModelPoint modelPoint = getById(libraryModelPointDTO.getTemplateId());
                if (Objects.isNull(modelPoint)) {
                    throw new BusinessException("modelPoint.not.found");
                }
                // 更新点位信息
                modelPoint = resolvePoint(libraryModelPointDTO);
                modelPoint.setUpdateDate(DateUtil.getByTimeZone(libraryModelPointDTO.getTimeZone()));
                modelPoint.setId(libraryModelPointDTO.getTemplateId());
                updateById(modelPoint);
                libraryModelPointVO.setTemplateId(modelPoint.getId());
                libraryModelPointVO.setRelationId(libraryModelPointDTO.getLibraryId());
            } else {
                // 新增模特点位信息
                LibraryModelPoint libraryModelPoint = resolvePoint(libraryModelPointDTO);
                libraryModelPoint.setModelType("Library");
                libraryModelPoint.setCreateDate(DateUtil.getByTimeZone(libraryModelPointDTO.getTimeZone()));
                save(libraryModelPoint);
                libraryModelPointVO.setTemplateId(libraryModelPoint.getId());
                libraryModelPointVO.setRelationId(libraryModelPointDTO.getLibraryId());
            }

        } else {
            // 不覆盖，即另存为
            // 新增模特library信息
            Library saveAsModel = new Library();
            saveAsModel.setAccountId(libModel.getAccountId());
            saveAsModel.setLevel1Type(libModel.getLevel1Type());
            saveAsModel.setLevel2Type(libModel.getLevel2Type());
            String ageGroup = StringUtil.isNullOrEmpty(libModel.getLevel3Type()) ? "Adult" : libModel.getLevel3Type();
            saveAsModel.setLevel3Type(ageGroup);
            saveAsModel.setName(DateUtil.dateToStr(new Date(), DateUtil.YYYY_MM_DD));
            saveAsModel.setUrl(url);
            saveAsModel.setMd5(MD5Utils.encryptFile(minioUtil.getPreSignedUrl(url, CommonConstant.MINIO_IMAGE_EXPIRE_TIME), false));
            List<Integer> imagesWidthAndHeight = minioUtil.getImagesWidthAndHeight(url);
            saveAsModel.setWidth(imagesWidthAndHeight.get(0));
            saveAsModel.setHigh(imagesWidthAndHeight.get(1));
            saveAsModel.setCreateDate(DateUtil.getByTimeZone(libraryModelPointDTO.getTimeZone()));
            libraryService.save(saveAsModel);
            // 更新新的模特在library中的id,用于后面新建模特点位信息用
            libraryModelPointDTO.setLibraryId(saveAsModel.getId());

            // 新增模特点位信息
            LibraryModelPoint libraryModelPoint = resolvePoint(libraryModelPointDTO);
            libraryModelPoint.setModelType("Library");
            libraryModelPoint.setCreateDate(DateUtil.getByTimeZone(libraryModelPointDTO.getTimeZone()));
            save(libraryModelPoint);
            libraryModelPointVO.setTemplateId(libraryModelPoint.getId());
            libraryModelPointVO.setRelationId(libraryModelPoint.getRelationId());
        }
        //编辑
            /*if (!StringUtils.isEmpty(libraryModelPointDTO.getModelSex())) {
                Library byId = libraryService.getById(libraryModelPointDTO.getLibraryId());
                if (!byId.getLevel2Type().equals(libraryModelPointDTO.getModelSex())) {
                    if (byId.getLevel2Type().equals(Sex.FEMALE.getValue())) {
                        libraryService.checkModel(Sex.FEMALE.getValue(), Collections.singletonList(byId.getId()), 1);
                    }else {
                        libraryService.checkModel(Sex.MALE.getValue(), Collections.singletonList(byId.getId()), 1);
                    }
                    byId.setLevel2Type(libraryModelPointDTO.getModelSex());
                    libraryService.updateById(byId);
                }
            }*/
        return libraryModelPointVO;
    }

    @Override
    public LibraryModelPointVO saveOrEditTemplatePointOld(LibraryModelPointDTO libraryModelPointDTO) {
//        Library library = libraryService.getById(libraryModelPointDTO.getLibraryId());
//        Assert.notNull(library,"library does not exist!");
        LibraryModelPointVO libraryModelPointVO = CopyUtil.copyObject(libraryModelPointDTO, LibraryModelPointVO.class);
        if (Objects.isNull(libraryModelPointDTO.getTemplateId())) {
            //新增
            LibraryModelPoint libraryModelPoint = resolvePoint(libraryModelPointDTO);
            libraryModelPoint.setCreateDate(DateUtil.getByTimeZone(libraryModelPointDTO.getTimeZone()));
            save(libraryModelPoint);
            libraryModelPointVO.setTemplateId(libraryModelPoint.getId());
        } else {
            //编辑
            if (!StringUtils.isEmpty(libraryModelPointDTO.getModelSex())) {
                Library byId = libraryService.getById(libraryModelPointDTO.getLibraryId());
                if (!byId.getLevel2Type().equals(libraryModelPointDTO.getModelSex())) {
                    if (byId.getLevel2Type().equals(Sex.FEMALE.getValue())) {
                        libraryService.checkModel(Sex.FEMALE.getValue(), Collections.singletonList(byId.getId()), 1);
                    } else {
                        libraryService.checkModel(Sex.MALE.getValue(), Collections.singletonList(byId.getId()), 1);
                    }
                    byId.setLevel2Type(libraryModelPointDTO.getModelSex());
                    libraryService.updateById(byId);
                }
            }
            LibraryModelPoint modelPoint = getById(libraryModelPointDTO.getTemplateId());
            if (Objects.isNull(modelPoint)) {
                throw new BusinessException("modelPoint.not.found");
            }
            modelPoint = resolvePoint(libraryModelPointDTO);
            modelPoint.setUpdateDate(DateUtil.getByTimeZone(libraryModelPointDTO.getTimeZone()));
            modelPoint.setId(libraryModelPointDTO.getTemplateId());
            updateById(modelPoint);
            libraryModelPointVO.setTemplateId(modelPoint.getId());
        }
        return libraryModelPointVO;
    }

    private LibraryModelPoint resolvePoint(LibraryModelPointDTO libraryModelPointDTO) {
        LibraryModelPoint libraryModelPoint = CopyUtil.copyObject(libraryModelPointDTO, LibraryModelPoint.class);
        libraryModelPoint.setRelationId(libraryModelPointDTO.getLibraryId());
        libraryModelPoint.setHandLeft(JSON.toJSONString(libraryModelPointDTO.getHandLeft()));
        libraryModelPoint.setHandRight(JSON.toJSONString(libraryModelPointDTO.getHandRight()));
        libraryModelPoint.setWaistbandLeft(JSON.toJSONString(libraryModelPointDTO.getWaistbandLeft()));
        libraryModelPoint.setWaistbandRight(JSON.toJSONString(libraryModelPointDTO.getWaistbandRight()));
        libraryModelPoint.setShoulderLeft(JSON.toJSONString(libraryModelPointDTO.getShoulderLeft()));
        libraryModelPoint.setShoulderRight(JSON.toJSONString(libraryModelPointDTO.getShoulderRight()));
        return libraryModelPoint;
    }


    @Override
    public List<LibraryModelPointVO> selectByLibraryIds(List<Long> libraryIds) {
        QueryWrapper<LibraryModelPoint> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(LibraryModelPoint::getModelType, ModelType.LIBRARY.getValue());
        queryWrapper.in("relation_id", libraryIds);
        List<LibraryModelPoint> libraryModelPoints = libraryModelPointMapper.selectList(queryWrapper);
        if (CollectionUtils.isEmpty(libraryModelPoints)) {
            return null;
        }
        return CopyUtil.copyList(libraryModelPoints, LibraryModelPointVO.class, (o, d) -> {
            d.setTemplateId(o.getId());
            d.setHandLeft(JSON.parseObject(o.getHandLeft(), List.class));
            d.setHandRight(JSON.parseObject(o.getHandRight(), List.class));
            d.setShoulderRight(JSON.parseObject(o.getShoulderRight(), List.class));
            d.setShoulderLeft(JSON.parseObject(o.getShoulderLeft(), List.class));
            d.setWaistbandRight(JSON.parseObject(o.getWaistbandRight(), List.class));
            d.setWaistbandLeft(JSON.parseObject(o.getWaistbandLeft(), List.class));
        });
    }

    @Override
    public String modelsDot(ModelsDotDTO modelsDotDTO) {
        DesignPythonObjects objects = pythonService.covertModelsDotParam(
                modelsDotDTO, SingleOverallEnum.OVERALL.getRealName(), "");
        pythonTAllInfoService.relationImageId(objects);
        JSONObject jsonObject = pythonService.designNew(objects);
        JSONObject data = jsonObject.getJSONObject("data");
        if (data == null) {
            throw new BusinessException("design.interface.exception");
        }
        JSONObject jsonObject1 = data.getJSONObject("0");
        if (jsonObject1 == null) {
            throw new BusinessException("design.interface.exception");
        }
        String synthesisUrl = jsonObject1.getString("synthesis_url");
        if (StringUtils.isEmpty(synthesisUrl)) {
            throw new BusinessException("design.interface.exception");
        }
        return synthesisUrl;
    }

    @Override
    public LibraryModelPoint getByRelationId(Long relationId, String modelType) {
        QueryWrapper<LibraryModelPoint> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(LibraryModelPoint::getRelationId, relationId);
        queryWrapper.lambda().eq(LibraryModelPoint::getModelType, modelType);
        queryWrapper.lambda().last("limit 1");
        List<LibraryModelPoint> libraryModelPoints = baseMapper.selectList(queryWrapper);
        if (CollectionUtil.isEmpty(libraryModelPoints)) {
            throw new BusinessException("modelPoint.not.found");
        }
        return libraryModelPoints.get(0);
    }

}
