package com.ruoyi.web.controller.ie;

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.NumberUtils;
import com.ruoyi.common.utils.PageUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.ie.service.IAWishRecordService;
import com.ruoyi.syzy.service.IBBusiWishLocationSubmitsService;
import com.ruoyi.web.domain.Constant;
import com.ruoyi.web.domain.VoluntaryDto;
import com.ruoyi.web.service.CommService;
import com.ruoyi.web.service.VoluntaryService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@RestController
@Api(tags = "志愿-单招")
public class VoluntaryController extends BaseController {
    private final VoluntaryService voluntaryService;
    private final IAWishRecordService aWishRecordService;
    private final IBBusiWishLocationSubmitsService busiWishLocationSubmitsService;
    private final CommService commService;

    public VoluntaryController(VoluntaryService voluntaryService, IAWishRecordService aWishRecordService, IBBusiWishLocationSubmitsService busiWishLocationSubmitsService, CommService commService) {
        this.voluntaryService = voluntaryService;
        this.aWishRecordService = aWishRecordService;
        this.busiWishLocationSubmitsService = busiWishLocationSubmitsService;
        this.commService = commService;
    }

    @PostMapping("getAIRenderRules")
    @ApiOperation("查询规则")
    public R<List<VoluntaryDto.AIRenderRule>> getAIRenderRules(@RequestBody VoluntaryDto.AIRenderRequest req) {
        return voluntaryService.getAIRenderRules(req);
    }

    @PostMapping("voluntary/getRenderRules")
    @ApiOperation("查询志愿规则")
    public R<List<VoluntaryDto.RenderRule>> getRenderRules(@RequestBody VoluntaryDto.RenderRequest req) {
        req.setRenderType(0);
        return voluntaryService.getRenderRules(req);
    }

    @PostMapping("voluntary/getSkillRules")
    @ApiOperation("查询技能分规则")
    public R<List<VoluntaryDto.RenderRule>> getSkillRules(@RequestBody VoluntaryDto.RenderRequest req) {
        req.setRenderType(2);
        return voluntaryService.getRenderRules(req);
    }

    @PostMapping("/voluntary/postRenderRules")
    @ApiOperation("单院校专业结果")
    public R<VoluntaryDto.RenderMajorResult> postRenderRules(@RequestBody String data) {
        commService.requireVip();
        VoluntaryDto.SingleRequest req = new VoluntaryDto.SingleRequest();
        JSONObject root = JSONObject.parseObject(data);
        Map<String, String> form = req.getForm();
        for(String key : root.keySet()) {
            JSONObject sub = root.getJSONObject(key);
            for (String field : sub.keySet()) {
                form.put(field, sub.getString(field));
            }
        }
        req.setUniversityCode(form.remove("universityId"));
        req.setMajorEnrollCode(form.remove("majorId"));
        return voluntaryService.postRenderResult(req, false);
    }

    @PostMapping("/voluntary/postSkillRules")
    @ApiOperation("单院校专业结果")
    public R<VoluntaryDto.RenderMajorResult> postSkillRules(@RequestBody String data) {
        commService.requireVip();
        VoluntaryDto.SingleRequest req = new VoluntaryDto.SingleRequest();
        JSONObject root = JSONObject.parseObject(data);
        Map<String, String> form = req.getForm();
        for(String key : root.keySet()) {
            JSONObject sub = root.getJSONObject(key);
            for (String field : sub.keySet()) {
                form.put(field, sub.getString(field));
            }
        }
        req.setUniversityCode(form.remove("universityId"));
        req.setMajorEnrollCode(form.remove("majorId"));
        return voluntaryService.postRenderResult(req, true);
    }

    @GetMapping("voluntary/getVoluntaryList")
    @ApiOperation("查询志愿列表")
    public R<List<VoluntaryDto.VoluntaryRecord>> voluntaryList() { // 我的志愿表 // 后台填充快照缺省
        List<VoluntaryDto.VoluntaryRecord> list = voluntaryService.getVoluntaryList2();
        return R.ok(list);
    }

    @PostMapping("voluntary/addVoluntary")
    @ApiOperation("填报志愿")
    public R<Long> addVoluntary(@RequestBody String body) { // 填报 // 前端+后台按需要剔除一些不需快照的信息（目前主要是院校信息）
        commService.requireVip();
        JSONObject model = JSONObject.parseObject(body);
        return voluntaryService.addVoluntary2(model);
    }

