package org.springblade.common.utils;

import cn.hutool.core.math.MathUtil;
import com.google.common.collect.Maps;
import org.apache.commons.compress.utils.Lists;
import org.springblade.core.http.util.HttpUtil;
import org.springblade.core.tool.utils.CollectionUtil;
import org.springblade.core.tool.utils.DateUtil;
import org.springblade.core.tool.utils.DigestUtil;
import org.springblade.core.tool.utils.StringUtil;
import org.springblade.modules.nh.pojo.entity.MonitorInverterDailyStatEntity;
import org.springframework.util.ReflectionUtils;

import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.*;
import java.time.temporal.TemporalAdjusters;
import java.util.*;

/**
 * 通用工具类
 *
 * @author Chill
 */
public class CommonUtil {

	public static Double sum(Double num1, Double num2) {
		Double sum = 0D;
		if(num1!=null){
			sum = sum+num1;
		}
		if(num2!=null){
			sum = sum+num2;
		}
		return sum;
	}

	public static int getDaysInCurrentMonth() {
		// 获取当前日期
		LocalDate currentDate = LocalDate.now();
		// 获取当前月的最后一天
		LocalDate lastDayOfMonth = currentDate.with(TemporalAdjusters.lastDayOfMonth());
		// 返回当前月的天数
		return lastDayOfMonth.getDayOfMonth();
	}

	public static List<String> splitOutStationIds(String outStationIds) {
		if(StringUtil.isBlank(outStationIds)) return null;
		String[] arr =  outStationIds.split(",");
		return Arrays.asList(arr);
	}

	public static List<Object> retainNum(List<Object> list, int num) {
		List<Object> result = Lists.newArrayList();
		if(CollectionUtil.isEmpty(list)){
			return list;
		}
		for(Object item : list){
			if(item instanceof  Double){
				String formattedValue = String.format("%."+num+"f", item);
				result.add(formattedValue);
			}else{
				result.add(item);
			}
		};
		return result;
	}

	public static Double retainDoubleNum(Double e, int num) {
		String formattedValue = String.format("%."+num+"f", e);
		return Double.parseDouble(formattedValue);
	}

	public static boolean monthBeginLessThanDays(int days, Date baseDate) {
		int date = baseDate.getDate();
		return date <= days;
	}
	public static boolean yearBeginLessThanDays(int days, Date baseDate) {
		Calendar c = Calendar.getInstance();
		c.setTime(baseDate);
		return c.get(Calendar.DAY_OF_YEAR) <= days;
	}

	public static List<String> hourListFrom0() {
		List<String> ret = new ArrayList<>();
		for (int i = 0; i < 24; i++) {
			ret.add(String.format("%d:00", i));
		}
		return ret;
	}

	public static List<String> hourListFrom1() {
		List<String> ret = new ArrayList<>();
		for (int i = 0; i < 24; i++) {
			ret.add(String.format("%02d", i + 1));
		}
		return ret;
	}

	public static Double getDoubleByFile(Class<?> clazz, MonitorInverterDailyStatEntity entity, String key) {
		Double ret=null;
		try{
			Field field = clazz.getDeclaredField(key);
			field.setAccessible(true);

			Object value = field.get(entity);
			return (Double) value;
		}catch (Exception e){
			e.printStackTrace();
		}

		return ret;
	}

	public static List<Double> repeatNum(int ticks, Double val) {
		List<Double> ret = new ArrayList<>();
		for (int i = 0; i < ticks; i++) {
			ret.add(val);
		}
		return ret;
	}

