/**
 * BladeX Commercial License Agreement
 * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
 * <p>
 * Use of this software is governed by the Commercial License Agreement
 * obtained after purchasing a license from BladeX.
 * <p>
 * 1. This software is for development use only under a valid license
 * from BladeX.
 * <p>
 * 2. Redistribution of this software's source code to any third party
 * without a commercial license is strictly prohibited.
 * <p>
 * 3. Licensees may copyright their own code but cannot use segments
 * from this software for such purposes. Copyright of this software
 * remains with BladeX.
 * <p>
 * Using this software signifies agreement to this License, and the software
 * must not be used for illegal purposes.
 * <p>
 * Author: Chill Zhuang (bladejava@qq.com)
 */

package org.springblade.transport.support;

import org.springblade.core.log.exception.ServiceException;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tool.utils.Func;
import org.springblade.system.cache.SysCache;
import org.springblade.system.pojo.entity.Dept;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.Objects;
import java.util.regex.Pattern;

/**
 * 运输业务公共校验支持
 *
 * @author Chill
 */
public final class TransportBusinessSupport {

	private static final Pattern PHONE_PATTERN = Pattern.compile("^(1\\d{10}|0\\d{2,3}-?\\d{7,8})$");
	private static final BigDecimal MIN_LONGITUDE = new BigDecimal("-180");
	private static final BigDecimal MAX_LONGITUDE = new BigDecimal("180");
	private static final BigDecimal MIN_LATITUDE = new BigDecimal("-90");
	private static final BigDecimal MAX_LATITUDE = new BigDecimal("90");

	private TransportBusinessSupport() {
	}

	public static Long currentDeptId(String moduleName) {
		Long deptId = Func.firstLong(AuthUtil.getDeptId());
		if (Func.isEmpty(deptId) || deptId <= 0) {
			throw new ServiceException("当前用户所属组织为空，无法操作" + moduleName);
		}
		return deptId;
	}

	public static Dept currentDept(String moduleName) {
		Dept dept = SysCache.getDept(currentDeptId(moduleName));
		if (Func.isEmpty(dept)) {
			throw new ServiceException("当前用户所属组织异常，请重新登录后再试");
		}
		return dept;
	}

	public static void assertCurrentDept(Long deptId, String moduleName) {
		if (!Objects.equals(deptId, currentDeptId(moduleName))) {
			throw new ServiceException("无权操作其他组织" + moduleName);
		}
	}

	public static void validateAllDept(Integer allDept, String moduleName) {
		if (Objects.equals(allDept, 1) && !AuthUtil.isAdministrator()) {
			throw new ServiceException("无权查看全部组织" + moduleName);
		}
	}

	public static String trimToEmpty(String value) {
		return value == null ? "" : value.trim();
	}

	public static String trimToNull(String value) {
		String trimValue = trimToEmpty(value);
		return trimValue.isEmpty() ? null : trimValue;
	}

	public static void validateRequired(String value, String message) {
		if (Func.isEmpty(trimToNull(value))) {
			throw new ServiceException(message);
		}
	}

	public static void validateLength(String value, int maxLength, String message) {
		if (Func.isNotEmpty(value) && value.length() > maxLength) {
			throw new ServiceException(message);
		}
	}

	public static void validatePhone(String value, String message) {
		if (Func.isNotEmpty(value) && !PHONE_PATTERN.matcher(value).matches()) {
			throw new ServiceException(message);
		}
	}

	public static void validateCoordinate(BigDecimal value, boolean longitude) {
		if (Func.isEmpty(value)) {
			return;
		}
		BigDecimal min = longitude ? MIN_LONGITUDE : MIN_LATITUDE;
		BigDecimal max = longitude ? MAX_LONGITUDE : MAX_LATITUDE;
		if (value.compareTo(min) < 0 || value.compareTo(max) > 0) {
			throw new ServiceException(longitude ? "经度范围为 -180 到 180" : "纬度范围为 -90 到 90");
		}
	}

	public static void validateNonNegative(BigDecimal value, String fieldName) {
		if (Func.isNotEmpty(value) && value.compareTo(BigDecimal.ZERO) < 0) {
			throw new ServiceException(fieldName + "不能小于0");
		}
	}

	public static void validateDateRange(LocalDate startDate, LocalDate endDate, String message) {
		if (startDate != null && endDate != null && startDate.isAfter(endDate)) {
			throw new ServiceException(message);
		}
	}

}
