<script setup>

import {inject, ref} from "vue"
import SubmitButton from "@/components/form/SubmitButton.vue";
import PriorCheckbox from "@/components/common/PriorCheckbox.vue";
import WarningMessage from "@/components/common/WarningMessage.vue";
import TinyBasicLabel from "@/components/common/TinyBasicLabel.vue";
import TDivider from "@/components/ui/TDivider.vue";
import TLabel from "@/components/ui/TLabel.vue";
import PlusButton from "@/components/common/PlusButton.vue";
import TipIcon from "@/components/common/TipIcon.vue";
import CodeLabel from "@/components/common/CodeLabel.vue";
import DefinitionTable from "@/components/common/DefinitionTable.vue";
import ListTable from "@/components/common/ListTable.vue";
import TColumn from "@/components/ui/TColumn.vue";
import TTabs from "@/components/ui/TTabs.vue";
import TTabView from "@/components/ui/TTabView.vue";
import TTab from "@/components/ui/TTab.vue";
import NavButton from "@/components/common/NavButton.vue";
import NotFoundInfo from "@/components/common/NotFoundInfo.vue";

const utils = inject("$utils")
const Tea = inject("$Tea")

const props = defineProps(["v-request-header-policy", "v-request-header-ref", "v-response-header-policy", "v-response-header-ref", "v-params", "v-is-location", "v-is-group", "v-has-group-request-config", "v-has-group-response-config", "v-group-setting-url"])

const {
	type,
	typeName,
	requestHeaderRef,
	responseHeaderRef,
	requestSettingHeaders,
	requestDeletingHeaders,
	requestNonStandardHeaders,
	responseSettingHeaders,
	responseDeletingHeaders,
	responseNonStandardHeaders,
	responseCORS
} = (function () {
	let type = "response"
	let hash = window.location.hash
	if (hash == "#request") {
		type = "request"
	}

	// ref
	let requestHeaderRef = props.vRequestHeaderRef
	if (requestHeaderRef == null) {
		requestHeaderRef = {
			isPrior: false,
			isOn: true,
			headerPolicyId: 0
		}
	}

	let responseHeaderRef = props.vResponseHeaderRef
	if (responseHeaderRef == null) {
		responseHeaderRef = {
			isPrior: false,
			isOn: true,
			headerPolicyId: 0
		}
	}

	// 请求相关
	let requestSettingHeaders = []
	let requestDeletingHeaders = []
	let requestNonStandardHeaders = []

	let requestPolicy = props.vRequestHeaderPolicy
	if (requestPolicy != null) {
		if (requestPolicy.setHeaders != null) {
			requestSettingHeaders = requestPolicy.setHeaders
		}
		if (requestPolicy.deleteHeaders != null) {
			requestDeletingHeaders = requestPolicy.deleteHeaders
		}
		if (requestPolicy.nonStandardHeaders != null) {
			requestNonStandardHeaders = requestPolicy.nonStandardHeaders
		}
	}

	// 响应相关
	let responseSettingHeaders = []
	let responseDeletingHeaders = []
	let responseNonStandardHeaders = []

	let responsePolicy = props.vResponseHeaderPolicy
	if (responsePolicy != null) {
		if (responsePolicy.setHeaders != null) {
			responseSettingHeaders = responsePolicy.setHeaders
		}
		if (responsePolicy.deleteHeaders != null) {
			responseDeletingHeaders = responsePolicy.deleteHeaders
		}
		if (responsePolicy.nonStandardHeaders != null) {
			responseNonStandardHeaders = responsePolicy.nonStandardHeaders
		}
	}

	let responseCORS = {
		isOn: false
	}
	if (responsePolicy.cors != null) {
		responseCORS = responsePolicy.cors
	}

	return {
		type: ref(type),
		typeName: ref((type == "request") ? "请求" : "响应"),

		requestHeaderRef: ref(requestHeaderRef),
		responseHeaderRef: ref(responseHeaderRef),
		requestSettingHeaders: ref(requestSettingHeaders),
		requestDeletingHeaders: ref(requestDeletingHeaders),
		requestNonStandardHeaders: ref(requestNonStandardHeaders),

		responseSettingHeaders: ref(responseSettingHeaders),
		responseDeletingHeaders: ref(responseDeletingHeaders),
		responseNonStandardHeaders: ref(responseNonStandardHeaders),
		responseCORS: ref(responseCORS)
	}
})()

const headerTab = ref(type)
const changeHeaderTab = function (headerType) {
	selectType(headerType.value)
}

const selectType = function (_type) {
	type.value = _type
	window.location.hash = "#" + _type
}

