package com.template.controller;


import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.template.api.SmartDepartmentControllerAPI;
import com.template.common.utils.*;
import com.template.config.ControlConfig;
import com.template.model.pojo.SmartDepartment;
import com.template.model.request.insertDepartmentRequest;
import com.template.model.request.updateDepartmentRequest;
import com.template.model.result.CommonResult;
import com.template.model.result.PageUtils;
import com.template.model.vo.*;
import com.template.services.SmartDepartmentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindingResult;

import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import static com.template.common.utils.AesTestOne.decrypt;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author ceshi
 * @since 2023-12-04
 */
@RestController
public class SmartDepartmentController implements SmartDepartmentControllerAPI {

    @Resource
    private ControlConfig controlConfig;

    @Autowired
    private SmartDepartmentService smartDepartmentService;

    /**
     * 新增部门
     *
     * @param smartDepartment    部门数据
     * @param bindingResult
     * @return
     */
    @Override
    public CommonResult insertSmartDepartment(insertDepartmentRequest smartDepartment, BindingResult bindingResult) throws Exception {
        if (bindingResult.hasErrors()) {
            String st = paramUtils.getParamError(bindingResult);
            return CommonResult.fail(st);
        }

        //新增的时候判断是否存在重复部门名称数据
        int exist = smartDepartmentService.existDataByName(smartDepartment.getName());
        if (exist > 0) {

            return CommonResult.fail(smartDepartment.getName() + "部门名称数据已存在，请勿重复添加！");
        }

        SmartDepartment sd = new SmartDepartment();
        sd.setParentId(smartDepartment.getParentId());
        sd.setName(smartDepartment.getName());

        //region 百胜添加教师数据
        String appId = controlConfig.getAppId();
        String schoolno = controlConfig.getSchoolCode();
        String timestamp = TimeExchange.DateNowTimeStamo();
        String appSecret = controlConfig.getAppSecret();
        String url = controlConfig.getUrl() + "department/create";

        JSONObject jsonobject = new JSONObject();
        jsonobject.put("appid", appId);
        String str = "{\"department_name\":\"" + smartDepartment.getName() + "\"}";
        String aesStr = URLEncoder.encode(AesTestOne.encrypt(str, controlConfig.getAppSecret()), "UTF-8");
        jsonobject.put("data", aesStr);
        jsonobject.put("schoolno", schoolno);
        jsonobject.put("timestamp", timestamp);

        String md5Str = "appid=" + appId + "&data={\"department_name\":\"" + smartDepartment.getName() + "\"}" + "&schoolno=" + schoolno + "&timestamp=" + timestamp + "&key=" + appSecret;
        String sign = CommonUtil.MD5(md5Str);
        //sign签名
        jsonobject.put("sign", sign);

        //返回的结果中 code为1表示成功
        String bsResult = RequestUtils.httpPost(url, jsonobject.toJSONString());

        if (bsResult.contains("添加成功")) {
            ObjectMapper objectMapper = new ObjectMapper();
            BsDepartmentVo department = objectMapper.readValue(bsResult, BsDepartmentVo.class);

            // URL解码
            String decodedUrl = URLDecoder.decode(department.getData(), "UTF-8");

            BsDepartmentNoVo departmentData = objectMapper.readValue(decrypt(decodedUrl, controlConfig.getAppSecret()), BsDepartmentNoVo.class);
            sd.setBsDepartmentNo(departmentData.getDepartment_no());
        }
        //endregion

        int result = smartDepartmentService.insertSmartDepartment(sd);

        return result > 0 ? CommonResult.ok("添加成功") : CommonResult.fail("添加失败");
    }

