/*
 * Author: wangjian
 * 生成controller
 */
package com.tofly.dc.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tofly.common.core.entity.ResultRespone;
import com.tofly.common.core.util.StringUtil;
import com.tofly.common.log.annotation.ToFlyAppLog;
import com.tofly.common.oauth.auth.ToflyUser;
import com.tofly.common.oauth.util.SecurityUtils;
import com.tofly.dc.comm.Constant;
import com.tofly.dc.comm.sys.RunningStatusEnum;
import com.tofly.dc.entity.InterfaceLog;
import com.tofly.dc.entity.InterfaceManage;
import com.tofly.dc.entity.vo.ModuleStatisticsBusinessVo;
import com.tofly.dc.entity.vo.ModuleStatisticsInterfaceVo;
import com.tofly.dc.entity.vo.ModuleStatisticsSysVo;
import com.tofly.dc.exception.BusinessException;
import com.tofly.dc.service.InterfaceLogService;
import com.tofly.dc.service.InterfaceManageService;
import com.tofly.dc.util.DateTimeUtil;
import lombok.AllArgsConstructor;
import org.springframework.http.HttpRequest;
import org.springframework.web.bind.annotation.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.net.SocketTimeoutException;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 接口管理表
 *
 * @author zev
 * @date Wed Jan 05 00:00:00 CST 2022
 */
@RestController
@AllArgsConstructor
@RequestMapping("/interfacemanage")
@Api(tags = "接口管理表接口")
public class InterfaceManageController {

    private final InterfaceManageService interfaceManageService;

    private final InterfaceLogService interfaceLogService;

    /**
     * 分页查询
     *
     * @param page            分页对象
     * @param interfaceManage 接口管理表
     * @return
     */
    @GetMapping("/page")
    @ApiOperation(value = "分页查询")
    public ResultRespone getInterfaceManagePage(Page page, @ModelAttribute InterfaceManage interfaceManage) {
        return ResultRespone.success(interfaceManageService.page(page, Wrappers.query(interfaceManage)));
    }


