package com.template.controller;


import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.seewo.open.sdk.DefaultSeewoClient;
import com.seewo.open.sdk.SeewoClient;
import com.seewo.open.sdk.auth.Account;
import com.template.api.SmartClassControllerAPI;
import com.template.common.utils.*;
import com.template.config.ControlConfig;
import com.template.config.SeewoConfig;
import com.template.model.pojo.*;
import com.template.model.request.insertSmartClassRequest;
import com.template.model.request.updateClassRequest;
import com.template.model.result.CommonResult;
import com.template.model.result.PageUtils;
import com.template.model.seewo.*;
import com.template.model.vo.*;
import com.template.services.SmartClassService;
import com.template.services.SmartGradeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
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.Optional;

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

/**
 * <p>
 * 楼栋表 前端控制器
 * </p>
 *
 * @author ceshi
 * @since 2023-12-25
 */
@RestController
public class SmartClassController implements SmartClassControllerAPI {

    @Resource
    private SeewoConfig seewoConfig;
    @Resource
    private ControlConfig controlConfig;
    @Autowired
    private SmartClassService smartClassService;
    @Autowired
    private SmartGradeService smartGradeService;

    @Override
    public CommonResult insertSmartClass(SmartClass smartApply, BindingResult bindingResult) {
        return null;
    }

