/*
 *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the dreamlu.net developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: Chill 庄骞 (smallchill@163.com)
 */
package org.springblade.manager.controller;

import com.alibaba.nacos.common.utils.MD5Utils;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.*;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import lombok.AllArgsConstructor;

import javax.validation.Valid;

import org.apache.commons.lang.StringUtils;
import org.springblade.common.utils.SnowFlakeUtil;
import org.springblade.core.log.exception.ServiceException;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.mp.support.Query;
import org.springblade.core.mp.utils.PageUtil;
import org.springblade.core.secure.BladeUser;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.Func;
import org.springblade.core.tool.utils.StringUtil;
import org.springblade.manager.dto.FindAllUserByConditionDTO;
import org.springblade.manager.dto.SaveUserInfoByProjectDTO;
import org.springblade.manager.dto.WbsTreeContractDTO;
import org.springblade.manager.entity.WbsTreeContract;
import org.springblade.manager.mapper.SaveUserInfoByProjectMapper;
import org.springblade.manager.service.IWbsTreeContractService;
import org.springblade.manager.service.SaveUserInfoByProjectService;
import org.springblade.manager.vo.CRolePostVO;
import org.springblade.manager.vo.WbsTreeContractTreeVO;
import org.springblade.manager.vo.WbsTreeVO;
import org.springblade.system.user.entity.User;
import org.springblade.system.user.feign.IUserClient;
import org.springblade.system.user.vo.UserVO2;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.RequestParam;

import org.springblade.manager.entity.ContractInfo;
import org.springblade.manager.vo.ContractInfoVO;
import org.springblade.manager.wrapper.ContractInfoWrapper;
import org.springblade.manager.service.IContractInfoService;
import org.springblade.core.boot.ctrl.BladeController;
import sun.security.provider.MD5;
import sun.security.provider.SHA;

import java.util.*;

/**
 * 合同段信息表 控制器
 *
 * @author liuyc
 * @since 2022-04-14
 */
@RestController
@AllArgsConstructor
@RequestMapping("/contractInfo")
@Api(value = "合同段", tags = "合同段接口")
public class ContractInfoController extends BladeController {

    private final IContractInfoService contractInfoService;
    private final SaveUserInfoByProjectService saveUserInfoByProject;
    private final IUserClient iUserClient;
    private final IWbsTreeContractService wbsTreeContractService;
    private final SaveUserInfoByProjectMapper saveUserInfoByProjectMapper;

    /**
     * 详情
     */
    @GetMapping("/detail")
    @ApiOperationSupport(order = 1)
    @ApiOperation(value = "详情", notes = "传入contractInfo")
    public R<ContractInfoVO> detail(ContractInfo contractInfo) {
        ContractInfo detail = contractInfoService.getOne(Condition.getQueryWrapper(contractInfo));
        return R.data(ContractInfoWrapper.build().entityVO(detail));
    }

    /**
     * 根据项目id查询当前所有合同
     */
    @GetMapping("/findContractInfoByPid")
    @ApiOperationSupport(order = 8)
    @ApiOperation(value = "根据项目id查询当前所有合同", notes = "传入pid")
    public R<List<ContractInfo>> findContractInfoByPid(String pid) {
        List<ContractInfo> contractInfoVOS = contractInfoService.selectContractInfoPageByPid(pid);
        return R.data(contractInfoVOS);
    }

    /**
     * 分页 合同段信息表
     */
    @GetMapping("/list")
    @ApiOperationSupport(order = 2)
    @ApiOperation(value = "分页", notes = "传入contractInfo")
    public R<IPage<ContractInfoVO>> list(ContractInfo contractInfo, Query query) {
        IPage<ContractInfo> pages = contractInfoService.page(Condition.getPage(query), Condition.getQueryWrapper(contractInfo));
        return R.data(ContractInfoWrapper.build().pageVO(pages));
    }

    /**
     * 自定义分页 合同段信息表
     */
    @GetMapping("/page")
    @ApiOperationSupport(order = 3)
    @ApiOperation(value = "自定义分页", notes = "传入contractInfo")
    public R<IPage<ContractInfoVO>> page(ContractInfoVO contractInfo, Query query) {
        IPage<ContractInfoVO> pages = contractInfoService.selectContractInfoPage(Condition.getPage(query), contractInfo);
        return R.data(pages);
    }


    /**
     * 新增 合同段信息表
     */
    @PostMapping("/save")
    @ApiOperationSupport(order = 4)
    @ApiOperation(value = "新增", notes = "传入contractInfo")
    public R save(@Valid @RequestBody ContractInfo contractInfo) {
        return R.status(contractInfoService.save(contractInfo));
    }

