<template>
	<el-dialog :title="props.rowData?.id ? '修改规则' : '新增规则'" width="1000" v-model="props.open"
		:close-on-click-modal="false" :destroy-on-close="true" @close="onCancel" draggable>
		<div class="w-full ml-[-8px]">
			<el-form ref="ruleFormRef" :model="formData" :rules="dataRules" label-width="90px" class="flex flex-wrap">
				<el-form-item label="规则名称" prop="ruleName" class="w-1/3">
					<el-input v-model="formData.ruleName" type="text" placeholder="请输入规则名称" />
				</el-form-item>
			</el-form>
			<div class="px-4 rounded overflow-y-auto mt-4" style="max-height: calc(100vh - 350px)">
				<div class="flex items-start">
					<label class="w-[65px] leading-8 text-right"><span class="text-[#f56c6c] mr-1">*</span> 关键字</label>
					<div class="flex gap-2 ml-2 flex-wrap w-57vw]">
						<el-tag v-for="tag in keywordData" :key="tag" size="large" closable :disable-transitions="false"
							@close="handleClose(tag, 'keyword')">
							{{ tag }}
						</el-tag>
						<el-input v-if="inputVisible" ref="InputRef" v-model="inputValue" class="!w-32"
							@keyup.enter="handleInputConfirm('keyword')" @blur="handleInputConfirm('keyword')" />
						<el-button v-else class="button-new-tag" @click="showInput"> 添加关键字</el-button>
						<!-- 注册隐藏的表单项以启用校验 -->
						<el-form-item prop="keyword" style="display:none;"></el-form-item>
					</div>
				</div>
			</div>
			<div class="px-4 rounded overflow-y-auto mt-4" style="max-height: calc(100vh - 350px)">
				<div class="flex items-start">
					<label class="w-[65px] leading-8 text-right">IP</label>
					<div class="flex gap-2 ml-2 flex-wrap w-57vw]">
						<el-tag v-for="tag in ipData" :key="tag" size="large" closable :disable-transitions="false"
							@close="handleClose(tag, 'ip')">
							{{ tag }}
						</el-tag>
						<el-input v-if="ipInputVisible" ref="ipInputRef" v-model="ipInputValue" class="!w-32"
							@keyup.enter="handleInputConfirm('ip')" @blur="handleInputConfirm('ip')" />
						<el-button v-else class="button-new-tag" @click="showIpInput"> 添加IP</el-button>
						<!-- 注册隐藏的表单项以启用校验 -->
						<el-form-item prop="ip" style="display:none;"></el-form-item>
					</div>
				</div>
			</div>

			<div class="px-4 rounded overflow-y-auto mt-4" style="max-height: calc(100vh - 350px)">
				<div class="flex items-start">
					<label class="w-[66px] leading-8 text-right">添加域名</label>
					<div class="flex gap-2 ml-2 flex-wrap w-57vw]">
						<el-tag v-for="tag in domainData" :key="tag" size="large" closable :disable-transitions="false"
							@close="handleClose(tag, 'domain')">
							{{ tag }}
						</el-tag>
						<el-input v-if="domainInputVisible" ref="domainInputRef" v-model="domainInputValue"
							class="!w-32" @keyup.enter="handleInputConfirm('domain')"
							@blur="handleInputConfirm('domain')" placeholder="如: example.com" />
						<el-button v-else class="button-new-tag" @click="showDomainInput"> 添加域名</el-button>
						<!-- 注册隐藏的表单项以启用校验 -->
						<el-form-item prop="domain" style="display:none;"></el-form-item>
					</div>
				</div>
			</div>
			<el-form ref="ruleFormRef" :model="formData" :rules="dataRules" label-width="90px"
				class="flex flex-wrap mt-4">
				<el-form-item label="推送方式" prop="action" class="w-1/2">
					<JDictSelect v-model:value="formData.action" placeholder="请选择推送方式" :dictType="'pushMode'"
						:selectFirst="true" :styleClass="'w-full'" />
				</el-form-item>

				<el-form-item label="推送频率" prop="pushFrequency" class="w-1/2">
					<el-input v-model="formData.pushFrequency" type="text" placeholder="请输入推送频率" />
				</el-form-item>
				<el-form-item label="推送图片" prop="pushContent" class="w-1/2 ">
					<div class="flex items-start">
						<el-switch v-model="formData.pushType" class="mr-2"
							@change="oldUrl = formData.pushContent, formData.pushContent = ''" />
						<Image v-if="formData.pushType" @change="success" :imageUrl="formData.pushContent"
							@update="success" />
					</div>
				</el-form-item>

				<el-form-item v-if="!formData.pushType" label="推送内容" prop="pushContent" class="w-full">
					<el-input v-model="formData.pushContent" type="textarea" placeholder="请输入推送内容" />
				</el-form-item>
				<el-form-item label="备注" prop="remark" class="w-full">
					<el-input v-model="formData.remark" type="textarea" placeholder="请输入备注" />
				</el-form-item>
			</el-form>
		</div>
		<template #footer>
			<span class="dialog-footer">
				<el-button @click="onCancel">{{ t('common.cancelButtonText') }}</el-button>
				<el-button type="primary" @click="onSubmit"
					:disabled="loading">{{ t('common.confirmButtonText') }}</el-button>
			</span>
		</template>
	</el-dialog>
