package com.hz.pm.api.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.Assert;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hz.pm.api.common.helper.RegionCacheHelper;
import com.hz.pm.api.common.model.constant.BizConst;
import com.hz.pm.api.common.util.StrUtils;
import com.hz.pm.api.gov.model.entity.GovBizProjectBaseinfo;
import com.hz.pm.api.gov.service.IGovBizProjectBaseinfoService;
import com.hz.pm.api.portrait.model.dto.TagDTO;
import com.hz.pm.api.portrait.model.dto.TagToProjectDTO;
import com.hz.pm.api.portrait.model.entity.ProjectTag;
import com.hz.pm.api.portrait.model.entity.Tag;
import com.hz.pm.api.portrait.model.req.TagPageReq;
import com.hz.pm.api.portrait.model.vo.TagVO;
import com.hz.pm.api.portrait.service.IProjectTagService;
import com.hz.pm.api.portrait.service.ITagService;
import com.hz.pm.api.projectlib.model.entity.Project;
import com.hz.pm.api.projectlib.service.IProjectService;
import com.hz.pm.api.user.security.model.UserInfoDetails;
import com.hz.pm.api.user.util.LoginUserUtil;
import com.ningdatech.basic.function.VUtils;
import com.ningdatech.basic.model.PageVo;
import com.ningdatech.basic.util.CollUtils;
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;

/**
 * <p>
 * TagManage-项目标签管理
 * </p>
 *
 * @author WendyYang
 * @since 11:37 2024/1/15
 */
@Component
@Slf4j
@AllArgsConstructor
public class TagManage {

    private final ITagService tagService;

    private final IProjectService projectService;

    private final IProjectTagService projectTagService;

    private final IGovBizProjectBaseinfoService baseinfoService;

    private final RegionCacheHelper regionCacheHelper;

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

    /**
     * 权限控制
     *
     * @param query \
     * @param user  \
     */
    private void checkAuth(LambdaQueryWrapper<Tag> query, UserInfoDetails user) {
        //如果是超管
        if (user.getSuperAdmin() || user.getRegionAdmin()) {
            log.info(user.getUsername() + " 是超管,可以看所有标签");
        } 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());
            Assert.notNull(old, "此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 BizConst.SAVE_SUCCESS;
    }

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

    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);
        GovBizProjectBaseinfo baseinfo = baseinfoService.getOne(Wrappers.lambdaQuery(GovBizProjectBaseinfo.class)
                .eq(GovBizProjectBaseinfo::getBaseProjId, projectCode)
                .last(BizConst.LIMIT_1));
        VUtils.isTrue(Objects.isNull(project) && Objects.isNull(baseinfo)).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("标签不存在!");
            ProjectTag projectTag = new ProjectTag();
            projectTag.setProjectCode(projectCode);
            projectTag.setTagId(tagId);
            projectTag.setCreateOn(LocalDateTime.now());
            projectTag.setCreateBy(user.getUsername());
            projectTagService.save(projectTag);
        }

        return BizConst.SAVE_SUCCESS;
    }

    public String removeTagToProject(TagToProjectDTO dto) {
        String projectCode = dto.getProjectCode();
        Project project = projectService.getProjectByCode(projectCode);
        GovBizProjectBaseinfo baseinfo = baseinfoService.getOne(Wrappers
                .lambdaQuery(GovBizProjectBaseinfo.class)
                .eq(GovBizProjectBaseinfo::getBaseProjId, projectCode)
                .last(BizConst.LIMIT_1));
        VUtils.isTrue(Objects.isNull(project) && Objects.isNull(baseinfo)).throwMessage("项目不存在!");
        Long tagId = dto.getTagId();
        Tag tag = tagService.getById(tagId);
        VUtils.isTrue(Objects.isNull(tag)).throwMessage("标签不存在!");
        ProjectTag pt = projectTagService.getOne(Wrappers.lambdaQuery(ProjectTag.class)
                .eq(ProjectTag::getProjectCode, projectCode)
                .eq(ProjectTag::getTagId, tagId));

        Assert.notNull(pt, "该项目没有绑定此标签!");
        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 "删除失败";
    }
}
