package cn.stylefeng.guns.zjxlUtil;

import org.json.JSONArray;
import org.json.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.util.ReflectionUtils;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Field;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/***
 * @ClassName: BaseController
 * @Description:
 * @Auther: shi kejing
 * @Date: 2020/11/2 10:27
 */
@ApiResponses(value = {
        @ApiResponse(code = 200, message = "返回的json里的status是200，成功"),
        @ApiResponse(code = 403, message = "返回的json里的status是403，该操作没有权限"),
        @ApiResponse(code = 997, message = "返回的json里的status是997，重新登陆"),
        @ApiResponse(code = 998, message = "返回的json里的status是998，登录超时，请重新登录"),
        @ApiResponse(code = 999, message = "返回的json里的status是999，帐号在别处登录，请重新登录")
})
public class BaseController {

    private static Logger logger = LoggerFactory.getLogger("error_logger");

    @Autowired
    protected HttpServletRequest request;

    /**
     * 獲取髮送請求用戶的uid

     * @return
     */
    public String getUID() {
        try {
            String userAgent = request.getHeader("userAgent");
            if (StringUtils.isEmpty(userAgent)) {
                userAgent = request.getHeader("User-Agent");
            }
            JSONObject json = new JSONObject(userAgent);
            return json.getString("uid");

//            return "xh1D2017031502222";// wjw00000001000e6badcfa163e424589/wjw00000001000e6badcfa163e424525
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 获取被代理人的code
     * @return
     */
    public String getRepresentedUID() {
        try {
            String userAgent = request.getHeader("userAgent");
            if (StringUtils.isEmpty(userAgent)) {
                userAgent = request.getHeader("User-Agent");
            }
            JSONObject json = new JSONObject(userAgent);
            return json.getString("represented");

        } catch (Exception e) {
            return null;
        }
    }


    /**
     * 获取平台端
     * @return
     */
    public Integer getPlatform() {
        try {
            String userAgent = request.getHeader("userAgent");
            if (StringUtils.isEmpty(userAgent)) {
                userAgent = request.getHeader("User-Agent");
            }
            JSONObject json = new JSONObject(userAgent);
            return json.getInt("platform");

        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 获取被代理人code，若没有则返回当前登录者
     * @return
     */
    public String getRepUID(){
        try {
            String userAgent = request.getHeader("userAgent");
            if (StringUtils.isEmpty(userAgent)) {
                userAgent = request.getHeader("User-Agent");
            }
            JSONObject json = new JSONObject(userAgent);
            if(json.isNull("represented")){
                return json.getString("uid");
            }
            return json.getString("represented");
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 獲取髮送請求用戶的uid
     *
     * @return
     */
    public String getLastUid() {
        try {
            String userAgent = request.getHeader("userAgent");
            if (StringUtils.isEmpty(userAgent)) {
                userAgent = request.getHeader("User-Agent");
            }
            JSONObject json = new JSONObject(userAgent);
            String id = json.getString("lastUid");
            if(StringUtils.isNoneBlank(id)){
                return id;
            }else{
                return json.getString("uid");
            }
        } catch (Exception e) {
            return null;
        }
    }
    public String getAppVersion() {
        try {
            String userAgent = request.getHeader("userAgent");
            if (StringUtils.isEmpty(userAgent)) {
                userAgent = request.getHeader("User-Agent");
            }
            JSONObject json = new JSONObject(userAgent);
            return json.getString("appVersion");

        } catch (Exception e) {
            return null;
        }
    }
    public String getOpenid() {
        try {
            String userAgent = request.getHeader("userAgent");
            if (StringUtils.isEmpty(userAgent)) {
                userAgent = request.getHeader("User-Agent");
            }
            JSONObject json = new JSONObject(userAgent);
            return json.getString("openid");

        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 获取用户ID
     *
     * @return
     */
    public long getId() {
        try {
            String userAgent = request.getHeader("userAgent");
            if (StringUtils.isEmpty(userAgent)) {
                userAgent = request.getHeader("User-Agent");
            }
            JSONObject json = new JSONObject(userAgent);
            return json.getLong("id");
        } catch (Exception e) {
            return 0;
        }
    }

    public String getIMEI() {
        try {
            String userAgent = request.getHeader("userAgent");
            if (StringUtils.isEmpty(userAgent)) {
                userAgent = request.getHeader("User-Agent");
            }
            JSONObject json = new JSONObject(userAgent);
            return json.getString("imei");
        } catch (Exception e) {
            return null;
        }
    }

    public String getToken() {
        try {
            String userAgent = request.getHeader("userAgent");
            if (StringUtils.isEmpty(userAgent)) {
                userAgent = request.getHeader("User-Agent");
            }
            JSONObject json = new JSONObject(userAgent);
            return json.getString("token");
        } catch (Exception e) {
            return null;
        }
    }

//    /**
//     * 获取当前用户的角色code
//     * @return
//     */
//    public String getCurrentRoleCode(){
//        try {
//            String userAgent = request.getHeader("userAgent");
//            if (StringUtils.isEmpty(userAgent)) {
//                userAgent = request.getHeader("User-Agent");
//            }
//            JSONObject json = new JSONObject(userAgent);
//            String currentUserRole = json.getJSONObject("currentUserRole").getString("code");
//            if(StringUtils.isNotEmpty(currentUserRole)){
//
//                Hospital hospital = hospitalDao.findByCode(currentUserRole);
//                if(hospital!=null&&hospital.getLevel()==3){
//                    return hospital.getTown();
//                }
//            }
//            return currentUserRole;
//        } catch (Exception e) {
//            return null;
//        }
//    }

    /**
     * 获取当前用户的角色级别
     * @return
     */
    public String getCurrentRoleLevel(){
        try {
            String userAgent = request.getHeader("userAgent");
            if (StringUtils.isEmpty(userAgent)) {
                userAgent = request.getHeader("User-Agent");
            }
            JSONObject json = new JSONObject(userAgent);
            return json.getJSONObject("currentUserRole").get("level")+"";
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 获取当前用户的角色是否是管理员
     * @return
     */
    public String getCurrentRoleIsManange(){
        try {
            String userAgent = request.getHeader("userAgent");
            if (StringUtils.isEmpty(userAgent)) {
                userAgent = request.getHeader("User-Agent");
            }
            JSONObject json = new JSONObject(userAgent);
            return json.getJSONObject("currentUserRole").getString("isManage");
        } catch (Exception e) {
            return null;
        }
    }

    public void error(Exception e) {
        logger.error(DateUtil.dateToStr(new Date(),"yyyy-MM-dd HH:mm:ss")+":"+getClass().getName() + ":", e.getMessage());
        e.printStackTrace();
    }

    public void warn(Exception e) {
        logger.warn(getClass().getName() + ":", e.getMessage());
        e.printStackTrace();
    }

    public void infoMessage(String message) {
        logger.info(message);
    }

    /**
     * 返回接口处理结果
     *
     * @param code  结果码，成功为200
     * @param msg   结果提示信息
     * @return
     */
    public String error(int code, String msg) {
        try {
            Map<Object, Object> map = new HashMap<Object, Object>();
            ObjectMapper mapper = new ObjectMapper();
            map.put("status", code);
            map.put("msg", msg);
            return mapper.writeValueAsString(map);
        } catch (Exception e) {
            error(e);
            return null;
        }
    }

    /**
     * 接口处理成功
     *
     * @param msg
     * @return
     */
    public String success(String msg) {
        try {
            Map<Object, Object> map = new HashMap<Object, Object>();
            ObjectMapper mapper = new ObjectMapper();
            map.put("status", 200);
            map.put("msg", msg);
            return mapper.writeValueAsString(map);
        } catch (Exception e) {
            error(e);
            return null;
        }
    }

    public String write(int code, String msg) {
        try {
            Map<Object, Object> map = new HashMap<Object, Object>();
            ObjectMapper mapper = new ObjectMapper();
            map.put("status", code);
            map.put("msg", msg);
            return mapper.writeValueAsString(map);
        } catch (Exception e) {
            error(e);
            return null;
        }
    }

    /**
     * 返回接口处理结果
     *
     * @param code  结果码，成功为200
     * @param msg   结果提示信息
     * @return
     */
    public String write(int code, String msg, String key, List<?> list) {
        try {
            Map<Object, Object> map = new HashMap<Object, Object>();
            ObjectMapper mapper = new ObjectMapper();
            mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
            map.put("status", code);
            map.put("msg", msg);
            map.put(key, list);
            String s = mapper.writeValueAsString(map);
            return s;
        } catch (Exception e) {
            error(e);
            return error(-1, "服务器异常，请稍候再试！");
        }
    }

    /**
     * 返回接口处理结果
     *
     * @param code  结果码，成功为200
     * @param msg   结果提示信息
     * @param value 结果数据
     * @return
     */
    public String write(int code, String msg, String key, JSONObject value) {
        try {
            JSONObject json = new JSONObject();
            json.put("status", code);
            json.put("msg", msg);
            json.put(key, value);
            return json.toString();
        } catch (Exception e) {
            error(e);
            return error(-1, "服务器异常，请稍候再试！");
        }
    }

    /**
     * 返回接口处理结果
     *
     * @param code  结果码，成功为200
     * @param msg   结果提示信息
     * @param value 结果数据
     * @return
     */
    public String write(int code, String msg, String key, JSONArray value,String key2, JSONObject value2) {
        try {
            JSONObject json = new JSONObject();
            json.put("status", code);
            json.put("msg", msg);
            json.put(key, value);
            json.put(key2, value2);
            return json.toString();
        } catch (Exception e) {
            error(e);
            return error(-1, "服务器异常，请稍候再试！");
        }
    }

    /**
     * 返回接口处理结果
     *
     * @param code  结果码，成功为200
     * @param msg   结果提示信息
     * @param value 结果数据
     * @return
     */
    public String write(int code, String msg, String key, JSONArray value) {
        try {
            JSONObject json = new JSONObject();
            json.put("status", code);
            json.put("msg", msg);
            json.put(key, value);
            return json.toString();
        } catch (Exception e) {
            error(e);
            return error(-1, "服务器异常，请稍候再试！");
        }
    }

    /**
     * 返回接口处理结果
     *
     * @param code  结果码，成功为200
     * @param msg   结果提示信息
     * @param total 总数
     * @param value 结果数据
     * @return
     */
    public String write(int code, String msg, int total, String key, JSONArray value) {
        try {
            JSONObject json = new JSONObject();
            json.put("status", code);
            json.put("msg", msg);
            json.put("total", total);
            json.put(key, value);
            return json.toString();
        } catch (Exception e) {
            error(e);
            return error(-1, "服务器异常，请稍候再试！");
        }
    }

    /**
     * 返回接口处理结果
     *
     * @param code  结果码，成功为200
     * @param msg   结果提示信息
     * @return
     */
    public String write(int code, String msg, int total, String key, List<?> list) {
        try {
            Map<Object, Object> map = new HashMap<Object, Object>();
            ObjectMapper mapper = new ObjectMapper();
            mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
            map.put("status", code);
            map.put("msg", msg);
            map.put("total", total);
            map.put(key, list);
            String s = mapper.writeValueAsString(map);
            return s;
        } catch (Exception e) {
            error(e);
            return error(-1, "服务器异常，请稍候再试！");
        }
    }

    /**
     * 返回接口处理结果
     *
     * @param code  结果码，成功为200
     * @param msg   结果提示信息
     * @param value 结果数据
     * @return
     */
    public String write(int code, String msg, String key, Object value) {
        try {
            Map<Object, Object> map = new HashMap<Object, Object>();
            ObjectMapper mapper = new ObjectMapper();
            map.put("status", code);
            map.put("msg", msg);
            map.put(key, value);
            return mapper.writeValueAsString(map);
        } catch (Exception e) {
            error(e);
            return error(-1, "服务器异常，请稍候再试！");
        }
    }

    /**
     * 返回接口处理结果
     *
     * @param code  结果码，成功为200
     * @param msg   结果提示信息
     * @return
     */
    public String write(int code, String msg, String key, Page<?> list) {
        try {
            Map<Object, Object> map = new HashMap<Object, Object>();
            ObjectMapper mapper = new ObjectMapper();
            map.put("status", code);
            map.put("msg", msg);
            // 是否为第一页
            map.put("isFirst", list.isFirst());
            // 是否为最后一页
            map.put("isLast", list.isLast());
            // 总条数
            map.put("total", list.getTotalElements());
            // 总页数
            map.put("totalPages", list.getTotalPages());
            map.put(key, list.getContent());
            return mapper.writeValueAsString(map);
        } catch (Exception e) {
            error(e);
            return error(-1, "服务器异常，请稍候再试！");
        }
    }

    /**
     * 返回接口处理结果
     *
     * @param code  结果码，成功为200
     * @param msg   结果提示信息
     * @return
     */
    public String write(int code, String msg, String key, Page<?> page, JSONArray array) {
        try {
            JSONObject json = new JSONObject();
            json.put("status", code);
            json.put("msg", msg);
            // 是否为第一页
            json.put("isFirst", page == null ? false : page.isFirst());
            // 是否为最后一页
            json.put("isLast", page == null ? true : page.isLast());
            // 总条数
            json.put("total", page == null ? 0 : page.getTotalElements());
            // 总页数
            json.put("totalPages", page == null ? 0 : page.getTotalPages());
            json.put(key, array);
            return json.toString();
        } catch (Exception e) {
            error(e);
            return error(-1, "服务器异常，请稍候再试！");
        }
    }

    /**
     * 返回接口处理结果
     *
     * @param code  结果码，成功为200
     * @param msg   结果提示信息
     * @param value 结果数据
     * @return
     */
    public String write(int code, String msg, String key, Map<?, ?> value) {
        try {
            Map<Object, Object> map = new HashMap<Object, Object>();
            ObjectMapper mapper = new ObjectMapper();
            map.put("status", code);
            map.put("msg", msg);
            map.put(key, value);
            return mapper.writeValueAsString(map);
        } catch (Exception e) {
            error(e);
            return error(-1, "服务器异常，请稍候再试！");
        }
    }

    /**
     * 返回接口处理结果
     *
     * @param code  结果码，成功为200
     * @param msg   结果提示信息
     * @param value 结果数据
     * @return
     */
    public String write(int code, String msg, String key, String value) {
        try {
            Map<Object, Object> map = new HashMap<Object, Object>();
            ObjectMapper mapper = new ObjectMapper();
            map.put("status", code);
            map.put("msg", msg);
            map.put(key, value);
            return mapper.writeValueAsString(map);
        } catch (Exception e) {
            error(e);
            return error(-1, "服务器异常，请稍候再试！");
        }
    }

    /**
     * 返回接口处理结果
     *
     * @param code  结果码，成功为200
     * @param msg   结果提示信息
     * @return
     */
    public String write(int code, String msg, String key, IdEntity entity) {
        try {
            Map<Object, Object> map = new HashMap<Object, Object>();
            ObjectMapper mapper = new ObjectMapper();
            map.put("status", code);
            map.put("msg", msg);
            map.put(key, entity);
            return mapper.writeValueAsString(map);
        } catch (Exception e) {
            error(e);
            return error(-1, "服务器异常，请稍候再试！");
        }
    }

    /**
     * 返回接口处理结果
     *
     * @param code  结果码，成功为200
     * @param msg   结果提示信息
     * @return
     */
    public String write(int code, String msg, boolean isFirst, boolean isLast, long total, int totalPages, String key, Object values) {
        try {
            JSONObject json = new JSONObject();
            json.put("status", code);
            json.put("msg", msg);
            // 是否为第一页
            json.put("isFirst", isFirst);
            // 是否为最后一页
            json.put("isLast", isLast);
            // 总条数
            json.put("total", total);
            // 总页数
            json.put("totalPages", totalPages);
            json.put(key, values);
            return json.toString();
        } catch (Exception e) {
            logger.error("BaseController:", e.getMessage());
            return error(-1, "服务器异常，请稍候再试！");
        }
    }

    public String trimEnd(String param, String trimChars) {
        if (param.endsWith(trimChars)) {
            param = param.substring(0, param.length() - trimChars.length());
        }
        return param;
    }

    /**
     * 无效用户消息返回
     *
     * @param e
     * @param defaultCode
     * @param defaultMsg
     * @return
     */
    public String invalidUserException(Exception e, int defaultCode, String defaultMsg) {
        try {
            // if (e instanceof UndeclaredThrowableException) {
            // UndeclaredThrowableException ute = (UndeclaredThrowableException) e;
            // InvalidUserException iue = (InvalidUserException) ute.getUndeclaredThrowable();
            // if (iue != null) {
            // return error(iue.getCode(), iue.getMsg());
            // }
            // }
            return error(defaultCode, defaultMsg);
        } catch (Exception e2) {
            return null;
        }
    }

    public List<Map<String, Object>> copyBeans(Collection<? extends Object> beans, String... propertyNames) {
        List<Map<String, Object>> result = new ArrayList<>();
        for (Object bean : beans) {
            result.add(copyBeanProperties(bean, propertyNames));
        }

        return result;
    }

    /**
     * 复制特定属性。
     *
     * @param bean
     * @param propertyNames
     * @return
     */
    public Map<String, Object> copyBeanProperties(Object bean, String... propertyNames) {
        Map<String, Object> simplifiedBean = new HashMap<>();
        for (String propertyName : propertyNames) {
            Field field = ReflectionUtils.findField(bean.getClass(), propertyName);
            if (field != null) {
                field.setAccessible(true);
                Object value = ReflectionUtils.getField(field, bean);
                simplifiedBean.put(propertyName, value == null ? "" : value);
            } else {
                simplifiedBean.put(propertyName, "");
            }
        }

        return simplifiedBean;
    }

    /**
     * 数据保留两位小数，**.0 去掉小数点
     * @param obj
     * @return
     */
    public String getNumberFormat(Object obj){
        if(obj != null){
            Double d = Double.valueOf(obj.toString());
            NumberFormat df = NumberFormat.getInstance();
            df.setGroupingUsed(false);
            df.setMaximumFractionDigits(2);
            return df.format(d);
        }else {
            return "";
        }
    }

    public String write(int code, String errorMsg, int page, int rows, long total, List<?> list) {
        try {
            Map<Object, Object> map = new HashMap<Object, Object>();
            ObjectMapper mapper = new ObjectMapper();
            map.put("successFlg", code == 0);
            map.put("errorMsg", errorMsg);
            // 是否为第一页
            map.put("errorCode", code);
            // 是否为最后一页
            map.put("currPage", page);
            // 分页大小
            map.put("pageSize", rows);
            // 总条数
            map.put("totalCount", total);
            // 总页数
            map.put("totalPage", Math.ceil((double)total/(rows)));
            // 结果集
            map.put("detailModelList", list);
            return mapper.writeValueAsString(map);
        } catch (Exception e) {
            error(e);
            return error(-1, "服务器异常，请稍候再试！");
        }
    }

    /**
     * 判断是否是观察者模式
     * @return
     */
    public boolean getObserverStatus () {

        String userAgent = request.getHeader("userAgent");
        if (StringUtils.isEmpty(userAgent)) {
            userAgent = request.getHeader("User-Agent");
        }
        logger.debug("userAgent:" + userAgent);
        JSONObject json = new JSONObject(userAgent);
        String observer = json.has("observer") ? json.getString("observer") : "";
        //如果是观察者直接返回true
        if (!org.springframework.util.StringUtils.isEmpty(observer) && observer.equals("1")) {
            return true;
        }else{
            return false;
        }
    }

    //获取ip地址
    public String getIpAddr() {
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        if ("0:0:0:0:0:0:0:1".equals(ip)) {
            ip = "127.0.0.1";
        }
        if (ip.split(",").length > 1) {
            ip = ip.split(",")[0];
        }
        return ip;
    }

    //获取手机型号
    public String getPhoneType(){
        String userAgent = request.getHeader("User-Agent");
        Pattern pattern = Pattern.compile(";\\s?(\\S*?\\s?\\S*?)\\s?(Build)?/");
        Matcher matcher = pattern.matcher(userAgent);
        String model = null;
        if (matcher.find()) {
            model = matcher.group(1).trim();
        }else{
            model = "未知型号";
        }
        return model;
    }

}
