package com.bocloud.ims.booter.aspect;


import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.Feature;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.bocloud.common.enums.BoCloudMethod;
import com.bocloud.common.enums.BoCloudService;
import com.bocloud.common.model.BocloudResult;
import com.bocloud.service.core.Service;
import com.bocloud.service.http.core.ServiceFactory;
import com.bocloud.service.http.model.RemoteService;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * 展示关联的业务系统切面
 *
 * @author: liuxw
 * @date: 2022/8/29 11:19
 */
@Aspect
@Component
@Slf4j
public class ShowBindingBusinessAspect {

    private final static String TOKEN = "token";

    @Autowired
    private ServiceFactory serviceFactory;

    private static Service service = Service.create(BoCloudService.SMS);

    private Map<String, Object> headers = new HashMap<>(4);

    /**
     * 定义切点
     */
    @Pointcut("@annotation(com.bocloud.ims.booter.annotation.ShowBindingBusiness)")
    public void showBindingBusiness() {
    }


    /**
     * 环绕通知 （可以控制目标方法前中后期执行操作，目标方法执行前后分别执行一些代码）
     * 此处是对列表增加关联业务系统数据
     *
     * @param joinPoint
     * @return
     */
    @Around("showBindingBusiness()")
    public Object before(ProceedingJoinPoint joinPoint) {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder
                .getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        Assert.notNull(request, "request cannot be null.");
        String token = request.getHeader(TOKEN);
        headers.put("token", token);
        try {
            Object result = joinPoint.proceed();
            JSONObject resultJson = JSONObject.parseObject(JSONObject.toJSONString(result, SerializerFeature.WriteNullStringAsEmpty), Feature.IgnoreNotMatch);
            JSONObject dataJson = resultJson.getJSONObject("data");
            JSONArray rows = dataJson.getJSONArray("rows");
            List<JSONObject> rowList = new ArrayList<>(rows.size());
            rows.forEach(row -> {
                rowList.add(JSONObject.parseObject(JSONObject.toJSONString(row), Feature.IgnoreNotMatch));
            });
            rowList.forEach(this::setBusiness);
            dataJson.put("rows", rowList);
            return JSONObject.parseObject(JSONObject.toJSONString(resultJson), BocloudResult.class, Feature.IgnoreNotMatch);
        } catch (Throwable throwable) {
            throw new RuntimeException(throwable);
        }

    }


    /**
     * 添加业务相关的参数
     *
     * @param row 单个行参数
     * @return 设置业务相关参数
     * @author liuxw
     * @date 2022/8/29 16:15
     */
    private void setBusiness(JSONObject row) {
        RemoteService remote = serviceFactory.build(service, "/v1/business/resource/" + row.getLong("id"), BoCloudMethod.GET, headers, null);
        try {
            BocloudResult result = remote.invoke();
            JSONObject data = JSONObject.parseObject(JSONObject.toJSONString(result.getData()));
            Long businessId = data.getLong("id");
            String businessName = data.getString("name");
            row.put("newBusinessId", businessId);
            row.put("newBusinessName", businessName);
        } catch (Exception e) {
            log.error("获取资源的业务系统信息异常：{}", e.getMessage(), e);
            row.put("newBusinessId", "");
            row.put("newBusinessName", "");
        }


    }


}