    /**
     * 通过id查询接口管理表
     *
     * @param id id
     * @return ResultRespone
     */
    @GetMapping("/{id}")
    @ApiOperation(value = "通过ID查询")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "ID", required = true, dataType = "Long")
    })
    public ResultRespone getById(@PathVariable("id") Long id) {
        return ResultRespone.success(interfaceManageService.getById(id));
    }

    /**
     * 新增接口管理表
     *
     * @param interfaceManage 接口管理表
     * @return ResultRespone
     */
    @ApiOperation(value = "新增接口管理表")
    @PostMapping
    public ResultRespone save(@RequestBody InterfaceManage interfaceManage) {
        return ResultRespone.success(interfaceManageService.saveInfo(interfaceManage));
    }

    /**
     * 修改接口管理表
     *
     * @param interfaceManage 接口管理表
     * @return ResultRespone
     */
    @ApiOperation(value = "修改接口管理表")
    @PutMapping
    public ResultRespone updateById(@RequestBody InterfaceManage interfaceManage) {
        return ResultRespone.success(interfaceManageService.updateById(interfaceManage));
    }

    @ApiOperation(value = "批量修改接口状态")
    @PutMapping("/updateByStatus")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "ids", value = "多个以,分隔", required = true, dataType = "String"),
            @ApiImplicitParam(name = "status", value = "修改的状态0草稿,1已发布,2已停用", required = true, dataType = "String")
    })
    public ResultRespone updateByStatus(String ids, String status) {
        if (StringUtil.isNotEmpty(ids)) {
            List<Long> processIds = Arrays.stream(ids.split(Constant.CSV)).map(s -> Long.parseLong(s.trim()))
                    .collect(Collectors.toList());
            return ResultRespone.success(interfaceManageService.update(new UpdateWrapper<InterfaceManage>().lambda()
                    .in(InterfaceManage::getId, processIds).set(InterfaceManage::getRunningStatus, status)));
        }
        return ResultRespone.success();
    }

    /**
     * 通过id批量删除接口管理表
     *
     * @param ids id
     * @return ResultRespone
     */
    @ApiOperation(value = "通过ID批量删除接口管理表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "ids", value = "批量删除，多个id以逗号隔开", required = true, dataType = "String")
    })
    @DeleteMapping("/deleteByIds")
    public ResultRespone removeById(String ids) {
        return ResultRespone.success(interfaceManageService.update(new UpdateWrapper<InterfaceManage>()
                .lambda()
                .in(InterfaceManage::getId, Arrays.asList(ids.split(Constant.CSV)))
                .set(InterfaceManage::getDel, "1")));
    }


    @PostMapping("/callInterface")
    @ApiOperation(value = "接口调用")
    public ResultRespone<Object> callInterface(HttpServletRequest httpRequest, String parameter, String code, String token, HttpServletResponse response) {
        ResultRespone<Object> respone = new ResultRespone<>();
        // 调用开始时间
        Date strDate = DateTimeUtil.convertLDTToDate(LocalDateTime.now());
        long strTime = strDate.getTime();
        ToflyUser user = SecurityUtils.getUser();
        int save = 1;
        if(null == user){
            save = 0;
        }
        InterfaceLog log = new InterfaceLog();
        log.setAccessTime(strDate);
        try {
            ResultRespone<Object> dispose = interfaceManageService.dispose(httpRequest, parameter, code, token, log, response);
            respone.setResult(dispose);
        } catch (BusinessException businessException) {
            respone.setCode(businessException.getRetCd());
            respone.setMessage(businessException.getMsgDes());
            log.setErrorCode(businessException.getRetCd() + "");
            log.setErrorNote(businessException.getMsgDes());
            log.setState("1");
        } catch (SocketTimeoutException timeoutException) {
            respone.setCode(Constant.READ_TIMED_OUT_CODE);
            respone.setMessage(Constant.READ_TIMED_OUT);
            log.setState("1");
            log.setErrorCode(Constant.READ_TIMED_OUT_CODE + "");
            log.setErrorNote(Constant.READ_TIMED_OUT);
            timeoutException.printStackTrace();
        } catch (Exception e) {
            log.setState("2");
            log.setErrorCode(Constant.SYS_ERROR_CODE + "");
            log.setErrorNote(Constant.SYS_ERROR);
            e.printStackTrace();
        } finally {
            Date endDate = DateTimeUtil.convertLDTToDate(LocalDateTime.now());
            long endTime = endDate.getTime();
            long l = endTime - strTime;
            log.setOperationLength(l);
            if(1 == save){
                log.setAccessUserId(user.getUserid());
                interfaceLogService.save(log);
            }

        }

        return respone;
    }

    @GetMapping("/moduleStatistics")
    @ApiOperation(value = "模块统计")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "sysId", value = "系统id", required = false, dataType = "String"),
            @ApiImplicitParam(name = "moduleId", value = "模块id", required = false, dataType = "String"),
            @ApiImplicitParam(name = "interfaceCode", value = "接口编码", required = false, dataType = "String")
    })
    public ResultRespone moduleStatistics(String sysId, String moduleId, String interfaceCode) {
        List<ModuleStatisticsSysVo> sysVoList = new ArrayList<>();
        List<InterfaceManage> list = interfaceManageService.list(new QueryWrapper<InterfaceManage>().lambda()
                .eq(InterfaceManage::getDel, "0")
                .eq(StringUtil.isNotEmpty(sysId), InterfaceManage::getOwnershipSystem, sysId)
                .eq(StringUtil.isNotEmpty(moduleId), InterfaceManage::getOwnershipBusiness, moduleId)
                .eq(StringUtil.isNotEmpty(interfaceCode), InterfaceManage::getCode, interfaceCode
                ));
        if(null!=list && list.size()>0){
            Map<String, String> sysMap = new HashMap<>(12);
            Map<String, String> businessMap = new HashMap<>(12);
            list.forEach(info -> {
                sysMap.put(info.getOwnershipSystem(), info.getOwnershipSystemName());
                businessMap.put(info.getOwnershipBusiness(), info.getOwnershipBusinessName());
            });
            // 按照系统分组
            Map<String, List<InterfaceManage>> collect = list.stream().collect(Collectors.groupingBy(InterfaceManage::getOwnershipSystem));
            collect.forEach((k, v) -> {
                ModuleStatisticsSysVo vo = new ModuleStatisticsSysVo();
                vo.setOwnershipSystem(k);
                vo.setOwnershipSystemName(sysMap.get(k));
                long count = v.stream().map(InterfaceManage::getOwnershipBusiness).collect(Collectors.toSet()).stream().count();
                vo.setChildNum(Integer.valueOf(count+""));
                List<ModuleStatisticsBusinessVo> businessVoList = new ArrayList<>();
                // 按照业务模块分组
                Map<String, List<InterfaceManage>> businessGroup = v.stream().collect(Collectors.groupingBy(InterfaceManage::getOwnershipBusiness));
                businessGroup.forEach((n, m) -> {
                    ModuleStatisticsBusinessVo businessVo = new ModuleStatisticsBusinessVo();
                    businessVo.setOwnershipSystem(k);
                    businessVo.setOwnershipSystemName(sysMap.get(k));
                    businessVo.setOwnershipBusiness(n);
                    businessVo.setOwnershipBusinessName(businessMap.get(n));
                    businessVo.setInterfaceNum(m.size());
                    long draft = m.stream().filter(bus -> RunningStatusEnum.DRAFT.getCode().equals(bus.getRunningStatus())).count();
                    long published = m.stream().filter(bus -> RunningStatusEnum.PUBLISHED.getCode().equals(bus.getRunningStatus())).count();
                    long stop = m.stream().filter(bus -> RunningStatusEnum.STOP.getCode().equals(bus.getRunningStatus())).count();
                    businessVo.setDraftNum(draft);
                    businessVo.setPublishedNum(published);
                    businessVo.setStopNum(stop);
                    businessVoList.add(businessVo);
                });
                vo.setBusinessVos(businessVoList);
                sysVoList.add(vo);
            });
        }


        return ResultRespone.success(sysVoList);
    }

}
