package com.qmth.themis.exam.api;

import com.google.common.reflect.TypeToken;
import com.qmth.themis.business.annotation.ApiJsonObject;
import com.qmth.themis.business.annotation.ApiJsonProperty;
import com.qmth.themis.business.bean.exam.EnvBean;
import com.qmth.themis.business.bean.exam.ExamFileUploadBean;
import com.qmth.themis.business.bean.exam.OrgInfoBean;
import com.qmth.themis.business.bean.exam.VersionBean;
import com.qmth.themis.business.constant.SystemConstant;
import com.qmth.themis.business.dto.response.TBOrgBean;
import com.qmth.themis.business.entity.SysConfig;
import com.qmth.themis.business.entity.TBClientVersion;
import com.qmth.themis.business.entity.TBOrg;
import com.qmth.themis.business.enums.ClientVersionTypeEnum;
import com.qmth.themis.business.enums.UploadFileEnum;
import com.qmth.themis.business.service.TBClientVersionService;
import com.qmth.themis.business.service.TBOrgService;
import com.qmth.themis.business.service.ThemisCacheService;
import com.qmth.themis.business.util.OssUtil;
import com.qmth.themis.common.enums.ExceptionResultEnum;
import com.qmth.themis.common.exception.BusinessException;
import com.qmth.themis.common.util.GsonUtil;
import com.qmth.themis.common.util.Result;
import com.qmth.themis.common.util.ResultUtil;
import com.qmth.themis.exam.config.DictionaryConfig;
import io.swagger.annotations.*;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;

@Api(tags = "系统信息Controller")
@RestController
@RequestMapping(SystemConstant.PREFIX_URL_OE + "/sys")
@Validated
public class SysController {

    @Resource
    DictionaryConfig dictionaryConfig;

    @Resource
    TBClientVersionService tbClientVersionService;

    @Resource
    ThemisCacheService themisCacheService;

    @Resource
    TBOrgService tbOrgService;

    @Resource
    OssUtil ossUtil;

    @ApiOperation(value = "获取环境接口")
    @RequestMapping(value = "/env", method = RequestMethod.POST)
    @ApiResponses({@ApiResponse(code = 200, message = "环境信息", response = Result.class)})
    public Result env(@ApiJsonObject(name = "oeEnv", value = {
            @ApiJsonProperty(key = "orgId", type = "long", example = "1", description = "机构id"),
    }) @ApiParam(value = "机构id", required = false) @RequestBody Map<String, Object> mapParameter) {
        EnvBean env = new EnvBean();
        if (Objects.nonNull(mapParameter.get(SystemConstant.ORG_ID))) {
            Long orgId = Long.parseLong(String.valueOf(mapParameter.get(SystemConstant.ORG_ID)));
            TBOrg org = themisCacheService.addOrgCache(orgId);
            if (Objects.nonNull(org)) {
                OrgInfoBean orgInfo = new OrgInfoBean(org.getName(), org.getLogo(), (org.getUpdateTime() == null ? null : org.getUpdateTime()));
                env.setOrgInfo(orgInfo);
            } else {
                throw new BusinessException("没有id为[" + orgId + "]的机构");
            }
        }
        env.setCurrentTime(System.currentTimeMillis());
        TBClientVersion tbClientVersion = tbClientVersionService.getMaxClientVersion();
        if (Objects.nonNull(tbClientVersion)) {
            VersionBean v = new VersionBean(tbClientVersion.getName(), tbClientVersion.getValue(), tbClientVersion.getUrl());
            env.setVersion(v);
        }
        boolean oss = dictionaryConfig.sysDomain().isOss();
        String url = null, examConfig = null;
        SysConfig sysConfig = themisCacheService.addSysConfigCache(SystemConstant.EXAM_FILE_HOST);
        Optional.ofNullable(sysConfig).orElseThrow(() -> new BusinessException("未配置exam文件host"));

        if (oss) {
            url = dictionaryConfig.aliYunOssDomain().getPublicUrl() + File.separator + UploadFileEnum.client.name() + "/" + SystemConstant.DENY_LIST_FILE_NAME;
            examConfig = dictionaryConfig.aliYunOssDomain().getPublicUrl() + File.separator + UploadFileEnum.client.name() + "/" + SystemConstant.EXAM_CONFIG_FILE_NAME;
        } else {
            url = "http://" + sysConfig.getConfigValue() + File.separator + UploadFileEnum.client.name() + "/" + SystemConstant.DENY_LIST_FILE_NAME;
            examConfig = "http://" + sysConfig.getConfigValue() + File.separator + UploadFileEnum.client.name() + "/" + SystemConstant.EXAM_CONFIG_FILE_NAME;
        }
        env.setDenyList(url);
        env.setExamConfig(examConfig);
        return ResultUtil.ok(env);
    }