	public static String queryWeather(String area){
		String host = "https://weather01.market.alicloudapi.com";
		String path = "/area-to-weather";
		String method = "GET";
		String appcode = "84f9472ee67349189cd5f61c1805a430";
		Map<String, String> headers = Maps.newHashMap();
		//最后在header中的格式(中间是英文空格)为Authorization:APPCODE 83359fd73fe94948385f570e3c139105
		headers.put("Authorization", "APPCODE " + appcode);
		Map<String, Object> querys = Maps.newHashMap();
		querys.put("area", area);
		querys.put("need3HourForcast", "0");
		querys.put("needAlarm", "0");
		querys.put("needHourData", "0");
		querys.put("needIndex", "0");
		querys.put("needMoreDay", "0");
		return HttpUtil.get(host+path,headers,querys);
	}

	public static String queryWeatherByMonth(String area,String month){
		String host = "https://weather01.market.alicloudapi.com";
		String path = "/weatherhistory";
		String method = "GET";
		String appcode = "84f9472ee67349189cd5f61c1805a430";
		Map<String, String> headers = Maps.newHashMap();
		//最后在header中的格式(中间是英文空格)为Authorization:APPCODE 83359fd73fe94948385f570e3c139105
		headers.put("Authorization", "APPCODE " + appcode);
		Map<String, Object> querys = Maps.newHashMap();
		querys.put("area", area);
		querys.put("month", month);
		return HttpUtil.get(host+path,headers,querys);
	}

	public static void reflectSetField(Object r, String fieldName, Object value) {
		try{
			Field field= r.getClass().getDeclaredField(fieldName);
			ReflectionUtils.makeAccessible(field);
			ReflectionUtils.setField(field, r,value);
		}catch (Exception e){
			e.printStackTrace();
		}
	}
	public static Object reflectGetField(Object r, String fieldName) {
		try{
			Field field= r.getClass().getDeclaredField(fieldName);
			ReflectionUtils.makeAccessible(field);
			return ReflectionUtils.getField(field, r);
		}catch (Exception e){

		}
		return null;
	}

	public static BigDecimal getPreHourMax(Map<String, Object> resMap, int hour) {
		BigDecimal max = BigDecimal.ZERO;
		for(int i=(hour-1); i>0; i--){
			BigDecimal bigDecimal = new BigDecimal(resMap.get("h" + i).toString());
			if(bigDecimal!=null && bigDecimal.compareTo(max) > 0){
				max = bigDecimal;
			}
		}
		return max;
	}

	public static  String assembleIUData(String ukey,String iKey,int max,Object detail){
		List<String> list = Lists.newArrayList();
		for(int i=1;i<=max;i++){
			Object iPvObj = CommonUtil.reflectGetField(detail,iKey+i);
			Object uPvObj = CommonUtil.reflectGetField(detail,ukey+i);
			if(iPvObj==null||uPvObj==null){
				break;
			}
			if(iPvObj.equals(0d) && uPvObj.equals(0d)){
				break;
			}
			list.add(uPvObj+":"+iPvObj);
		}
		return String.join("|", list);
	}

	public static  void copyFieldToOther(Object sourceObj,String sourceField,Object toObj,String toField){
		Object sourceVal = CommonUtil.reflectGetField(sourceObj,sourceField);
		CommonUtil.reflectSetField(toObj,toField,sourceVal);
	}

	/**
	 * @param start
	 * @return
	 */
	public static  String calDuringToNow(Date start){

		String today = DateUtil.format(new Date(),"yyyyMMdd");
		Date startDate = DateUtil.parse(today+"080000","yyyyMMddHHmmss");

		if(start==null){
			start = startDate;
		}

		if(start.after(startDate)){
			startDate = start;
		}

		Long now = System.currentTimeMillis();
		Long startTime = startDate.getTime();
		long during = (now - startTime)/1000;
		return convertDuring(during);
	}

	public static  String convertDuring(Long during){
		if(during==null){
			return "";
		}
		long day = during/(24*3600);
		during = during%(24*3600);
		long hour = during/3600;
		during = during%(3600);
		long min = during/60;

		StringBuilder sb = new StringBuilder();
		if(day>0){
			sb.append(day+"天");
		}
		if(hour>0){
			sb.append(hour+"时");
		}
		if(min>0){
			sb.append(min+"分");
		}
		return sb.toString();
	}