    @Log(title = "志愿删除院校", businessType = BusinessType.DELETE)
    @PostMapping("voluntary/removeVoluntaryByUniversity/{universityId}")
    public AjaxResult removeVoluntaryByUniversity(@PathVariable Long universityId)
    {
        return toAjax(voluntaryService.removeVoluntaryByUniversity(SecurityUtils.getLoginUser().getUserId(), universityId));
    }

    @Log(title = "志愿删除专业", businessType = BusinessType.DELETE)
    @PostMapping("voluntary/removeVoluntaryByMajor/{majorId}")
    public AjaxResult removeVoluntaryByMajor(@PathVariable Long majorId)
    {
        return toAjax(voluntaryService.removeVoluntaryByMajor(SecurityUtils.getLoginUser().getUserId(), majorId));
    }

    @PostMapping("voluntary/sortVoluntaryByMajor")
    @ApiOperation("志愿专业排序")
    public R sortVoluntaryByMajor(@RequestBody String body) { // 填报 // 前端+后台按需要剔除一些不需快照的信息（目前主要是院校信息）
        JSONObject model = JSONObject.parseObject(body);
        JSONArray list = model.getJSONArray("majorIdList");
        Map<Long, Integer> majorRankMap = Maps.newHashMap();
        for (int i = 0; i < list.size(); i++) {
            majorRankMap.put(list.getLong(i), i);
        }
        voluntaryService.sortVoluntaryByMajor(SecurityUtils.getUserId(), model.getLong("universityId"), majorRankMap);
        return R.ok();
    }

    @PostMapping("voluntary/sortVoluntaryByUniversity")
    @ApiOperation("志愿院校排序")
    public R sortVoluntaryByUniversity(@RequestBody String body) { // 填报 // 前端+后台按需要剔除一些不需快照的信息（目前主要是院校信息）
        JSONObject model = JSONObject.parseObject(body);
        JSONArray list = model.getJSONArray("universityIdList");
        Map<Long, Integer> universityRankMap = Maps.newHashMap();
        for (int i = 0; i < list.size(); i++) {
            universityRankMap.put(list.getLong(i), i);
        }
        voluntaryService.sortVoluntaryByUniversity(SecurityUtils.getUserId(), universityRankMap);
        return R.ok();
    }




    @PostMapping("postSingleResultSample")
    @ApiOperation("单院校专业结果")
    public R<VoluntaryDto.SingleResponse> postSingleResultSample(@RequestBody VoluntaryDto.SingleRequest req) {
        return R.ok();
    }

    @PostMapping("postCalculateResult")
    @ApiOperation("技能分计算")
    public R<VoluntaryDto.SingleResponse> postCalculateResult(@RequestBody String data) {
        commService.requireVip();

        VoluntaryDto.SingleRequest req = new VoluntaryDto.SingleRequest();
        JSONObject root = JSONObject.parseObject(data);
        Map<String, String> form = req.getForm();
        for (String field : root.keySet()) {
            form.put(field, root.getString(field));
        }
        req.setUniversityCode(form.remove("universityCode"));
        req.setMajorCode(form.remove("majorCode"));
        req.setMajorEnrollCode(form.remove("majorEnrollCode"));
        return voluntaryService.postSingleResult(req, true);
    }

    @PostMapping("postSingleResult")
    @ApiOperation("单院校专业结果")
    public R<VoluntaryDto.SingleResponse> postSingleResult(@RequestBody String data) {
        commService.requireVip();

        VoluntaryDto.SingleRequest req = new VoluntaryDto.SingleRequest();
        JSONObject root = JSONObject.parseObject(data);
        Map<String, String> form = req.getForm();
        for (String field : root.keySet()) {
            form.put(field, root.getString(field));
        }
        req.setUniversityCode(form.remove("universityCode"));
        req.setMajorCode(form.remove("majorCode"));
        req.setMajorEnrollCode(form.remove("majorEnrollCode"));
        return voluntaryService.postSingleResult(req, false);
    }

    @PostMapping("postMultipleResultSample")
    @ApiOperation("多院校专业结果")
    public R<List<VoluntaryDto.SingleResponse>> postMultipleResultSample(@RequestBody VoluntaryDto.MultipleRequest req) {
        return R.ok();
    }

    @PostMapping("postMultipleResult")
    @ApiOperation("多院校专业结果")
    public R<List<VoluntaryDto.SingleResponse>> postMultipleResult(@RequestBody String data) {
        commService.requireVip();

        VoluntaryDto.MultipleRequest req = new VoluntaryDto.MultipleRequest();
        JSONObject root = JSONObject.parseObject(data);
        req.setMajorCategory(root.getString("majorCategory"));
        req.setUniversities(getCollegeMajor(root));
        root.remove("majorCategory");
        root.remove("universities");
        return voluntaryService.postMultipleResult(req, false);
    }