</template>

<script setup name="Edit" lang="ts">
import { update } from '/@/api/marketing/rules';
import { useI18n } from 'vue-i18n';
import { useMessage } from '/@/hooks/message';
let baseURL = import.meta.env.VITE_API_URL;

// 定义子组件向父组件传值/事件
const emit = defineEmits(['update:open', 'onsuccess']);

const props = defineProps({
	open: {
		type: Boolean,
		default: false,
	},
	rowData: {
		type: Object,
		default: () => { },
	},
});
const onCancel = () => {
	emit('update:open', false);
};
const oldUrl = ref('');
const success = (val: string) => {
	formData.value.pushContent = val;
};

// 引入组件
const JDictSelect = defineAsyncComponent(() => import('/@/components/JDictSelect/index.vue'));
const Image = defineAsyncComponent(() => import('/@/components/Upload/Image.vue'));
const { t } = useI18n();
// 定义变量内容

const loading = ref(false);

const ruleFormRef = ref();
interface FormDataType {
	ruleName: string;
	keyword: string[];
	ip: string[];
	domain: string[];
	pushContent: string;
	pushFrequency: string;
	action: string;
	remark: string;
	pushType: boolean;
}

const formData = ref<FormDataType>({
	ruleName: '',
	keyword: [],
	ip: [],
	domain: [],
	pushContent: '',
	pushFrequency: '',
	action: '1',
	remark: '',
	pushType: false,
});

// // 表单校验规则
const dataRules = reactive({
	ruleName: [{ required: true, message: '规则名称不能为空', trigger: 'blur' }],
	keyword: [
		{
			required: true,
			validator: (rule: any, value: any, callback: any) => {
				if (!keywordData.value || keywordData.value.length === 0) {
					callback(new Error('关键字不能为空'));
				} else {
					callback();
				}
			},
			trigger: 'blur',
		},
	],
	pushContent: [{ required: true, message: '推送内容不能为空', trigger: 'blur' }],
	ip: [
		{
			validator: (rule: any, value: any, callback: any) => {
				if (!ipData.value || ipData.value.length === 0) {
					callback(new Error('IP不能为空'));
				} else {
					callback();
				}
			},
			trigger: 'blur',
		},
	],
	domain: [
		{
			validator: (rule: any, value: any, callback: any) => {
				if (!domainData.value || domainData.value.length === 0) {
					callback(new Error('域名不能为空'));
				} else {
					callback();
				}
			},
			trigger: 'blur',
		},
	],
	pushFrequency: [
		{ required: true, message: '推送频率不能为空', trigger: 'blur' },
		{
			pattern: /^(10000|[1-9]\d{0,3}|0)$|^(100%|[1-9]?\d%|0%)$/,
			message: '请输入 0-10000 的正整数或 0%-100% 的百分比',
			trigger: 'blur',
		},
	],
});

//tab相关

const inputValue = ref('');
const ipInputValue = ref('');
const domainInputValue = ref('');