const addSettingHeader = function (policyId) {
	utils.popup("/servers/server/settings/headers/createSetPopup?" + props.vParams + "&headerPolicyId=" + policyId + "&type=" + type.value, {
		callback: function () {
			utils.successRefresh("保存成功")
		}
	})
}

const addDeletingHeader = function (policyId, type) {
	utils.popup("/servers/server/settings/headers/createDeletePopup?" + props.vParams + "&headerPolicyId=" + policyId + "&type=" + type, {
		callback: function () {
			utils.successRefresh("保存成功")
		}
	})
}

const addNonStandardHeader = function (policyId, type) {
	utils.popup("/servers/server/settings/headers/createNonStandardPopup?" + props.vParams + "&headerPolicyId=" + policyId + "&type=" + type, {
		callback: function () {
			utils.successRefresh("保存成功")
		}
	})
}

const updateSettingPopup = function (policyId, headerId) {
	utils.popup("/servers/server/settings/headers/updateSetPopup?" + props.vParams + "&headerPolicyId=" + policyId + "&headerId=" + headerId + "&type=" + type.value, {
		callback: function () {
			utils.successRefresh("保存成功")
		}
	})
}

const deleteDeletingHeader = function (policyId, headerName) {
	utils.confirm("确定要删除'" + headerName + "'吗？", function () {
		Tea.action("/servers/server/settings/headers/deleteDeletingHeader")
			.params({
				headerPolicyId: policyId,
				headerName: headerName
			})
			.post()
			.refresh()
	})
}

const deleteNonStandardHeader = function (policyId, headerName) {
	utils.confirm("确定要删除'" + headerName + "'吗？", function () {
		Tea.action("/servers/server/settings/headers/deleteNonStandardHeader")
			.params({
				headerPolicyId: policyId,
				headerName: headerName
			})
			.post()
			.refresh()
	})
}

const deleteHeader = function (policyId, type, headerId) {
	utils.confirm("确定要删除此报头吗？", function () {
			Tea.action("/servers/server/settings/headers/delete")
				.post()
				.params({
					headerPolicyId: policyId,
					type: type,
					headerId: headerId
				})
				.refresh()
		}
	)
}

const updateCORS = function (policyId) {
	utils.popup("/servers/server/settings/headers/updateCORSPopup?" + props.vParams + "&headerPolicyId=" + policyId + "&type=" + type.value, {
		callback: function () {
			utils.successRefresh("保存成功")
		}
	})
}

</script>