    private List<VoluntaryDto.CollegeMajorDto> getCollegeMajor(JSONObject root) {
        List<VoluntaryDto.CollegeMajorDto> universities = Lists.newArrayList();
        if (root.containsKey("universities")) {
            root.getJSONArray("universities").forEach(l -> {
                JSONObject lo = (JSONObject) l;
                VoluntaryDto.CollegeMajorDto cm = new VoluntaryDto.CollegeMajorDto();
                cm.setCode(lo.getString("code"));
                List<String> marjorCodeList = Lists.newArrayList();
                if(lo.containsKey("majorCodes")) {
                    lo.getJSONArray("majorCodes").forEach(lm -> {
                        marjorCodeList.add((String) lm);
                    });
                }
                cm.setMajorCodes(marjorCodeList);
                Map<String, String> form = cm.getForm();
                for (String field : lo.keySet()) {
                    form.put(field, lo.getString(field));
                }
                universities.add(cm);
            });
        }
        return universities;
    }

    @PostMapping("postAIResultSample")
    @ApiOperation("AI多院校专业结果")
    public TableDataInfo postAIResultSample(@RequestBody VoluntaryDto.AIRequest req) {
        return new TableDataInfo(Lists.newArrayList(), 0);
    }

    @PostMapping("postAIResult")
    @ApiOperation("AI多院校专业结果")
    public TableDataInfo postAIResult(@RequestBody String data) {
        commService.requireVip();

        VoluntaryDto.AIRequest req = new VoluntaryDto.AIRequest();
        JSONObject root = JSONObject.parseObject(data);
        req.setPageNum(root.getInteger("pageNum"));
        req.setPageSize(root.getInteger("pageSize"));
        req.setMajorCategory(root.getString("majorCategory"));
        req.setUniversities(getCollegeMajor(root));
        root.remove("pageNum");
        root.remove("pageSize");
        root.remove("majorCategory");
        root.remove("universities");

        VoluntaryDto.AIRequestFilter filter = req.getFilter();
        if (root.containsKey("filter")) {
            String tempValue;
            JSONObject filterObj = root.getJSONObject("filter");
            if (StringUtils.isNotBlank(tempValue = filterObj.getString("enumPickType"))) {
                try {
                    filter.setEnumPickType(VoluntaryDto.EnumPickType.valueOf(tempValue));
                } catch (IllegalArgumentException e) {

                }
            }
            if (StringUtils.isNotBlank(tempValue = filterObj.getString("enumPickEmpty"))) {
                try {
                    filter.setEnumPickEmpty(NumberUtils.isNumeric(tempValue) ? VoluntaryDto.EnumPickEmpty.values()[Integer.parseInt(tempValue)] : VoluntaryDto.EnumPickEmpty.valueOf(tempValue));
                } catch (IllegalArgumentException e) {

                }
            }
            if (filterObj.containsKey("hasClearing")) {
                filter.setHasClearing(filterObj.getBoolean("hasClearing")); // true: 仅看补录 false:不看补录 null:不限。默认null
            }
            if (filterObj.containsKey("majorTypes")) {
                filter.setMajorTypes(filterObj.getJSONArray("majorTypes").stream().map(t -> (String) t).collect(Collectors.toList()));
            }
            if (filterObj.containsKey("keyword")) {
                filter.setKeyword(filterObj.getString("keyword"));
            }
            if (filterObj.containsKey("level")) {
                filter.setLevel(filterObj.getJSONArray("level").stream().map(t -> (String) t).collect(Collectors.toList()));
            }
            if (filterObj.containsKey("type")) {
                filter.setType(filterObj.getJSONArray("type").stream().map(t -> (String) t).collect(Collectors.toList()));
            }
            if (filterObj.containsKey("natureTypeCN")) {
                filter.setNatureTypeCN(filterObj.getJSONArray("natureTypeCN").stream().map(t -> (String) t).collect(Collectors.toList()));
            }
            if (filterObj.containsKey("location")) {
                filter.setLocation(filterObj.getJSONArray("location").stream().map(t -> (String) t).collect(Collectors.toList()));
            }
            root.remove("filter");
        }
        Map<String, String> form = req.getForm();
        for (String field : root.keySet()) {
            form.put(field, root.getString(field));
        }
        return voluntaryService.postAIResult(req);
    }