const inputVisible = ref(false);
const ipInputVisible = ref(false);
const domainInputVisible = ref(false);

const InputRef = ref();
const ipInputRef = ref();
const domainInputRef = ref();

const keywordData = ref<string[]>([]);
const ipData = ref<string[]>([]);
const domainData = ref<string[]>([]);

const showInput = () => {
	inputVisible.value = true;
	nextTick(() => {
		InputRef.value!.input!.focus();
	});
};
const showIpInput = () => {
	ipInputVisible.value = true;
	nextTick(() => {
		ipInputRef.value!.input!.focus();
	});
};
const showDomainInput = () => {
	domainInputVisible.value = true;
	nextTick(() => {
		domainInputRef.value!.input!.focus();
	});
};
const handleClose = (tag: string, type: string) => {
	if (type === 'keyword') {
		keywordData.value = keywordData.value.filter((item: string) => item !== tag);
	} else if (type === 'ip') {
		ipData.value = ipData.value.filter((item: string) => item !== tag);
	} else if (type === 'domain') {
		domainData.value = domainData.value.filter((item: string) => item !== tag);
	}
};

// 自定义校验函数
const validateIP = (ip: string): boolean => {
	// 支持IP段格式：192.168.3.4/255
	if (ip.includes('/')) {
		const [ipPart, rangePart] = ip.split('/');
		const range = parseInt(rangePart);

		// 验证IP部分
		const ipRegex = /^(\d{1,3}\.){3}\d{1,3}$/;
		if (!ipRegex.test(ipPart)) return false;

		// 验证范围部分（1-255）
		if (isNaN(range) || range < 1 || range > 255) return false;

		// 验证IP部分的每个段
		const parts = ipPart.split('.');
		return parts.every((part) => {
			const num = parseInt(part);
			return num >= 0 && num <= 255;
		});
	}

	// 普通IP格式
	const ipRegex = /^(\d{1,3}\.){3}\d{1,3}$/;
	if (!ipRegex.test(ip)) return false;

	const parts = ip.split('.');
	return parts.every((part) => {
		const num = parseInt(part);
		return num >= 0 && num <= 255;
	});
};

// 检查IP是否在某个IP段内
const isIPInRange = (ip: string, ipRange: string): boolean => {
	if (!ipRange.includes('/')) return false;

	const [rangeIP, rangePart] = ipRange.split('/');
	const range = parseInt(rangePart);

	// 将IP转换为数字进行比较
	const ipToNumber = (ipStr: string): number => {
		const parts = ipStr.split('.').map((part) => parseInt(part));
		return (parts[0] << 24) + (parts[1] << 16) + (parts[2] << 8) + parts[3];
	};

	const ipNum = ipToNumber(ip);
	const rangeIPNum = ipToNumber(rangeIP);
	const rangeEndNum = rangeIPNum + range - 1;

	return ipNum >= rangeIPNum && ipNum <= rangeEndNum;
};

// 检查IP是否与现有IP段冲突
const isIPConflict = (newIP: string): boolean => {
	// 如果新添加的是IP段，检查是否与现有IP冲突
	if (newIP.includes('/')) {
		const [rangeIP, rangePart] = newIP.split('/');
		const range = parseInt(rangePart);
		const rangeIPNum = ipToNumber(rangeIP);
		const rangeEndNum = rangeIPNum + range - 1;

		// 检查现有IP是否在新IP段内
		for (const existingIP of ipData.value) {
			if (!existingIP.includes('/')) {
				const existingIPNum = ipToNumber(existingIP);
				if (existingIPNum >= rangeIPNum && existingIPNum <= rangeEndNum) {
					return true;
				}
			}
		}
	} else {
		// 如果新添加的是单个IP，检查是否在现有IP段内
		for (const existingIP of ipData.value) {
			if (existingIP.includes('/') && isIPInRange(newIP, existingIP)) {
				return true;
			}
		}
	}

	return false;
};

// 辅助函数：将IP转换为数字
const ipToNumber = (ipStr: string): number => {
	const parts = ipStr.split('.').map((part) => parseInt(part));
	return (parts[0] << 24) + (parts[1] << 16) + (parts[2] << 8) + parts[3];
};