    /**
     * 修改 合同段信息表
     */
    @PostMapping("/update")
    @ApiOperationSupport(order = 5)
    @ApiOperation(value = "修改", notes = "传入contractInfo")
    public R update(@Valid @RequestBody ContractInfo contractInfo) {
        return R.status(contractInfoService.updateById(contractInfo));
    }

    /**
     * 删除文件
     */
    @GetMapping("/deleteFile")
    @ApiOperationSupport(order = 5)
    @ApiOperation(value = "删除文件", notes = "传入文件url")
    public R deleteFile(@Valid @RequestParam("url") String url) {
        return R.status(contractInfoService.deleteFile(url));
    }


    /**
     * 新增或修改 合同段信息表
     */
    @PostMapping("/submit")
    @ApiOperationSupport(order = 6)
    @ApiOperation(value = "新增或修改", notes = "传入contractInfo")
    public R submit(@Valid @RequestBody ContractInfoVO contractInfo) {
        //新增合同段
        boolean b = contractInfoService.saveAndUpdateContract(contractInfo);
        if (b) {
            return R.data(contractInfo, "操作成功");
        }
        return R.fail("操作失败");
    }


    /**
     * 删除 合同段信息表
     */
    @PostMapping("/remove")
    @ApiOperationSupport(order = 7)
    @ApiOperation(value = "逻辑删除", notes = "传入ids")
    public R remove(@ApiParam(value = "主键集合", required = true) @RequestParam String ids) {
        List<WbsTreeContract> wbsTreeContracts = wbsTreeContractService.findWbsTreeContract(ids);
        if (wbsTreeContracts.size() > 0) {
            return R.fail("合同段存在WBS树,删除失败");
        }
        return R.status(contractInfoService.deleteLogic(Func.toLongList(ids)));
    }


    /**
     * 查询角色的岗位
     */
    @GetMapping("/findJobByRoleId")
    @ApiOperationSupport(order = 8)
    @ApiOperation(value = "查询角色下的岗位", notes = "传入id")
    public R<List<CRolePostVO>> findJobByRoleId(@ApiParam(value = "id", required = true)
                                                @RequestParam("id") String id) {
        List<CRolePostVO> list = contractInfoService.findJobByRoleId(id);
        if (list.size() <= 0) {
            return R.data(list, "未查询到信息");
        }
        return R.data(list);
    }


    /**
     * 根据姓名查询用户
     */
    @GetMapping("/findUserByName")
    @ApiOperationSupport(order = 11)
    @ApiOperation(value = "根据姓名模糊查询用户", notes = "传入用户姓名")
    public R<List<User>> findUserByName(@RequestParam("name") String name) {
        List<User> userByName = contractInfoService.findUserByName(name);
        if (userByName.size() > 0) {
            return R.data(userByName);
        }
        return R.success("未查询到信息");
    }


    /**
     * 根据项目id、合同id、角色id查询当前运维的用户
     */
    @GetMapping("/findUserListByCondition")
    @ApiOperationSupport(order = 10)
    @ApiOperation(value = "查询当前项目角色下的运维用户列表", notes = "传入项目id、角色id、合同id(非必传)、size每页数量、current当前页")
    public R<IPage<User>> findUserListByCondition(FindAllUserByConditionDTO values, Query query) {
        IPage<User> users = contractInfoService.findUserListByCondition(Condition.getPage(query), values);
        return R.data(users);
    }


    /**
     * 项目分配用户批量保存-项目分配维护人员
     */
    @PostMapping("/saveUserInfoByProject")
    @ApiOperationSupport(order = 12)
    @ApiOperation(value = "保存-项目分配维护人员", notes = "传入项目id、合同id、字典主键id、用户id List集合")
    public R saveUserInfoByProject(@RequestBody List<SaveUserInfoByProjectDTO> list) {
        if (list.size() > 0) {
            list.forEach((lists) -> {
                //判重
                Long row = saveUserInfoByProjectMapper.selectCount(
                        Wrappers.<SaveUserInfoByProjectDTO>query().lambda().
                                eq(SaveUserInfoByProjectDTO::getProjectId, lists.getProjectId()).
                                eq(SaveUserInfoByProjectDTO::getContractId, lists.getContractId()).
                                eq(SaveUserInfoByProjectDTO::getRoleId, lists.getRoleId()).
                                eq(SaveUserInfoByProjectDTO::getUserId, lists.getUserId()));
                if (row > 0L) {
                    throw new ServiceException("当前用户角色已存在该合同段,请重新选择");
                }
                if (StringUtils.isEmpty(lists.getContractId())) {
                    //新增到全部合同段
                    List<ContractInfo> contractInfos = contractInfoService.selectContractInfoPageByPid(lists.getProjectId());
                    contractInfos.forEach(contractInfo -> {
                        Long id = SnowFlakeUtil.getId();
                        lists.setId(id);
                        lists.setStatus(1);
                        lists.setContractId(String.valueOf(contractInfo.getId()));
                        saveUserInfoByProject.save(lists);
                    });
                } else {
                    //新增单个合同段
                    saveUserInfoByProject.saveBatch(list);
                }
            });
            return R.success("保存成功");
        }
        return R.fail("保存失败");
    }