    @Override
    public CommonResult updateSmartClassById(updateClassRequest ucr, BindingResult bindingResult) throws Exception {
        if (bindingResult.hasErrors()) {
            String st = paramUtils.getParamError(bindingResult);
            return CommonResult.fail(st);
        }

        //数据ID是否有效
        SmartClass oldData = smartClassService.querySmartClassById(ucr.getId());
        if (oldData == null) {
            return CommonResult.fail("班级数据无效，更新失败");
        }

        //判断重复性
        SmartClass existData = smartClassService.existSmartClassData(oldData.getGradeId(), ucr.getName(), ucr.getClassNo());
        if (existData != null && !existData.getId().equals(ucr.getId())) {
            return CommonResult.fail("该班级数据已在系统中存在，更新失败");
        }

        //region 修改百胜中的班级数据
        String appId = controlConfig.getAppId();
        String schoolno = controlConfig.getSchoolCode();
        String timestamp = TimeExchange.DateNowTimeStamo();
        String className = ucr.getName();
        String appSecret = controlConfig.getAppSecret();
        String url = controlConfig.getUrl() + "classtab/update";

        JSONObject jsonobject = new JSONObject();
        jsonobject.put("appid", appId);
        String str = "{\"classtab_no\":\"" + oldData.getBsClassNo() + "\",\"classtab_name\":\"" + oldData.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={\"classtab_no\":\"" + oldData.getBsClassNo() + "\",\"classtab_name\":\"" + oldData.getName() + "\"}" + "&schoolno=" + schoolno + "&timestamp=" + timestamp + "&key=" + appSecret;
        String sign = CommonUtil.MD5(md5Str);
        //sign签名
        jsonobject.put("sign", sign);

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

        if (result.contains("更新成功")) {
            oldData.setClassNo(ucr.getClassNo());
            oldData.setName(ucr.getName());
            int updateClass = smartClassService.updateSmartClass(oldData);

            if (updateClass <= 0) {
                return CommonResult.fail("班级信息更新失败");
            }
        } else {
            return CommonResult.fail("班级信息更新失败");
        }
        //endregion

        return CommonResult.ok("班级信息更新成功");
    }

    @Override
    public CommonResult queryPageSmartClasss(int currentPage, int pageCount, String name) {
        PageUtils<SmartClass> result = smartClassService.queryPageSmartClass(currentPage, pageCount, name);

        PageUtils<SmartClassPageVo> datas = new PageUtils<SmartClassPageVo>(null, result.getTotalCount(),result.getPageSize(),result.getCurrPage());

        if(result != null && result.getList().size() > 0){
            List<SmartGrade> grades = smartGradeService.getSmartGrades();
            List<SmartClassPageVo> pages = new ArrayList<>();
            for (SmartClass data : result.getList()) {
                SmartClassPageVo pageData = new SmartClassPageVo();
                pageData.setId(data.getId());
                pageData.setGradeId(data.getGradeId());
                Optional<SmartGrade> grade = grades.stream().filter(e -> e.getId().equals(data.getGradeId())).findFirst();
                if(grade != null && grade.isPresent()){
                    pageData.setGradeStr(grade.get().getName());
                }
                pageData.setClassUid(data.getClassUid());
                pageData.setName(data.getName());
                pageData.setClassNo(data.getClassNo());
                pageData.setBsClassNo(data.getBsClassNo());
                pages.add(pageData);
            }

            datas = new PageUtils<SmartClassPageVo>(pages, result.getTotalCount(),result.getPageSize(),result.getCurrPage());
        }

        return CommonResult.ok(datas);
    }

    @Override
    public CommonResult deleteSmartClassById(int id) {
        return null;
    }

    @Override
    public CommonResult querySmartClasss(int gradeId) {
        List<SmartClass> datas = smartClassService.getSmartClassByGradeID(gradeId);
        List<SemesterVo> result = new ArrayList<>();
        for (SmartClass data : datas) {
            SemesterVo model = new SemesterVo();
            model.setId(data.getId());
            model.setName(data.getName());
            result.add(model);
        }
        return CommonResult.ok(result);
    }

    @Override
    @Transactional(rollbackFor = {Exception.class})
    public CommonResult insertSmartClassToBaisheng(insertSmartClassRequest iscr, BindingResult bindingResult) throws Exception {
        if (bindingResult.hasErrors()) {
            String st = paramUtils.getParamError(bindingResult);
            return CommonResult.fail(st);
        }

        //先查找年级编号对应的年级数据是否存在
        SmartGrade grade = smartGradeService.querySmartGradeByBaisheng(iscr.getGradeNo());
        if (grade == null) {
            return CommonResult.fail("添加班级前，请先添加对应年级数据");
        }

        //判断重复性
        int existCount = smartClassService.existSmartClass(iscr.getClassName(), grade.getId());
        if (existCount > 0) {
            return CommonResult.fail("该班级数据已在系统中存在，请勿重复添加");
        }

        String appId = controlConfig.getAppId();
        String schoolno = controlConfig.getSchoolCode();
        String timestamp = TimeExchange.DateNowTimeStamo();
        String className = iscr.getClassName();
        String gradeNo = iscr.getGradeNo();
        String appSecret = controlConfig.getAppSecret();
        String url = controlConfig.getUrl() + "classtab/create";

        JSONObject jsonobject = new JSONObject();
        jsonobject.put("appid", appId);
        String str = "{\"grade_no\":\"" + gradeNo + "\",\"classtab_name\":\"" + grade.getName() + className + "\"}";
        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={\"grade_no\":\"" + gradeNo + "\",\"classtab_name\":\"" + grade.getName() + className + "\"}" + "&schoolno=" + schoolno + "&timestamp=" + timestamp + "&key=" + appSecret;
        String sign = CommonUtil.MD5(md5Str);
        //sign签名
        jsonobject.put("sign", sign);

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

        if (result.contains("添加成功")) {

            //region 将K12校区的班级数据初始化
            //希沃班级传输特点：
            //当前月份小于9月份就传当前年份 - 1 ；如果大于9月份就传当前年份
            Integer nowMonth = Integer.valueOf(TimeExchange.getNowMonth());
            //初始化客户端
            SeewoClient seewoClient = new DefaultSeewoClient(new Account(seewoConfig.getAppId(), seewoConfig.getAppSecret()));
            OrganizationNodeServiceInitSchoolClassesParam kParam = new OrganizationNodeServiceInitSchoolClassesParam();
            //响应体，MimeType为 application/json
            OrganizationNodeServiceInitSchoolClassesParam.RequestBody kRequestBody = OrganizationNodeServiceInitSchoolClassesParam.RequestBody.builder()
                    .build();
            kParam.setRequestBody(kRequestBody);
            //query
            OrganizationNodeServiceInitSchoolClassesParam.Query kQuery = OrganizationNodeServiceInitSchoolClassesParam.Query.builder()
                    .appId(seewoConfig.getAppId())
                    .unitUid(seewoConfig.getSchoolId())
                    .campusName("宜阳学校")
                    .build();
            kRequestBody.setQuery(kQuery);
            //新增班级列表(最大200条)
            OrganizationNodeServiceInitSchoolClassesParam.Object kClassList = OrganizationNodeServiceInitSchoolClassesParam.Object.builder()
                    .stageName("初中")
                    .gradeYear(nowMonth < 9 ? Integer.valueOf(TimeExchange.getYear()).intValue() - 1 : Integer.valueOf(TimeExchange.getYear()))
                    .build();
            kQuery.setClassList(java.util.Collections.singletonList(kClassList));
            kParam.setRequestBody(kRequestBody);
            OrganizationNodeServiceInitSchoolClassesRequest kRequest = new OrganizationNodeServiceInitSchoolClassesRequest(kParam);
            System.out.println("入参：" + kRequest);
            //如果想要调用沙箱环境，请通过设置 request 对象的 serverUrl 属性，如：
            //request.setServerUrl("https://openapi.test.seewo.com")
            //执行请求，如果想获取到com.seewo.open.sdk.HttpResponse对象，请调用 seewoClient.execute 方法
            OrganizationNodeServiceInitSchoolClassesResult kResult = seewoClient.invoke(kRequest);
            System.out.println("出参：" + kResult);
            //endregion


            //region 将数据加入希沃系统中
            //初始化客户端
            //SeewoClient seewoClient = new DefaultSeewoClient(new Account(seewoConfig.getAppId(), seewoConfig.getAppSecret()));
            ClassServiceBatchSaveClassParam param = new ClassServiceBatchSaveClassParam();
            //请求体，MimeType为 application/json
            ClassServiceBatchSaveClassParam.JSONRequestBody requestBody = ClassServiceBatchSaveClassParam.JSONRequestBody.builder()
                    .build();
            param.setRequestBody(requestBody);
            //查询条件
            ClassServiceBatchSaveClassParam.ClassSaveQuery query = ClassServiceBatchSaveClassParam.ClassSaveQuery.builder()
                    .appId(seewoConfig.getAppId())
                    .schoolUid(seewoConfig.getSchoolId())
                    .build();
            requestBody.setQuery(query);

            //班级信息列表
            ClassServiceBatchSaveClassParam.ClassInfo classList = ClassServiceBatchSaveClassParam.ClassInfo.builder()
                    .stageCode("CodeSchoolStage_1")
                    .clazz(iscr.getClassNo())
                    .nickName(iscr.getClassName())
                    .grade(grade.getGradeNo())
                    .gradeYear(nowMonth < 9 ? Integer.valueOf(TimeExchange.getYear()).intValue() - 1 : Integer.valueOf(TimeExchange.getYear()))
                    .build();
            query.setClassList(java.util.Collections.singletonList(classList));
            param.setRequestBody(requestBody);
            ClassServiceBatchSaveClassRequest request = new ClassServiceBatchSaveClassRequest(param);
            System.out.println("入参：" + request);
            //如果想要调用沙箱环境，请通过设置 request 对象的 serverUrl 属性，如：
            // request.setServerUrl("https://openapi.test.seewo.com")
            //执行请求，如果想获取到com.seewo.open.sdk.HttpResponse对象，请调用 seewoClient.execute 方法
            ClassServiceBatchSaveClassResult xwResult = seewoClient.invoke(request);
            System.out.println("出参：" + xwResult);

            if (xwResult == null) {
                return CommonResult.fail("希沃班级数据新增失败！");
            }

            if (!xwResult.getResponseBody().getCode().equals("000000")) {
                return CommonResult.fail(xwResult.getResponseBody().getMessage());
            }
            //endregion

            //希沃添加年级和班级数据是：存在就覆盖 不存在就新增
            //要拿到希沃的年级Uid和班级Uid
            String gradeUid = xwResult.getResponseBody().getData().get(0).getGradeUid();
            String classUid = xwResult.getResponseBody().getData().get(0).getUid();

            ObjectMapper objectMapper = new ObjectMapper();
            BsClassVo classVo = objectMapper.readValue(result, BsClassVo.class);

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

            BsClassNoVo classNo = objectMapper.readValue(decrypt(decodedUrl, controlConfig.getAppSecret()), BsClassNoVo.class);

            if (classNo == null) {
                return CommonResult.fail("百胜班级编号为空，新增失败");
            }

            SmartClass smartClass = new SmartClass();
            smartClass.setGradeId(grade.getId());
            smartClass.setClassUid(classUid);
            smartClass.setName(iscr.getClassName());
            smartClass.setClassNo(iscr.getClassNo());
            smartClass.setBsClassNo(classNo.getClasstab_no());

            grade.setGradeUid(gradeUid);

            try {
                int insertClass = smartClassService.insertSmartClass(smartClass);
                if (insertClass <= 0) {
                    throw new Exception("新增失败");
                }

                int updateGrade = smartGradeService.updateSmartGrade(grade);
                if (updateGrade <= 0) {
                    throw new Exception("新增失败");
                }

            } catch (Exception e) {
                throw new Exception("新增失败");
            }

            return CommonResult.ok("新增成功");

        }

        return CommonResult.fail("操作失败");

    }

    @Override
    public CommonResult insertTestClassToXw(insertSmartClassRequest iscr, BindingResult bindingResult) throws Exception {

        if (bindingResult.hasErrors()) {
            String st = paramUtils.getParamError(bindingResult);
            return CommonResult.fail(st);
        }

        //先查找年级编号对应的年级数据是否存在
        SmartGrade grade = smartGradeService.querySmartGradeByBaisheng(iscr.getGradeNo());
        if (grade == null) {
            return CommonResult.fail("添加班级前，请先添加对应年级数据");
        }

        //判断重复性
        int existCount = smartClassService.existSmartClass(iscr.getClassName(), grade.getId());
        if (existCount > 0) {
            return CommonResult.fail("该班级数据已在系统中存在，请勿重复添加");
        }

        //希沃班级传输特点：
        //当前月份小于9月份就传当前年份 - 1 ；如果大于9月份就传当前年份
        Integer nowMonth = Integer.valueOf(TimeExchange.getNowMonth());

        //region 将数据加入希沃系统中
        //初始化客户端
        SeewoClient seewoClient = new DefaultSeewoClient(new Account(seewoConfig.getAppId(), seewoConfig.getAppSecret()));
        ClassServiceBatchSaveClassParam param = new ClassServiceBatchSaveClassParam();
        //请求体，MimeType为 application/json
        ClassServiceBatchSaveClassParam.JSONRequestBody requestBody = ClassServiceBatchSaveClassParam.JSONRequestBody.builder()
                .build();
        param.setRequestBody(requestBody);
        //查询条件
        ClassServiceBatchSaveClassParam.ClassSaveQuery query = ClassServiceBatchSaveClassParam.ClassSaveQuery.builder()
                .appId(seewoConfig.getAppId())
                .schoolUid(seewoConfig.getSchoolId())
                .build();
        requestBody.setQuery(query);

        //班级信息列表
        ClassServiceBatchSaveClassParam.ClassInfo classList = ClassServiceBatchSaveClassParam.ClassInfo.builder()
                .stageCode("CodeSchoolStage_1")
                .clazz(iscr.getClassNo())
                .nickName(iscr.getClassName())
                .grade(grade.getGradeNo())
                .gradeYear(nowMonth < 9 ? Integer.valueOf(TimeExchange.getYear()).intValue() - 1 : Integer.valueOf(TimeExchange.getYear()))
                .build();
        query.setClassList(java.util.Collections.singletonList(classList));
        param.setRequestBody(requestBody);
        ClassServiceBatchSaveClassRequest request = new ClassServiceBatchSaveClassRequest(param);
        System.out.println("入参：" + request);
        //如果想要调用沙箱环境，请通过设置 request 对象的 serverUrl 属性，如：
        // request.setServerUrl("https://openapi.test.seewo.com")
        //执行请求，如果想获取到com.seewo.open.sdk.HttpResponse对象，请调用 seewoClient.execute 方法
        ClassServiceBatchSaveClassResult xwResult = seewoClient.invoke(request);
        System.out.println("出参：" + xwResult);

        if (xwResult == null) {
            return CommonResult.fail("希沃班级数据新增失败！");
        }

        if (!xwResult.getResponseBody().getCode().equals("000000")) {
            return CommonResult.fail(xwResult.getResponseBody().getMessage());
        }
        //endregion

        //希沃添加年级和班级数据是：存在就覆盖 不存在就新增
        //要拿到希沃的年级Uid和班级Uid
        String gradeUid = xwResult.getResponseBody().getData().get(0).getGradeUid();
        String classUid = xwResult.getResponseBody().getData().get(0).getUid();

        SmartClass smartClass = new SmartClass();
        smartClass.setGradeId(grade.getId());
        smartClass.setClassUid(classUid);
        smartClass.setName(iscr.getClassName());
        smartClass.setClassNo(iscr.getClassNo());
        smartClass.setBsClassNo("bs");

        grade.setGradeUid(gradeUid);

        try {
            int insertClass = smartClassService.insertSmartClass(smartClass);
            if (insertClass <= 0) {
                throw new Exception("新增失败");
            }

            int updateGrade = smartGradeService.updateSmartGrade(grade);
            if (updateGrade <= 0) {
                throw new Exception("新增失败");
            }

        } catch (Exception e) {
            throw new Exception("新增失败");
        }

        return CommonResult.ok("新增成功");
    }


    @Override
    public CommonResult initSchoolClasses() {
        //初始化客户端
        SeewoClient seewoClient = new DefaultSeewoClient(new Account(seewoConfig.getAppId(), seewoConfig.getAppSecret()));
        OrganizationNodeServiceInitSchoolClassesParam param = new OrganizationNodeServiceInitSchoolClassesParam();
        //响应体，MimeType为 application/json
        OrganizationNodeServiceInitSchoolClassesParam.RequestBody requestBody = OrganizationNodeServiceInitSchoolClassesParam.RequestBody.builder()
                .build();
        param.setRequestBody(requestBody);
        //query
        OrganizationNodeServiceInitSchoolClassesParam.Query query = OrganizationNodeServiceInitSchoolClassesParam.Query.builder()
                .appId(seewoConfig.getAppId())
                .unitUid(seewoConfig.getSchoolId())
                .campusName("宜阳学校")
                .build();
        requestBody.setQuery(query);
        //新增班级列表(最大200条)
        OrganizationNodeServiceInitSchoolClassesParam.Object classList = OrganizationNodeServiceInitSchoolClassesParam.Object.builder()
                .stageName("初中")
                .gradeYear(2022)
                .build();
        query.setClassList(java.util.Collections.singletonList(classList));
        param.setRequestBody(requestBody);
        OrganizationNodeServiceInitSchoolClassesRequest request = new OrganizationNodeServiceInitSchoolClassesRequest(param);
        System.out.println("入参：" + request);
        //如果想要调用沙箱环境，请通过设置 request 对象的 serverUrl 属性，如：
        //request.setServerUrl("https://openapi.test.seewo.com")
        //执行请求，如果想获取到com.seewo.open.sdk.HttpResponse对象，请调用 seewoClient.execute 方法
        OrganizationNodeServiceInitSchoolClassesResult result = seewoClient.invoke(request);
        System.out.println("出参：" + result);

        return null;
    }
}