const validateDomain = (domain: string): boolean => {
	// 移除首尾空格
	const trimmedDomain = domain.trim();

	// 基本长度检查
	if (trimmedDomain.length === 0 || trimmedDomain.length > 253) {
		return false;
	}

	// 检查是否包含至少一个点号（顶级域名）
	if (!trimmedDomain.includes('.')) {
		return false;
	}

	// 分割域名部分
	const parts = trimmedDomain.split('.');

	// 检查域名部分数量（至少2部分：主域名.顶级域名）
	if (parts.length < 2) {
		return false;
	}

	// 检查每个部分
	for (let i = 0; i < parts.length; i++) {
		const part = parts[i];

		// 每个部分不能为空
		if (part.length === 0) {
			return false;
		}

		// 顶级域名至少2个字符
		if (i === parts.length - 1 && part.length < 2) {
			return false;
		}

		// 每个部分不能超过63个字符
		if (part.length > 63) {
			return false;
		}

		// 检查字符格式：只能包含字母、数字、连字符，不能以连字符开头或结尾
		const partRegex = /^[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?$/;
		if (!partRegex.test(part)) {
			return false;
		}

		// 顶级域名只能包含字母
		if (i === parts.length - 1) {
			const tldRegex = /^[a-zA-Z]+$/;
			if (!tldRegex.test(part)) {
				return false;
			}
		}
	}

	return true;
};

const handleInputConfirm = (type: string) => {
	if (type === 'keyword') {
		if (inputValue.value) {
			keywordData.value.push(inputValue.value);
		}
		inputVisible.value = false;
		inputValue.value = '';
	} else if (type === 'ip') {
		if (ipInputValue.value) {
			// 校验IP格式
			if (validateIP(ipInputValue.value)) {
				// 检查IP冲突
				if (isIPConflict(ipInputValue.value)) {
					useMessage().error('该IP与现有IP段冲突，无法添加');
					return;
				}
				ipData.value.push(ipInputValue.value);
			} else {
				useMessage().error('请输入正确的IP地址格式，支持单个IP(192.168.1.1)或IP段(192.168.1.1/255)');
				return;
			}
		}
		ipInputVisible.value = false;
		ipInputValue.value = '';
	} else if (type === 'domain') {
		if (domainInputValue.value) {
			// 校验域名格式
			if (validateDomain(domainInputValue.value)) {
				domainData.value.push(domainInputValue.value);
			} else {
				useMessage().error('请输入正确的域名格式，例如：example.com、sub.example.com');
				return;
			}
		}
		domainInputVisible.value = false;
		domainInputValue.value = '';
	}
};
const getpushContent = () => {
	if (formData.value.pushContent) {
		return formData.value.pushContent.includes('http') ? formData.value.pushContent : baseURL + formData.value.pushContent
	} else {
		return ''
	}
};

const onSubmit = async () => {
	// 触发表单校验（包含隐藏注册的 keyword/ip/domain 规则）
	try {
		await ruleFormRef.value.validate();
	} catch (e) {
		return;
	}
	formData.value = {
		...formData.value,
		ip: ipData.value,
		keyword: keywordData.value,
		domain: domainData.value,
		pushContent: getpushContent(),
	};
	if (!formData.value.pushContent) {
		return useMessage().error(formData.value.pushType ? '推送图片不能为空' : '推送内容不能为空');
	}
	try {
		loading.value = true;

		await update({
			...formData.value,
		});

		useMessage().success(props.rowData?.id ? t('common.editSuccessText') : t('common.addSuccessText'));
		emit('onsuccess');
		onCancel();
	} catch (err: any) {
		useMessage().error(err.msg);
	} finally {
		loading.value = false;
	}
};

watch(
	() => props.open,
	(val) => {
		if (val) {
			formData.value = {
				...props.rowData,
			};
			ipData.value = props.rowData.ip || [];
			keywordData.value = props.rowData.keyword || [];
			domainData.value = props.rowData.domain || [];
			oldUrl.value = props.rowData.pushContent;
		}
	}
);
</script>
<style lang="scss">
</style>