	public static int getVendorIndex(Map<String, Object> ctx){
		if(ctx.containsKey("index")){
			int index = (int) ctx.get("index");
			return index;
		}else{
			return 1;
		}
	}

	public static Map<String,Object> getCtx(int i){
		Map<String, Object> ctx = Maps.newHashMap();
		ctx.put("index",i);
		return ctx;
	}

	public static List<String> assembleIdsList(List<String> list,int size) {
		List<String> result = Lists.newArrayList();
		int page = list.size()/size;
		if(list.size()%size>0){
			page++;
		}
		for(int i=0;i<page;i++){
			int last = (i+1)*size;
			if(last>=list.size()){
				last = list.size();
			}
			List<String> sublist = list.subList(i*size,last);
			result.add(StringUtil.join(sublist,","));
		}
		return result;
	}

	public static Double round(Double number,int precision) {
		BigDecimal bigDecimal = new BigDecimal(number);
		// 四舍五入到两位有效数字
		bigDecimal = bigDecimal.round(new java.math.MathContext(precision, RoundingMode.HALF_UP));
		// 转换回double类型
		return bigDecimal.doubleValue();
	}

	public static Double setScale(Double number,int precision) {
		BigDecimal bigDecimal = new BigDecimal(number);
		// 四舍五入到两位有效数字
		bigDecimal = bigDecimal.setScale(precision,RoundingMode.HALF_UP);
		// 转换回double类型
		return bigDecimal.doubleValue();
	}
	public static boolean isOutTime(Long time,int min){
		if(time==null) return true;

		long during = System.currentTimeMillis() - time;
		//超过15分钟
		if(during>min*60*1000){
			return true;
		}

		return false;
	}

	public static Date getNowHour(){
		// 获取当前日期和时间
		LocalDateTime now = LocalDateTime.now();
		int c = now.getMinute()/15;
		// 获取当前小时的整点时间
		LocalTime currentHour = LocalTime.of(now.getHour(), c*15);
		LocalDateTime currentHourDateTime = LocalDateTime.of(now.toLocalDate(), currentHour);
		// 将LocalDateTime转换为ZonedDateTime
		ZonedDateTime zonedDateTime = currentHourDateTime.atZone(ZoneId.systemDefault());
		Instant instant = zonedDateTime.toInstant();
		// 将Instant转换为Date
		Date date = Date.from(instant);
		return date;
	}

	public static String genSign(Map<String, ?> paramMap){
		TreeMap<String, Object> treeMap = Maps.newTreeMap();
		paramMap.forEach((key, value) -> {
			treeMap.put(key, value);
		});
		return genSign(treeMap);
	}

	/**
	 * Generate Sign
	 * @return String
	 */
	public static String genSign(TreeMap<String, Object> paramMap) {
		StringBuilder data = new StringBuilder();
		paramMap.forEach((key, value) -> {
			if (StringUtil.isNotBlank(data.toString())) {
				data.append(",");
			}
			data.append(key).append("=").append(value);
		});
		try {
			return DigestUtil.sha256Hex(data.toString());
		} catch (Exception e) {
			return null;
		}
	}

	public static void main(String[] args) {
//		{
//			"aqiLevel": "1",
//			"wind_direction": "无持续风向",
//			"aqi": "40",
//			"wind_power": "微风",
//			"area": "丽江",
//			"time": "20160101",
//			"min_temperature": "1",
//			"max_temperature": "15",
//			"aqiInfo": "优",
//			"weather": "多云"
//		},
//		System.out.println(queryWeatherByMonth("合肥","202405"));
//		System.out.println(DateUtil.formatDateTime(getNowHour()));
		TreeMap<String, Object> paramMap = Maps.newTreeMap();
		paramMap.put("appId", "123456789");
		System.out.println(genSign(paramMap));
	}
}