<template>
	<div>
		<TTabView v-model="headerTab" @change="changeHeaderTab" class="mb-4">
			<TTabs>
				<TTab code="response">
					响应报头<span v-if="responseSettingHeaders.length > 0">({{ responseSettingHeaders.length }})</span>
				</TTab>
				<TTab code="request">
					请求报头<span v-if="requestSettingHeaders.length > 0">({{ requestSettingHeaders.length }})</span>
				</TTab>
			</TTabs>
		</TTabView>

		<input type="hidden" name="type" :value="type"/>

		<!-- 请求 -->
		<div v-if="(vIsLocation || vIsGroup) && type == 'request'" class="mb-4">
			<input type="hidden" name="requestHeaderJSON" :value="JSON.stringify(requestHeaderRef)"/>
			<DefinitionTable>
				<PriorCheckbox :v-config="requestHeaderRef"></PriorCheckbox>
			</DefinitionTable>
			<SubmitButton></SubmitButton>
		</div>

		<div v-if="((!vIsLocation && !vIsGroup) || requestHeaderRef.isPrior) && type == 'request'">
			<div v-if="vHasGroupRequestConfig">
				<div class="margin"></div>
				<WarningMessage>由于已经在当前<a :href="vGroupSettingUrl + '#request'">网站分组</a>中进行了对应的配置，在这里的配置将不会生效。
				</WarningMessage>
			</div>
			<div :class="{'opacity-mask': vHasGroupRequestConfig}">
				<NavButton action-create @click.prevent="addSettingHeader(vRequestHeaderPolicy.id)">添加新请求报头</NavButton>
				<TDivider></TDivider>
				<NotFoundInfo v-if="requestSettingHeaders.length == 0">暂时还没有自定义请求报头。</NotFoundInfo>
				<div v-if="requestSettingHeaders.length > 0">
					<ListTable :items="requestSettingHeaders">
						<TColumn header="名称" class="name-column" frozen>
							<template #body="{data: header}">
								<a href="" @click.prevent="updateSettingPopup(vRequestHeaderPolicy.id, header.id)">{{ header.name }}
									<i class="icon expand small"></i></a>
								<div class="label-group mt-1">
									<span v-if="header.status != null && header.status.codes != null && !header.status.always" class="label-group"><TinyBasicLabel v-for="code in header.status.codes" :key="code">{{ code }}</TinyBasicLabel></span>
									<span v-if="header.methods != null && header.methods.length > 0" class="label-group"><TinyBasicLabel v-for="method in header.methods" :key="method">{{ method }}</TinyBasicLabel></span>
									<span v-if="header.domains != null && header.domains.length > 0"><TinyBasicLabel v-for="domain in header.domains" :key="domain">{{ domain }}</TinyBasicLabel></span>
									<TinyBasicLabel v-if="header.shouldAppend">附加</TinyBasicLabel>
									<TinyBasicLabel v-if="header.disableRedirect">跳转禁用</TinyBasicLabel>
									<TinyBasicLabel v-if="header.shouldReplace && header.replaceValues != null && header.replaceValues.length > 0">替换</TinyBasicLabel>
								</div>
							</template>
						</TColumn>
						<TColumn header="值" class="description-column">
							<template #body="{data: header}">
								{{ header.value }}
							</template>
						</TColumn>
						<TColumn header="操作" class="two op" frozen align-frozen="right">
							<template #body="{data: header}">
								<a href="" @click.prevent="updateSettingPopup(vRequestHeaderPolicy.id, header.id)">修改</a> &nbsp;
								<a href="" @click.prevent="deleteHeader(vRequestHeaderPolicy.id, 'setHeader', header.id)">删除</a>
							</template>
						</TColumn>
					</ListTable>
				</div>

				<h5 class="group-header">其他设置</h5>

				<DefinitionTable>
					<tbody>
					<tr>
						<td class="title">删除报头
							<TipIcon content="可以通过此功能删除转发到源站的请求报文中不需要的报头"></TipIcon>
						</td>
						<td>
							<div v-if="requestDeletingHeaders.length > 0" class="label-group">
								<TLabel outlined="" v-for="headerName in requestDeletingHeaders">{{ headerName }}
									<a href=""><i class="icon remove" title="删除" @click.prevent="deleteDeletingHeader(vRequestHeaderPolicy.id, headerName)"></i></a>
								</TLabel>
								<TDivider></TDivider>
							</div>
							<PlusButton secondary="" size="small" type="button" @click.prevent="addDeletingHeader(vRequestHeaderPolicy.id, 'request')"></PlusButton>
						</td>
					</tr>
					<tr>
						<td class="title">非标报头
							<TipIcon content="可以通过此功能设置转发到源站的请求报文中非标准的报头，比如hello_world"></TipIcon>
						</td>
						<td>
							<div v-if="requestNonStandardHeaders.length > 0" class="label-group">
								<TLabel outlined="" v-for="headerName in requestNonStandardHeaders">{{ headerName }}
									<a href=""><i class="icon remove" title="删除" @click.prevent="deleteNonStandardHeader(vRequestHeaderPolicy.id, headerName)"></i></a>
								</TLabel>
								<TDivider></TDivider>
							</div>
							<PlusButton secondary="" size="small" type="button" @click.prevent="addNonStandardHeader(vRequestHeaderPolicy.id, 'request')"></PlusButton>
						</td>
					</tr>
					</tbody>
				</DefinitionTable>
			</div>
		</div>

		<!-- 响应 -->
		<div v-if="(vIsLocation || vIsGroup) && type == 'response'" class="mb-4">
			<input type="hidden" name="responseHeaderJSON" :value="JSON.stringify(responseHeaderRef)"/>
			<DefinitionTable>
				<PriorCheckbox :v-config="responseHeaderRef"></PriorCheckbox>
			</DefinitionTable>
			<SubmitButton></SubmitButton>
		</div>

		<div v-if="((!vIsLocation && !vIsGroup) || responseHeaderRef.isPrior) && type == 'response'">
			<div v-if="vHasGroupResponseConfig">
				<WarningMessage>由于已经在当前<a :href="vGroupSettingUrl + '#response'">网站分组</a>中进行了对应的配置，在这里的配置将不会生效。
				</WarningMessage>
			</div>
			<div :class="{'opacity-mask': vHasGroupResponseConfig}">
				<NavButton action-create @click.prevent="addSettingHeader(vResponseHeaderPolicy.id)">添加新响应报头</NavButton>
				<TDivider></TDivider>
				<NotFoundInfo v-if="responseSettingHeaders.length == 0">暂时还没有自定义响应报头。</NotFoundInfo>
				<div v-if="responseSettingHeaders.length > 0">
					<ListTable :items="responseSettingHeaders">
						<TColumn header="名称" class="name-column" frozen>
							<template #body="{data: header}">
								<a href="" @click.prevent="updateSettingPopup(vResponseHeaderPolicy.id, header.id)">{{ header.name }}
									<i class="icon expand small"></i></a>
								<div class="label-group mt-1">
									<span v-if="header.status != null && header.status.codes != null && !header.status.always" class="label-group"><TinyBasicLabel v-for="code in header.status.codes" :key="code">{{ code }}</TinyBasicLabel></span>
									<span v-if="header.methods != null && header.methods.length > 0" class="label-group"><TinyBasicLabel v-for="method in header.methods" :key="method">{{ method }}</TinyBasicLabel></span>
									<span v-if="header.domains != null && header.domains.length > 0"><TinyBasicLabel v-for="domain in header.domains" :key="domain">{{ domain }}</TinyBasicLabel></span>
									<TinyBasicLabel v-if="header.shouldAppend">附加</TinyBasicLabel>
									<TinyBasicLabel v-if="header.disableRedirect">跳转禁用</TinyBasicLabel>
									<TinyBasicLabel v-if="header.shouldReplace && header.replaceValues != null && header.replaceValues.length > 0">替换</TinyBasicLabel>
								</div>

								<!-- CORS -->
								<div v-if="header.name == 'Access-Control-Allow-Origin' && header.value == '*'">
									<span class="red small">建议使用当前页面下方的"CORS自适应跨域"功能代替Access-Control-*-*相关报头。</span>
								</div>
							</template>
						</TColumn>
						<TColumn header="值" class="description-column">
							<template #body="{data: header}">
								{{ header.value }}
							</template>
						</TColumn>
						<TColumn header="操作" class="two op" frozen align-frozen="right">
							<template #body="{data: header}">
								<a href="" @click.prevent="updateSettingPopup(vResponseHeaderPolicy.id, header.id)">修改</a> &nbsp;
								<a href="" @click.prevent="deleteHeader(vResponseHeaderPolicy.id, 'setHeader', header.id)">删除</a>
							</template>
						</TColumn>
					</ListTable>
				</div>

				<h5 class="group-header">其他设置</h5>

				<DefinitionTable>
					<tbody>
					<tr>
						<td class="title">删除报头
							<TipIcon content="可以通过此功能删除响应报文中不需要的报头"></TipIcon>
						</td>
						<td>
							<div v-if="responseDeletingHeaders.length > 0" class="label-group">
								<TLabel outlined="" v-for="headerName in responseDeletingHeaders">{{ headerName }} &nbsp;
									<a href=""><i class="icon remove small" title="删除" @click.prevent="deleteDeletingHeader(vResponseHeaderPolicy.id, headerName)"></i></a>
								</TLabel>
								<TDivider></TDivider>
							</div>
							<PlusButton secondary="" size="small" type="button" @click.prevent="addDeletingHeader(vResponseHeaderPolicy.id, 'response')"></PlusButton>
						</td>
					</tr>
					<tr>
						<td>非标报头
							<TipIcon content="可以通过此功能设置响应报文中非标准的报头，比如hello_world"></TipIcon>
						</td>
						<td>
							<div v-if="responseNonStandardHeaders.length > 0" class="label-group">
								<TLabel outlined="" v-for="headerName in responseNonStandardHeaders">{{ headerName }} &nbsp;
									<a href=""><i class="icon remove small" title="删除" @click.prevent="deleteNonStandardHeader(vResponseHeaderPolicy.id, headerName)"></i></a>
								</TLabel>
								<TDivider></TDivider>
							</div>
							<PlusButton secondary="" size="small" type="button" @click.prevent="addNonStandardHeader(vResponseHeaderPolicy.id, 'response')"></PlusButton>
						</td>
					</tr>
					<tr>
						<td class="title">CORS自适应跨域</td>
						<td>
							<span v-if="responseCORS.isOn" class="green">已启用</span><span class="disabled" v-else>未启用</span> &nbsp;
							<a href="" @click.prevent="updateCORS(vResponseHeaderPolicy.id)">[修改]</a>
							<p class="comment">
								<span v-if="!responseCORS.isOn">启用后，服务器可以</span><span v-else>服务器会</span>自动生成
								<CodeLabel>Access-Control-*-*</CodeLabel>
								相关的报头。
							</p>
						</td>
					</tr>
					</tbody>
				</DefinitionTable>
			</div>
		</div>
		<div class="margin"></div>
	</div>
</template>

<style scoped>
.label-group .item:not(.active) {
	color: var(--p-text-color);
}
</style>
