package incheon.cmm.g2f;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

public abstract class RegexPatterns {

	/**
	 * 이메일 주소를 검증하는 정규 표현식
	 * 이메일 주소는 다음 조건을 만족해야 합니다:
	 * - 영문, 숫자, 하이픈(-), 밑줄(_) 등을 포함할 수 있습니다.
	 * - '@' 기호가 포함되어야 하며, 뒤에는 도메인 이름이 와야 합니다.
	 * - 도메인 이름은 '.'(점)으로 구분된 두 부분 이상이어야 합니다.
	 */
	public static final String EMAIL = "^[a-zA-Z0-9_+&*-]+(?:\\.[a-zA-Z0-9_+&*-]+)*@(?:[a-zA-Z0-9-]+\\.)+[a-zA-Z]{2,7}$";

	/**
	 * 전화번호를 검증하는 정규 표현식
	 * 전화번호는 다음 형식을 만족합니다:
	 * - 숫자로만 이루어져 있으며, 길이는 10~11자리.
	 * - 첫 번째 자리는 '0'이어야 하며, 두 번째 자리는 '1'로 시작할 수 있습니다.
	 * - 예시: 010-1234-5678, 02-123-4567
	 */
	public static final String PHONE_NUMBER = "^(\\d{2,3})-(\\d{3,4})-(\\d{4})$";

	/**
	 * URL을 검증하는 정규 표현식
	 * URL은 다음 조건을 만족해야 합니다:
	 * - 'http' 또는 'https'로 시작해야 하며, '://'
	 * - 도메인 이름과 경로를 포함할 수 있습니다.
	 * - 예시: https://www.example.com, http://example.com/path/to/resource
	 */
	public static final String URL = "^(https?)://[a-zA-Z0-9-]+(?:\\.[a-zA-Z0-9-]+)*(?:/[a-zA-Z0-9_?&=.-]*)*$";

	/**
	 * 숫자만 포함된 문자열을 검증하는 정규 표현식
	 * - 문자열은 숫자만 포함해야 하며, 빈 문자열은 허용하지 않습니다.
	 * - 예시: 12345, 6789
	 */
	public static final String DIGITS_ONLY = "^\\d+$";

	/**
	 * 공백을 포함하지 않은 문자열을 검증하는 정규 표현식
	 * - 문자열에 공백이 포함되지 않아야 합니다.
	 * - 예시: hello, abc123
	 */
	public static final String NO_WHITESPACE = "^\\S+$";

	/**
	 * 대소문자와 숫자가 혼합된 비밀번호를 검증하는 정규 표현식
	 * - 최소 8자, 최대 20자
	 * - 최소 하나의 대문자, 하나의 소문자, 하나의 숫자가 포함되어야 합니다.
	 * - 예시: Abcd1234, P@ssw0rd
	 */
	public static final String PASSWORD = "^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)[A-Za-z\\d]{8,20}$";

	/**
	 * 날짜(YYYY-MM-DD) 형식을 검증하는 정규 표현식
	 * - 날짜는 'YYYY-MM-DD' 형식을 따라야 하며, 유효한 날짜만 포함합니다.
	 * - 예시: 2021-12-31, 2022-02-28
	 */
	public static final String DATE = "^(?:19|20)\\d\\d-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12][0-9]|3[01])$";

	/**
	 * IP 주소를 검증하는 정규 표현식
	 * - IP 주소는 '0-255' 범위의 숫자가 4개, 각 숫자는 '.'으로 구분됩니다.
	 * - 예시: 192.168.0.1, 255.255.255.255
	 */
	public static final String IP_ADDRESS = "^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$";

	/**
	 * 영문 소문자와 공백을 포함하는 문자열을 검증하는 정규 표현식
	 * - 영문 소문자만 포함되며, 공백도 허용됩니다.
	 * - 예시: hello world, abc def
	 */
	public static final String LOWERCASE_WITH_WHITESPACE = "^[a-z\\s]+$";

	/**
	 * 특정 문자열이 포함된 이메일 주소를 검증하는 정규 표현식
	 * - 예시: 특정 도메인(예: 'gmail.com')을 포함하는 이메일 주소를 찾을 때 유용합니다.
	 * - 예시: user@gmail.com, admin@example.com
	 */
	public static final String EMAIL_WITH_SPECIFIC_DOMAIN = "^[a-zA-Z0-9_+&*-]+(?:\\.[a-zA-Z0-9_+&*-]+)*@gmail\\.com$";