    @ApiOperation(value = "获取所有学校接口")
    @RequestMapping(value = "/school/list", method = RequestMethod.POST)
    @ApiResponses({@ApiResponse(code = 200, message = "学校信息", response = TBOrgBean.class)})
    public Result schoolList() {
        List<TBOrg> tbOrgList = tbOrgService.list();
        List<TBOrgBean> tbOrgBeanList = GsonUtil.fromJson(GsonUtil.toJson(tbOrgList), new TypeToken<List<TBOrgBean>>() {
        }.getType());
        return ResultUtil.ok(tbOrgBeanList);
    }

    @ApiOperation(value = "上传安装包回调接口")
    @RequestMapping(value = "/upload/package/callback", method = RequestMethod.POST)
    @ApiResponses({@ApiResponse(code = 200, message = "常规信息", response = Result.class)})
    @Transactional
    public Result uploadPackageCallback(@Validated @ApiParam(value = "学校信息", required = true) @RequestBody TBOrgBean tbOrgBean, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return ResultUtil.error(bindingResult.getAllErrors().get(0).getDefaultMessage());
        }
        TBOrg tbOrg = themisCacheService.addOrgCache(tbOrgBean.getId());
        Optional.ofNullable(tbOrg).orElseThrow(() -> new BusinessException(ExceptionResultEnum.ORG_NO));

        SysConfig cdnUrl = themisCacheService.addSysConfigCache(SystemConstant.CDN_URL);
        Optional.ofNullable(cdnUrl).orElseThrow(() -> new BusinessException("cdn地址未配置"));
        return ResultUtil.ok(tbClientVersionService.save(new TBClientVersion(tbOrg.getId(), cdnUrl.getConfigValue() + tbOrgBean.getPackagePath(), tbOrgBean.getDescription(), ClientVersionTypeEnum.UPLOAD)));
    }

    @ApiOperation(value = "文件上传")
    @RequestMapping(value = "/file/upload", method = RequestMethod.POST)
    @ApiResponses({@ApiResponse(code = 200, message = "试卷信息")})
    public Result fileUpload(@ApiParam(value = "上传文件", required = true) @RequestParam MultipartFile file,
                             @ApiParam(value = "md5", required = true) @RequestParam String md5,
                             @ApiParam(value = "上传文件目录") @RequestParam(required = false) String fileDir) throws IOException {
        InputStream in = null;
        ExamFileUploadBean ret = new ExamFileUploadBean();
        try {
            SysConfig sysConfig = themisCacheService.addSysConfigCache(SystemConstant.CLIENT_DB_UPLOAD_LOCATION);
            Optional.ofNullable(sysConfig).orElseThrow(() -> new BusinessException("未配置客户端上传db目录地址"));

            StringJoiner stringJoiner = new StringJoiner("").add(sysConfig.getConfigValue());
            stringJoiner = Objects.nonNull(fileDir) && !Objects.equals(fileDir.trim(), "") ? stringJoiner.add(File.separator).add(fileDir) : stringJoiner;
            stringJoiner = stringJoiner.add(File.separator).add(file.getOriginalFilename());
            in = file.getInputStream();
            ossUtil.upload(true, stringJoiner.toString(), in, md5);
            String url = ossUtil.getAliYunOssPublicDomain().getPublicUrl() + File.separator + stringJoiner.toString();
            ret.setUrl(url);
            ret.setUploadTime(System.currentTimeMillis());
        } catch (IOException e) {
            throw new BusinessException("文件读取出错");
        } finally {
            in.close();
        }
        return ResultUtil.ok(ret);
    }
}