package com.roma.romaapi.utils;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import static com.roma.romaapi.utils.JWTUtil.SIGN;

// 系统公共工具类
@Component
public class CommonUtil {

    @Autowired
    StringRedisTemplate stringRedisTemplate;
    @Value("${upload.path}")
    private String configUploadPath;

    // 通过header中token信息,获取用户Id
    public String getUserIdByHeaderAuthorization(String headerAuthorization){
        String token = headerAuthorization.substring(7); // 截取token
        String redisTokenKey = SIGN + token;
        String userId = stringRedisTemplate.opsForValue().get(redisTokenKey);
        if(null == userId || userId.equals("")){
            return "";
        }
        return userId;
    }

    // 退出登录删除缓存中的token
    public Boolean logoutDeleteRedisToken(String headerAuthorization){
        String token = headerAuthorization.substring(7); // 截取token
        String redisTokenKey = SIGN + token;
        return stringRedisTemplate.delete(redisTokenKey);
    }

    // 解析请求参数
    public Map analysisRequestParams(HttpServletRequest request, @RequestBody String data) {
        Map<String, String[]> maps = request.getParameterMap();
        String requestContentType = request.getContentType(); // 请求类型
        Map ret = new HashMap<>();
        if (requestContentType.equals("application/x-www-form-urlencoded")) {
            // 组装要绑定的参数数据
            for (Map.Entry<String, String[]> entry : maps.entrySet()) {
                String paramsKey = entry.getKey();
                String paramsValue = entry.getValue()[0];
                ret.put(paramsKey, paramsValue);
            }
        } else if (requestContentType.equals("application/json")) {
            try {
                ObjectMapper jacksonMapper = new ObjectMapper();
                Map<String, String> jsonParams = jacksonMapper.readValue(data, new TypeReference<Map<String, String>>() {});
                // 组装要绑定的参数数据
                for (Map.Entry<String, String> entry : jsonParams.entrySet()) {
                    String paramsKey = entry.getKey();
                    String paramsValue = entry.getValue();
                    ret.put(paramsKey, paramsValue);
                }
            }catch (IOException e) {
                e.printStackTrace();
            }
        }

        return  ret;
    }

    /**
     * 去除首尾指定字符
     * @param str   字符串
     * @param element   指定字符
     * @return
     */
    public String trimFirstAndLastChar(String str, String element){
        boolean beginIndexFlag = true;
        boolean endIndexFlag = true;
        do{
            int beginIndex = str.indexOf(element) == 0 ? 1 : 0;
            int endIndex = str.lastIndexOf(element) + 1 == str.length() ? str.lastIndexOf(element) : str.length();
            str = str.substring(beginIndex, endIndex);
            beginIndexFlag = (str.indexOf(element) == 0);
            endIndexFlag = (str.lastIndexOf(element) + 1 == str.length());
        } while (beginIndexFlag || endIndexFlag);
        return str;
    }

    // 返回当前年月日 时分秒
    public String getNowYYMMDDHHIISS() {
        Date date = new Date();
        SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String dateString = fmt.format(date);

        return dateString;
    }

    // api的请求,整理返回的要绑定的参数信息
    public Map filterApiBindParams(Map<String, String> maps) {
        Map bindData = new HashMap<>();
        for (Map.Entry<String, String> entry : maps.entrySet()) {
            String paramsKey = entry.getKey();
            String paramsValue = entry.getValue();
            String fourBeforestring = "";
            if(paramsKey.length() >= 4) {
                fourBeforestring = paramsKey.substring(0,4);
                if (fourBeforestring.equals("api_")) {
                    bindData.put(paramsKey, paramsValue);
                }
            }
        }

        return bindData;
    }

    /**
     * // 计算分页,返回 5,10 这种
     * @param count
     * @param page
     * @param perPage
     * @return
     */
    public String calcPagingString(Integer count, String page, String perPage){
        Integer nowPage = Integer.parseInt(page);  // 当前第几页
        Integer nowPerPage = Integer.parseInt(perPage); // 每页多少条
        Integer maxPage = count / nowPerPage + (count % nowPerPage != 0 ? 1 : 0);// 总数/每页多少条=最多多少页
        if (nowPage <= 1) {
            nowPage = 1;
        } else if (maxPage > 0 && nowPage >= maxPage) {
            nowPage = maxPage;
        }
        Integer startNum = (nowPage - 1) * nowPerPage;
        String limitAfter = startNum + "," + nowPerPage;

        return limitAfter;
    }

    public String getUUID(){
        return UUID.randomUUID().toString().replace("-", "");
    }

    /**
     * 获取文件后缀
     * @param fileName
     * @return
     */
    public String getSuffix(String fileName){
        return fileName.substring(fileName.lastIndexOf("."));
    }

    /**
     * 生成新的文件名
     * @param fileOriginName 源文件名
     * @return
     */
    public String getFileName(String fileOriginName){
        return this.getUUID() + this.getSuffix(fileOriginName);
    }

    //头像上传
    public Map uploadFile(MultipartFile file) {
        String value = "";
        Map map = new HashMap<>();
        if (file.isEmpty()) {
            map.put("sysErrorCode", "59000");
            return map;
        }
        try {
            //1.定义上传的文件
            String localPath = configUploadPath;
            //2.获得文件名字
            String fileName = file.getOriginalFilename();
            //3.上传
            //3.1 生成新的文件名
            String realPath = localPath + "/" + this.getFileName(fileName);
            //3.2 保存文件
            File dest = new File(realPath);
            //判断文件目目录是否存在,不存在则新建
            if (!dest.getParentFile().exists()){
                dest.getParentFile().mkdir();
            }
            file.transferTo(dest);
            value = realPath;
            map.put("uploadPath", value);
        } catch (Exception e) {
            e.printStackTrace();
            map.put("sysErrorCode", "59000");

            return map;
        }

        return map;
    }
}
