package com.qmth.themis.admin.api;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.reflect.TypeToken;
import com.qmth.themis.business.bean.admin.NotifyBean;
import com.qmth.themis.business.constant.SystemConstant;
import com.qmth.themis.business.entity.TSBlackList;
import com.qmth.themis.business.entity.TSNotify;
import com.qmth.themis.business.enums.UploadFileEnum;
import com.qmth.themis.business.service.TSNotifyService;
import com.qmth.themis.business.service.ThemisCacheService;
import com.qmth.themis.business.util.OssUtil;
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 io.swagger.annotations.*;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import java.io.File;
import java.io.FileOutputStream;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

/**
 * <p>
 * 系统通知表 前端控制器
 * </p>
 *
 * @author wangliang
 * @since 2023-02-01
 */
@Api(tags = "系统通知信息Controller")
@RestController
@RequestMapping(SystemConstant.PREFIX_URL_ADMIN + "/notify")
@Validated
public class TSNotifyController {
    private final static Logger log = LoggerFactory.getLogger(TSNotifyController.class);

    @Resource
    TSNotifyService tsNotifyService;

    @Resource
    OssUtil ossUtil;

    @Resource
    ThemisCacheService themisCacheService;

    @ApiOperation(value = "系统通知信息查询接口")
    @RequestMapping(value = "/select", method = RequestMethod.POST)
    @ApiResponses({@ApiResponse(code = 200, message = "系统通知信息", response = TSBlackList.class)})
    public Result select(@ApiParam(value = "分页页码", required = true) @RequestParam @Min(SystemConstant.PAGE_NUMBER_MIN) int pageNumber,
                         @ApiParam(value = "分页数", required = true) @RequestParam @Min(SystemConstant.PAGE_SIZE_MIN) @Max(SystemConstant.PAGE_SIZE_MAX) int pageSize) {
        return ResultUtil.ok(tsNotifyService.select(new Page<>(pageNumber, pageSize)));
    }

    @ApiOperation(value = "系统通知信息保存接口")
    @RequestMapping(value = "/save", method = RequestMethod.POST)
    @ApiResponses({@ApiResponse(code = 200, message = "常规信息", response = Result.class)})
    @Transactional
    public Result save(@Validated @ApiParam(value = "系统通知信息", required = true) @RequestBody TSNotify tsNotify, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return ResultUtil.error(bindingResult.getAllErrors().get(0).getDefaultMessage());
        }
        tsNotifyService.saveOrUpdate(tsNotify);
        updateTsNotifyCache();
        return ResultUtil.ok(true);
    }

    @ApiOperation(value = "系统通知信息启用/禁用接口")
    @RequestMapping(value = "/enable", method = RequestMethod.POST)
    @ApiResponses({@ApiResponse(code = 200, message = "常规信息", response = Result.class)})
    @Transactional
    public Result enable(@ApiParam(value = "系统通知信息id", required = true) @RequestParam Long id,
                         @ApiParam(value = "启用/禁用", required = true) @RequestParam Boolean enable) {
        TSNotify tsNotify = tsNotifyService.getById(id);
        Optional.ofNullable(tsNotify).orElseThrow(() -> new BusinessException("系统通知信息为空"));

        tsNotify.setEnable(enable);
        tsNotifyService.saveOrUpdate(tsNotify);
        updateTsNotifyCache();
        return ResultUtil.ok(true);
    }

    /**
     * 刷新缓存信息并写入json文件
     */
    public void updateTsNotifyCache() {
        File file = null;
        try {
            file = SystemConstant.getFileTempVar(SystemConstant.JSON_PREFIX);
            List<TSNotify> tsNotifyList = themisCacheService.updateSysNotifyCache();
            List<NotifyBean> notifyBeanList = GsonUtil.fromJson(GsonUtil.toJson(tsNotifyList), new TypeToken<List<NotifyBean>>() {
            }.getType());
            JSONObject jsonObject = JSONObject
                    .parseObject(new String(ossUtil.download(true, UploadFileEnum.client.name() + "/" + SystemConstant.EXAM_CONFIG_FILE_NAME), StandardCharsets.UTF_8));
            if (Objects.isNull(jsonObject) || jsonObject.size() == 0) {
                jsonObject = new JSONObject();
            }
            jsonObject.put(SystemConstant.NOTIFY_LIST, notifyBeanList);
            IOUtils.write(jsonObject.toJSONString().getBytes(StandardCharsets.UTF_8), new FileOutputStream(file));
            ossUtil.upload(true, UploadFileEnum.client.name() + "/" + SystemConstant.EXAM_CONFIG_FILE_NAME, file);
        } catch (Exception e) {
            log.error(SystemConstant.LOG_ERROR, e);
            if (e instanceof BusinessException) {
                throw new BusinessException(e.getMessage());
            } else {
                throw new RuntimeException(e);
            }
        } finally {
            if (Objects.nonNull(file)) {
                file.delete();
            }
        }
    }
}