    // 填报
    @GetMapping("getVoluntaryConfig")
    @ApiOperation("取填报配置信息")
    public R<VoluntaryDto.VoluntaryConfig> getVoluntaryConfig() { // 如果有填报配置相关，放在这里
        return voluntaryService.getVoluntaryConfig();
    }

    @GetMapping("getVoluntaryList")
    @ApiOperation("查询志愿列表")
    public TableDataInfo getVoluntaryList(@ApiParam @RequestParam(required = false) VoluntaryDto.EnumVoluntaryType type,
                                          @ApiParam @RequestParam Integer pageNum, @ApiParam @RequestParam Integer pageSize) { // 我的志愿表 // 后台填充快照缺省
        PageUtils.startPage(pageNum, pageSize);
        List<JSONObject> list = voluntaryService.getVoluntaryList(type);
        return getDataTable(list);
    }

    @PostMapping("submitVoluntary")
    @ApiOperation("填报志愿")
    public R<Long> submitVoluntary(@RequestBody String body) { // 填报 // 前端+后台按需要剔除一些不需快照的信息（目前主要是院校信息）
        JSONObject model = JSONObject.parseObject(body);
        return voluntaryService.submitVoluntary(model);
    }

    @GetMapping("getVoluntary")
    @ApiOperation("查询志愿详情")
    public R<JSONObject> getVoluntary(@ApiParam @RequestParam Long id) { // 志愿表详情 // 后台填充快照缺省
        return voluntaryService.getVoluntary(id);
    }

    @Log(title = "删除志愿记录", businessType = BusinessType.DELETE)
    @DeleteMapping("removeVoluntary/{id}")
    public AjaxResult remove(@PathVariable Long id)
    {
        Map cond = new HashMap();
        cond.put("userId", SecurityUtils.getLoginUser().getUserId());
        cond.put("id", id);
        return toAjax(aWishRecordService.deleteAWishRecordByMap(cond));
    }

    @GetMapping("getExamTypesNoToken")
    @ApiOperation("查询考生类型")
    public R<List<String>> getExamTypesNoToken(@RequestParam(required = false) String provinceName) {
        return getExamTypes(provinceName, null);
    }

    @GetMapping("getExamTypes")
    @ApiOperation("查询考生类型")
    public R<List<String>> getExamTypes(@RequestParam(required = false) String provinceName) {
        SysUser sysUser = SecurityUtils.getLoginUser().getUser();
        return getExamTypes(StringUtils.isNotBlank(provinceName) ? provinceName : sysUser.getLocation(), sysUser);
    }

    private R<List<String>> getExamTypes(String provinceName, SysUser sysUser) {
        List<String> examTypes;
        if(Constant.PROVINCE_HUNAN.equals(provinceName)) {
            examTypes = Lists.newArrayList(Constant.EXAM_TYPE_PG, Constant.EXAM_TYPE_ZZ);
        } else if(Constant.PROVINCE_HENAN.equals(provinceName)) {
            examTypes = Lists.newArrayList(Constant.EXAM_TYPE_ZG);
        } else {
            examTypes = Lists.newArrayList(Constant.EXAM_TYPE_PG, Constant.EXAM_TYPE_ZZ, Constant.EXAM_TYPE_ZG);
        }
        return R.ok(examTypes); // TODO MF
    }

    @GetMapping("getExamMajorsNoToken")
    @ApiOperation("查询考生专业类")
    public R<List<Map>> getExamMajorsNoToken(String provinceName, String examType) {
        return getExamMajors(provinceName, examType, null); // TODO MF
    }

    @GetMapping("getExamMajors")
    @ApiOperation("查询考生专业类")
    public R<List<Map>> getExamMajors(String provinceName, String examType) {
        SysUser sysUser = SecurityUtils.getLoginUser().getUser(); // TODO MF
        return getExamMajors(StringUtils.isNotBlank(provinceName) ? provinceName : sysUser.getLocation(), StringUtils.isNotBlank(examType) ? examType : sysUser.getExamType().title(), sysUser);
    }

    private R<List<Map>> getExamMajors(String provinceName, String examType, SysUser sysUser) {
        List<Map> examMajors;
        examMajors = busiWishLocationSubmitsService.examMajors(provinceName).stream().map(t -> {
            Map d = new HashMap();
            d.put("code", t.getCourse());
            d.put("name", t.getCourseName());
            return d;
        }).collect(Collectors.toList());
        return R.ok(examMajors); // TODO MF
    }
}
