package cn.kk.spring_simple_operation.utils;

import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.client.HttpClientErrorException;

import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.time.Instant;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.function.Function;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * @description:
 * @author: Devin
 * @date: 2022-12-21
 */
public class CommonUtils {

	private static final String[] EXCEL_ARRAY = new String[]{"xls", "xlsx"};

	/**
	 * 判断是否为整数
	 *
	 * @param str 传入的字符串
	 * @return 是整数返回true, 否则返回false
	 */
	public static boolean isInteger(String str) {
		Pattern pattern = Pattern.compile("^[-\\+]?[\\d]*$");
		return pattern.matcher(str).matches();
	}

	/**
	 * 判断是否为null或者为0
	 *
	 * @param number 传入的数字
	 * @return 是null或者0,返回true,否则false
	 */
	public static boolean isNullOrZero(Number number) {
		return null == number || 0 == number.intValue();
	}

	/**
	 * 判断数值是否大于0
	 *
	 * @param number
	 * @return
	 */
	public static boolean isGtZero(Object number) {
		if (null == number) return false;
		if (number instanceof BigDecimal) {
			return ((BigDecimal) number).compareTo(BigDecimal.ZERO) > 0;
		}
		else if (number instanceof Number) {
			return ((Number) number).doubleValue() > 0;
		}
		return false;
	}

	public static Object getValue(Object object, String fieldName) {
		try {
			Field field = object.getClass().getDeclaredField(fieldName);
			field.setAccessible(true);
			return field.get(object);
		} catch (NoSuchFieldException e) {

		} catch (IllegalAccessException e) {

		}
		return null;
	}

	/**
	 * @Description: 获取文件名称的后缀名
	 * @Param: 文件名
	 * @return: 后缀名
	 * @Author: guokk
	 * @date: 2023/5/12
	 */
	public static String getFileExtension(String filePath) {
		int dotIndex = filePath.lastIndexOf('.');
		if (dotIndex == -1 || dotIndex == filePath.length() - 1) {
			// 如果没有找到'.',或者'.'是最后一个字符
			return "";
		}
		return filePath.substring(dotIndex + 1);
	}

	/**
	 * @Description: 判断文件是否是excel
	 * @Param: 文件名
	 * @return: true:是excel文件
	 * @Author: guokk
	 * @date: 2023/5/12
	 */
	public static Boolean isExcel(String filePath) {
		String fileExtension = getFileExtension(filePath);
		for (String s : EXCEL_ARRAY) {
			if (s.equals(fileExtension)) {
				return true;
			}
		}
		return false;
	}


	public static String getRegion(String region) {
		if (StringUtils.isEmpty(region)) {
			return "";
		}
		if (region.contains("深圳")) {
			return "深圳";
		}
		else if (region.contains("武汉")) {
			return "武汉";
		}
		else if (region.contains("合肥")) {
			return "合肥";
		}
		else if (region.contains("长沙")) {
			return "长沙";
		}
		else if (region.contains("香港")) {
			return "香港";
		}
		else if (region.contains("广州")) {
			return "广州";
		}
		else {
			return "深圳";
		}
	}


	public static List<String> getRegionList(String region) {
		if (StringUtils.isEmpty(region)) {
			return Collections.emptyList();
		}
		List<String> list = new LinkedList<>();
		switch (region) {
			case "合肥":
				list.add("合肥");
				break;
			case "武汉":
				list.add("武汉");
				break;
			case "长沙":
				list.add("长沙");
				break;
			case "广州":
				list.add("广州");
				break;
			case "香港":
				list.add("香港");
				break;
			default:
				list.add("深圳");
				list.add("微谷");
		}
		return list;
	}

	public static String defaultString(String str, String defaultStr) {
		return str == null || str.trim().length() == 0 ? defaultStr : str;
	}

	public static boolean isNumeric(String str) {
		if (str == null || str.length() == 0) {
			return false;
		}
		for (int i = 0; i < str.length(); i++) {
			if (!Character.isDigit(str.charAt(i))) {
				return false;
			}
		}
		return true;
	}


	public static Boolean securityCheck(String md5, String prefix, Long time) {
		if (StringUtils.isEmpty(md5) || Objects.isNull(time)) {
			return false;
		}
		if (StringUtils.isEmpty(prefix)) {
			prefix = "";
		}
		try {
			MessageDigest md = MessageDigest.getInstance("MD5");
			byte[] bytes = md.digest((prefix + time).getBytes());
			StringBuilder sb = new StringBuilder();
			for (byte b : bytes) {
				// 将每个字节转换为两位十六进制数,并追加到结果字符串上
				sb.append(String.format("%02x", b));
			}
			return sb.toString().equals(md5);
		} catch (NoSuchAlgorithmException e) {
			return false;
		}
	}

	public static Boolean eq(Number number1, Number number2) {
		if (number1 == null || number2 == null) {
			return Boolean.FALSE;
		}
		return number1.intValue() == number2.intValue();
	}

	public static Boolean ne(Number number1, Number number2) {
		if (number1 == null || number2 == null) {
			return Boolean.FALSE;
		}
		return number1.intValue() != number2.intValue();
	}