    /**
     * 根据项目id、合同id、岗位id查询当前分配的用户-查询当前项目合同岗位下的用户
     */
    @GetMapping("/findAllUserByCondition")
    @ApiOperationSupport(order = 9)
    @ApiOperation(value = "查询当前项目合同岗位下的用户", notes = "传入项目id、合同id、岗位id、size每页数量、current当前页")
    public R<IPage<UserVO2>> findAllUserByCondition(FindAllUserByConditionDTO values, Query query) {
        IPage<UserVO2> users = contractInfoService.findAllUserByCondition(Condition.getPage(query), values);
        return R.data(users);
    }


    /**
     * 项目分配用户批量保存-项目合同分配人员
     */
    @PostMapping("/saveUserInfoByProjectTow")
    @ApiOperationSupport(order = 13)
    @ApiOperation(value = "保存-项目合同分配人员", notes = "传入项目id、合同id、岗位处roleId、用户id")
    @Transactional(rollbackFor = Exception.class)
    public R saveUserInfoByProjectTow(@RequestBody List<SaveUserInfoByProjectDTO> list) {
        if (list.size() > 0) {
            //判重
            list.forEach((lists) -> {
                Long row = saveUserInfoByProjectMapper.selectCount(
                        Wrappers.<SaveUserInfoByProjectDTO>query().lambda().
                                eq(SaveUserInfoByProjectDTO::getProjectId, lists.getProjectId()).
                                eq(SaveUserInfoByProjectDTO::getContractId, lists.getContractId()).
                                eq(SaveUserInfoByProjectDTO::getRoleId, lists.getRoleId()).
                                eq(SaveUserInfoByProjectDTO::getUserId, lists.getUserId()));
                if (row > 0L) {
                    throw new ServiceException("当前用户角色岗位已存在,请重新选择");
                }
            });
            boolean result = saveUserInfoByProject.saveBatch(list);
            if (result) {
                return R.success("保存成功");
            }
        }
        return R.fail("保存失败");
    }


    /**
     * 项目分配用户逻辑删除
     */
    @PostMapping("/removeUsersByIds")
    @ApiOperationSupport(order = 14)
    @ApiOperation(value = "逻辑删除", notes = "传入当前列表用户的记录ids")
    public R removeUsersByIds(@ApiParam(value = "主键集合", required = true) @RequestParam String ids) {
        return R.status(saveUserInfoByProject.deleteLogic(Func.toLongList(ids)));
    }

    /**
     * 重置密码
     */
    @PostMapping("/resetPasswordByUserId")
    @ApiOperationSupport(order = 15)
    @ApiOperation(value = "重置密码", notes = "传入当前用户的userId，默认重置密码123456")
    public R updatePasswordByUserId(@ApiParam(value = "用户userId", required = true) @RequestParam String userId) {
        if (StringUtils.isNotEmpty(userId)) {
            return iUserClient.resetPassword(userId);
        }
        return R.fail("操作失败");
    }


    /**
     * 分配合同段wbs节点树保存或者修改
     */
    @PostMapping("/submitWbsTreeInContract")
    @ApiOperationSupport(order = 16)
    @ApiOperation(value = "分配合同段wbs节点树保存或修改", notes = "传入ids,wbsId,项目id,合同段id")
    public R submitWbsTreeInContract(@RequestBody WbsTreeContractDTO wbsTreeContractDTO) {
        boolean b = wbsTreeContractService.submitWbsTreeInContract(wbsTreeContractDTO);
        if (b) {
            return R.success("关联合同段树成功");
        }
        return R.fail("关联合同段树失败");
    }

    /**
     * 查询合同段私有Wbs节点树形结构
     */
    @GetMapping("/tree")
    @ApiOperationSupport(order = 17)
    @ApiOperation(value = "查询合同段私有Wbs节点树形结构", notes = "传入wbsId,项目id,合同段id")
    @ApiImplicitParams(value = {
            @ApiImplicitParam(name = "wbsId", value = "wbsId", required = true),
            @ApiImplicitParam(name = "项目id", value = "projectId", required = true),
            @ApiImplicitParam(name = "合同段id", value = "contractId", required = true)
    })
    public R saveWbsTreeInContract(String wbsId, String projectId, String contractId) {
        List<WbsTreeContractTreeVO> tree = contractInfoService.tree(wbsId, projectId, contractId);
        if (tree != null && tree.size() > 0) {
            return R.data(tree);
        }
        return R.fail(200, "未查询到信息");
    }


}