    /**
     * 更新部门
     *
     * @param udr            部门数据
     * @param bindingResult
     * @return
     */
    @Override
    public CommonResult updateSmartDepartmentById(updateDepartmentRequest udr, BindingResult bindingResult) throws Exception {
        if (bindingResult.hasErrors()) {
            String st = paramUtils.getParamError(bindingResult);
            return CommonResult.fail(st);
        }

        SmartDepartment oldData = smartDepartmentService.getSmartById(udr.getId());
        if(oldData == null){
            return CommonResult.fail("部门数据无效，修改失败");
        }

        SmartDepartment exist = smartDepartmentService.getSmartByName(udr.getName());
        if (exist != null && !exist.getId().equals(udr.getId())) {
            return CommonResult.fail(udr.getName() + "部门名称数据已存在，请勿重复添加！");
        }

        SmartDepartment sd = new SmartDepartment();
        sd.setId(udr.getId());
        sd.setParentId(udr.getParentId());
        sd.setName(udr.getName());

        //region 百胜添加教师数据
        String appId = controlConfig.getAppId();
        String schoolno = controlConfig.getSchoolCode();
        String timestamp = TimeExchange.DateNowTimeStamo();
        String appSecret = controlConfig.getAppSecret();
        String url = controlConfig.getUrl() + "department/update";

        JSONObject jsonobject = new JSONObject();
        jsonobject.put("appid", appId);
        String str = "{\"department_no\":\"" + oldData.getBsDepartmentNo() + "\"department_name\":\"" + udr.getName() + "\"}";
        String aesStr = URLEncoder.encode(AesTestOne.encrypt(str, controlConfig.getAppSecret()), "UTF-8");
        jsonobject.put("data", aesStr);
        jsonobject.put("schoolno", schoolno);
        jsonobject.put("timestamp", timestamp);

        String md5Str = "appid=" + appId + "&data={\"department_no\":\"" + oldData.getBsDepartmentNo() + "\"department_name\":\"" + udr.getName() + "\"}" + "&schoolno=" + schoolno + "&timestamp=" + timestamp + "&key=" + appSecret;
        String sign = CommonUtil.MD5(md5Str);
        //sign签名
        jsonobject.put("sign", sign);

        //返回的结果中 code为1表示成功
        String bsResult = RequestUtils.httpPost(url, jsonobject.toJSONString());

        if (bsResult.contains("添加成功")) {
            ObjectMapper objectMapper = new ObjectMapper();
            BsDepartmentVo department = objectMapper.readValue(bsResult, BsDepartmentVo.class);

            // URL解码
            String decodedUrl = URLDecoder.decode(department.getData(), "UTF-8");

            BsDepartmentNoVo departmentData = objectMapper.readValue(decrypt(decodedUrl, controlConfig.getAppSecret()), BsDepartmentNoVo.class);
            sd.setBsDepartmentNo(departmentData.getDepartment_no());
        }
        //endregion

        int result = smartDepartmentService.updateSmartDepartment(sd);
        return result > 0 ? CommonResult.ok("修改成功") : CommonResult.fail("修改失败");
    }

    /**
     * 部门分页数据查询
     *
     * @param currentPage 当前页数
     * @param pageCount   一页数据条数
     * @param name        查询名称
     * @return
     */
    @Override
    public CommonResult queryPageSmartDepartments(int currentPage, int pageCount, String name) {
        PageUtils<SmartDepartment> result = smartDepartmentService.queryPageSmartDepartments(currentPage, pageCount, name);

        return CommonResult.ok(result);
    }


    @Override
    public CommonResult deleteSmartDepartmentById(int id) {

        SmartDepartment data = smartDepartmentService.getSmartById(id);

        if (data == null) {
            return CommonResult.fail("当前数据不存在，删除失败！");
        }

        int result = smartDepartmentService.deleteSmartDepartmentById(id);

        return result > 0 ? CommonResult.ok("删除成功") : CommonResult.fail("删除失败");
    }

    /**
     * 根据部门名称查询部门树形图结构数据
     *
     * @param name 部门名称
     * @return
     */
    @Override
    public CommonResult queryDepartmentTree(String name) {
        List<SmartDepartment> result = smartDepartmentService.getSmartsByName(name);

        List<SmartDepartment> zeroResult = result.stream().filter(e -> e.getParentId().intValue() == 0).collect(Collectors.toList());
        List<DepartmentTreeVo> departments = new ArrayList<>();
        if (ObjectUtils.isEmpty(name)) {
            for (SmartDepartment data : zeroResult) {
                DepartmentTreeVo newData = new DepartmentTreeVo().builder()
                        .id(data.getId())
                        .name(data.getName())
                        .parentId(data.getParentId())
                        .build();

                List<DepartmentTreeVo> departmentTrees = QueryDepartmentTreeRecords(newData.getId(), result);
                newData.setChildren(departmentTrees);
                departments.add(newData);
            }
        } else {
            for (SmartDepartment data : result) {
                DepartmentTreeVo newData = new DepartmentTreeVo().builder()
                        .id(data.getId())
                        .name(data.getName())
                        .parentId(data.getParentId())
                        .build();
                departments.add(newData);
            }
        }

        return CommonResult.ok(departments);
    }

    /**
     * 根据父级ID获取树形数据
     *
     * @param parentID 父级ID
     * @param lists    数据集合
     * @return
     */
    private List<DepartmentTreeVo> QueryDepartmentTreeRecords(Integer parentID, List<SmartDepartment> lists) {
        List<DepartmentTreeVo> newTrees = new ArrayList<>();

        List<SmartDepartment> datas = lists.stream().filter(e -> e.getParentId().equals(parentID)).collect(Collectors.toList());

        for (SmartDepartment data : datas) {
            DepartmentTreeVo item = DepartmentTreeVo.builder()
                    .id(data.getId())
                    .parentId(parentID)
                    .name(data.getName())
                    .build();
            List<DepartmentTreeVo> news = QueryDepartmentTreeRecords(item.getId(), lists);
            if (news == null || news.size() == 0) {
                newTrees.add(item);
                continue;
            } else {
                item.setChildren(news);
                newTrees.add(item);
            }
        }

        return newTrees;
    }
}