	/**
	 * 12시간 형식의 시간 (AM/PM)을 검증하는 정규 표현식
	 * - 시간은 01-12 사이로, 분은 00-59, 초는 00-59입니다.
	 * - AM 또는 PM이 붙습니다.
	 * - 예시: 08:30:45 AM, 10:45:59 PM
	 */
	public static final String TIME_12H_FORMAT = "^(0[1-9]|1[0-2]):([0-5][0-9]):([0-5][0-9]) (AM|PM)$";

	/**
	 * 24시간 형식의 시간 (HH:mm:ss)을 검증하는 정규 표현식
	 * - 시간은 00-23 사이로, 분은 00-59, 초는 00-59입니다.
	 * - 예시: 08:30:45, 14:59:59
	 */
	public static final String TIME_24H_FORMAT = "^([01][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$";

	/**
	 * 날짜와 시간을 함께 검증하는 정규 표현식 (YYYY-MM-DD HH:mm:ss)
	 * - 날짜는 'YYYY-MM-DD' 형식, 시간은 24시간 형식의 'HH:mm:ss'입니다.
	 * - 예시: 2021-12-31 14:30:45
	 */
	public static final String DATETIME_24H_FORMAT = "^(?:19|20)\\d\\d-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12][0-9]|3[01]) ([01][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$";

	/**
	 * 날짜와 시간을 함께 검증하는 정규 표현식 (YYYY/MM/DD HH:mm:ss)
	 * - 날짜는 'YYYY/MM/DD' 형식, 시간은 24시간 형식의 'HH:mm:ss'입니다.
	 * - 예시: 2021/12/31 14:30:45
	 */
	public static final String DATETIME_24H_FORMAT_SLASH = "^(?:19|20)\\d\\d/(?:0[1-9]|1[0-2])/(?:0[1-9]|[12][0-9]|3[01]) ([01][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$";

	/**
	 * UTC 시간대 형식 (YYYY-MM-DDTHH:mm:ssZ)을 검증하는 정규 표현식
	 * - 날짜는 'YYYY-MM-DD' 형식, 시간은 24시간 형식의 'HH:mm:ss'입니다.
	 * - UTC 시간대를 나타내는 'Z'가 뒤에 붙습니다.
	 * - 예시: 2021-12-31T14:30:45Z
	 */
	public static final String UTC_DATETIME = "^(?:19|20)\\d\\d-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])Z$";

	/**
	 * Unix 타임스탬프 (1970-01-01 00:00:00부터 경과한 초)를 검증하는 정규 표현식
	 * - 숫자만 포함된 정수 값이어야 합니다.
	 * - 예시: 1630385915
	 */
	public static final String UNIX_TIMESTAMP = "^\\d+$";

	/**
	 * 연/월/일 형식의 날짜를 검증하는 정규 표현식 (YYYY/MM/DD)
	 * - 날짜는 'YYYY/MM/DD' 형식이어야 합니다.
	 * - 예시: 2021/12/31, 2022/02/28
	 */
	public static final String DATE_SLASH_FORMAT = "^(?:19|20)\\d\\d/(?:0[1-9]|1[0-2])/(?:0[1-9]|[12][0-9]|3[01])$";

	/**
	 * ISO 8601 형식의 날짜 (YYYY-MM-DD)를 검증하는 정규 표현식
	 * - 날짜는 'YYYY-MM-DD' 형식이어야 하며, 유효한 날짜만 포함됩니다.
	 * - 예시: 2021-12-31, 2022-02-28
	 */
	public static final String ISO_DATE_FORMAT = "^(?:19|20)\\d\\d-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12][0-9]|3[01])$";

	/**
	 * RFC 3339 형식의 날짜 (YYYY-MM-DDTHH:mm:ss±hh:mm)을 검증하는 정규 표현식
	 * - 날짜와 시간은 'YYYY-MM-DDTHH:mm:ss' 형식이어야 하며, 타임존 오프셋은 '±hh:mm' 형식으로 포함됩니다.
	 * - 예시: 2021-12-31T14:30:45+09:00
	 */
	public static final String RFC3339_DATETIME = "^(?:19|20)\\d\\d-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])([+-](?:0[0-9]|1[0-3]):[0-5][0-9])$";


	public static Map<String, String> getStaticFieldsMap() throws IllegalAccessException {
		Map<String, String> fieldMap = new HashMap<>();

		// 클래스의 모든 필드들을 가져옴
		Field[] fields = RegexPatterns.class.getDeclaredFields();

		for (Field field : fields) {
			// public static String 필드만 처리
			if (java.lang.reflect.Modifier.isPublic(field.getModifiers()) && java.lang.reflect.Modifier.isStatic(field.getModifiers()) && field.getType() == String.class) {
				// 필드 이름과 값을 Map에 추가
				fieldMap.put(field.getName(), (String) field.get(null)); // static 필드이므로 null을 첫 번째 인자로
			}
		}

		return fieldMap;

	}
}