	public static <T> List<T> emptyList() {
		return new LinkedList<>();
	}

	public static <T> List<T> singletonList(T o) {
		List<T> list = new LinkedList<>();
		list.add(o);
		return list;
	}

	@SafeVarargs
	public static <T> List<T> lists(T... args) {
		if (Objects.isNull(args) || args.length == 0) {
			throw new RuntimeException("请传入有效的参数!");
		}
		List<T> list = new LinkedList<>();
		for (T arg : args) {
			list.add(arg);
		}
		return list;
	}

	/**
	 * 将秒级时间戳格式化输出字符串
	 *
	 * @param backlogStartTimestamp 起始时间戳
	 * @param backlogEndTimestamp   结束时间戳
	 * @param format                格式   如:yyyy-MM
	 * @param offset                时间间隔:天
	 * @return
	 */
	public static List<String> format10(Integer backlogStartTimestamp, Integer backlogEndTimestamp, String format, Long offset) {
		// 将时间戳转换成Instant对象
		Instant startInstant = Instant.ofEpochSecond(backlogStartTimestamp);
		Instant endInstant = Instant.ofEpochSecond(backlogEndTimestamp);

		// 可选:转换时区(若不需要时区转换,可跳过此步骤)
		ZoneId zoneId = ZoneId.systemDefault(); // 或者使用ZoneId.of("时区代码")指定特定时区
		LocalDate startDate = startInstant.atZone(zoneId).toLocalDate();
		LocalDate endDate = endInstant.atZone(zoneId).toLocalDate();

		// 使用Stream生成日期范围并输出
		DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern(format);
		Set<String> dateList = new HashSet<>(16);
		do {
			String dateString = startDate.format(dateFormatter);
			dateList.add(dateString);
			startDate = startDate.plusDays(offset);
		} while ((startDate.toEpochDay() <= endDate.toEpochDay()));

		return new LinkedList<>(dateList);
	}


	public static List<String> distinctSplit(List<String> list, String split) {
		if (StringUtils.isEmpty(split)) {
			split = ",";
		}
		Set<String> set = new HashSet<>(16);
		String finalSplit = split;
		list.stream().filter(t -> !StringUtils.isEmpty(t)).forEach(l -> {
			String[] split1 = l.split(finalSplit);
			set.addAll(Arrays.stream(split1).filter(t -> !StringUtils.isEmpty(t)).collect(Collectors.toList()));
		});
		return new LinkedList<>(set);
	}

	/**
	 * A+/视频策划  根据标签获取对应的权重
	 * 普通A+/视频默认1,高级A+默认 1.5,A+/视频优化默认0.2;A+品牌故事默认1/3(展示在页面默认保留两位小数)
	 *
	 * @param vdtId
	 * @return
	 */
	public static BigDecimal getWeight(Long vdtId) {
		if (isNullOrZero(vdtId)) {
			return BigDecimal.ZERO;
		}
		switch (vdtId.intValue()) {
			case 2:
			case 67:
			case 82:
			case 83:
			case 107:
				return BigDecimal.ONE;
			case 68:
				return new BigDecimal("1.5");
			case 73:
			case 74:
				return new BigDecimal("0.2");
			case 80:
				return new BigDecimal("0.333");
			case 66:
				return new BigDecimal("0.5");
			default:
				return BigDecimal.ZERO;
		}
	}

	public static <T, R> R dealHttp(Function<T, R> function, T dto) {
		R apply = null;
		if (function == null) {
			return null;
		}
		try {
			apply = function.apply(dto);
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e1) {
				throw new RuntimeException("获取sku销量休眠失败!", e1);
			}
		} catch (HttpClientErrorException e) {
			try {
				Thread.sleep(60000);
			} catch (InterruptedException e1) {
				throw new RuntimeException("获取sku销量休眠失败!", e1);
			}
			apply = function.apply(dto);
		}
		return apply;
	}

	public static boolean isToday(Integer timestamp) {
		if (CommonUtils.isNullOrZero(timestamp)) {
			return false;
		}
		Integer currentTimeSecond = DateUtils.getCurrentTimeSecond();
		Integer startOfDay = DateUtils.getStartOfDay(currentTimeSecond);
		Integer endOfDay = DateUtils.getEndOfDay(currentTimeSecond);
		return timestamp >= startOfDay && timestamp <= endOfDay;
	}

	/**
	 * 判断list1是否包含list2的所有元素
	 *
	 * @param list1
	 * @param list2
	 * @return boolean
	 */
	public static boolean allInclusive(Collection<Long> list1, Collection<Long> list2) {
		if (CollectionUtils.isEmpty(list1) || CollectionUtils.isEmpty(list2)) {
			return false;
		}
		for (Long l : list2) {
			if (!list1.contains(l)) {
				return false;
			}
		}
		return true;
	}

	public static boolean isCurrentMonth(Integer createTime) {
		String month = DateUtils.formatTimeSecond(createTime, "yyyy-MM");
		String currentMonth = DateUtils.formatTimeSecond(DateUtils.getCurrentTimeSecond(), "yyyy-MM");
		return month.equals(currentMonth);
	}
}