package com.ningdatech.pmapi.portrait.manage;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ningdatech.basic.function.VUtils;
import com.ningdatech.basic.model.PageVo;
import com.ningdatech.basic.util.CollUtils;
import com.ningdatech.pmapi.common.constant.RegionConst;
import com.ningdatech.pmapi.portrait.model.dto.TagDTO;
import com.ningdatech.pmapi.portrait.model.dto.TagToProjectDTO;
import com.ningdatech.pmapi.portrait.model.entity.ProjectTag;
import com.ningdatech.pmapi.portrait.model.entity.Tag;
import com.ningdatech.pmapi.portrait.model.req.TagPageReq;
import com.ningdatech.pmapi.portrait.model.vo.TagVO;
import com.ningdatech.pmapi.portrait.service.IProjectTagService;
import com.ningdatech.pmapi.portrait.service.ITagService;
import com.ningdatech.pmapi.projectlib.model.entity.Project;
import com.ningdatech.pmapi.projectlib.service.IProjectService;
import com.ningdatech.pmapi.user.security.auth.model.UserInfoDetails;
import com.ningdatech.pmapi.user.util.LoginUserUtil;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @Classname TagManage
 * @Description
 * @Date 2023/8/2 14:10
 * @Author PoffyZhang
 */
@Component
@Slf4j
@AllArgsConstructor
public class TagManage {

    private final ITagService tagService;

    private final IProjectService projectService;

    private final IProjectTagService projectTagService;

    /**
     * 标签分页
     * @param areaCode
     * @param req
     * @return
     */
    public PageVo<TagVO> list(String areaCode, TagPageReq req) {
        LambdaQueryWrapper<Tag> query = Wrappers.lambdaQuery(Tag.class)
                .eq(Tag::getAreaCode, areaCode)
                .like(StringUtils.isNotBlank(req.getName()),Tag::getName,req.getName())
                .orderByDesc(Tag::getUpdateOn);
        checkAuth(query,LoginUserUtil.loginUserDetail());
        Page<Tag> page = tagService.page(req.page(), query);
        long total;
        if ((total = page.getTotal()) == 0) {
            return PageVo.empty();
        }
        List<TagVO> records = CollUtils.convert(page.getRecords(),
                t -> BeanUtil.copyProperties(t,TagVO.class));
        return PageVo.of(records, total);
    }

    /**
     * 权限控制
     * @param query
     * @param user
     */
    private void checkAuth(LambdaQueryWrapper<Tag> query, UserInfoDetails user) {
        //如果是超管
        if(user.getSuperAdmin()){
            log.info(user.getUsername() + " 是超管,可以看所有标签");
        }else if(user.getRegionAdmin()){
            //如果是区域管理员
            log.info(user.getUsername() + " 是区管,可以看本区域" + user.getRegionCode() + "标签");
            if(!RegionConst.RC_LS.equals(user.getRegionCode())){
                //非市本级的区管 只可以看自己区域的
                query.eq(Tag::getAreaCode,user.getRegionCode());
            }
            //市本级 能看所有区域
        }else{
            //其它角色全都看不见
            query.eq(Tag::getId,0L);
        }
    }

    /**
     * 保存标签
     * @param dto
     * @return
     */
    public String save(TagDTO dto) {
        deduplicationName(dto);
        UserInfoDetails user = LoginUserUtil.loginUserDetail();
        Tag entity = BeanUtil.copyProperties(dto,Tag.class);
        if(Objects.nonNull(dto.getId())){
            Tag old = tagService.getById(dto.getId());
            VUtils.isTrue(Objects.isNull(old)).throwMessage("此id标签不存在!");
            entity.setId(old.getId());
        }else{
            entity.setId(null);
            entity.setCreateOn(LocalDateTime.now());
            entity.setCreateBy(user.getUsername());
        }
        entity.setUpdateOn(LocalDateTime.now());
        entity.setUpdateBy(user.getUsername());
        tagService.saveOrUpdate(entity);

        return "保存成功";
    }

    /**
     * 标签名 去重
     * @param dto
     */
    private void deduplicationName(TagDTO dto) {
        if(StringUtils.isNotBlank(dto.getName())){
            long count = tagService.count(Wrappers.lambdaQuery(Tag.class)
                    .eq(Tag::getAreaCode, dto.getAreaCode())
                    .eq(Tag::getName, dto.getName())
                    .ne(Objects.nonNull(dto.getId()), Tag::getId, dto.getId()));
            VUtils.isTrue(count > 0).throwMessage("保存失败！此区域标签名重复!");
        }
    }

    public String saveToProject(List<TagToProjectDTO> dtos) {
        if(CollUtil.isEmpty(dtos)){
            return "参入的标签为空";
        }
        UserInfoDetails user = LoginUserUtil.loginUserDetail();
        String projectCode = dtos.get(0).getProjectCode();
        Project project = projectService.getProjectByCode(projectCode);
        VUtils.isTrue(Objects.isNull(project)).throwMessage("项目不存在!");
        projectTagService.remove(Wrappers.lambdaQuery(ProjectTag.class)
                .eq(ProjectTag::getProjectCode,projectCode));
        //去重
        dtos = dtos.stream().distinct().collect(Collectors.toList());
        for(TagToProjectDTO dto : dtos){
            Long tagId = dto.getTagId();
            Tag tag = tagService.getById(tagId);
            VUtils.isTrue(Objects.isNull(tag)).throwMessage("标签不存在!");
            VUtils.isTrue(!tag.getAreaCode().equals(project.getAreaCode()))
                    .throwMessage("项目和标签不是一个区域的!");
            ProjectTag projectTag = new ProjectTag();
            projectTag.setProjectCode(projectCode);
            projectTag.setTagId(tagId);
            projectTag.setCreateOn(LocalDateTime.now());
            projectTag.setCreateBy(user.getUsername());
            projectTagService.save(projectTag);
        }

        return "保存成功";
    }

    public String removeTagToProject(TagToProjectDTO dto) {
        String projectCode = dto.getProjectCode();
        Project project = projectService.getProjectByCode(projectCode);
        VUtils.isTrue(Objects.isNull(project)).throwMessage("项目不存在!");
        Long tagId = dto.getTagId();
        Tag tag = tagService.getById(tagId);
        VUtils.isTrue(Objects.isNull(tag)).throwMessage("标签不存在!");

        VUtils.isTrue(!tag.getAreaCode().equals(project.getAreaCode()))
                .throwMessage("项目和标签不是一个区域的!");

        ProjectTag pt = projectTagService.getOne(Wrappers.lambdaQuery(ProjectTag.class)
                .eq(ProjectTag::getProjectCode, projectCode)
                .eq(ProjectTag::getTagId, tagId));

        VUtils.isTrue(Objects.isNull(pt))
                .throwMessage("该项目没有绑定此标签!");
        projectTagService.removeById(pt.getId());

        return "删除成功";
    }

    /**
     * 删除标签
     * @param id
     * @return
     */
    public String delete(Long id) {
        Tag tag = tagService.getById(id);
        VUtils.isTrue(Objects.isNull(tag))
                .throwMessage("删除失败 此标签ID不存在！");

        if(tagService.removeById(id)){
            //关联关系 也要删
            projectTagService.remove(Wrappers.lambdaQuery(ProjectTag.class)
                    .eq(ProjectTag::getTagId,id));
            return "删除成功";
        }
        return "删除失败";
    }
}
