<script setup>

import {inject, ref, watch} from "vue"
import TInputText from "@/components/ui/TInputText.vue";
import TSelect from "@/components/ui/TSelect.vue";
import TOption from "@/components/ui/TOption.vue";
import TButton from "@/components/ui/TButton.vue";
import TInputGroup from "@/components/ui/TInputGroup.vue";
import TInputGroupAddon from "@/components/ui/TInputGroupAddon.vue";
import HTTPCacheRefsConfigBox from "@/components/server/HTTPCacheRefsConfigBox.vue";
import SubmitButton from "@/components/form/SubmitButton.vue";
import TDivider from "@/components/ui/TDivider.vue";
import PriorCheckbox from "@/components/common/PriorCheckbox.vue";
import TCheckboxBinary from "@/components/ui/TCheckboxBinary.vue";
import CodeLabel from "@/components/common/CodeLabel.vue";
import HTTPCacheStaleConfig from "@/components/server/HTTPCacheStaleConfig.vue";
import DefinitionTable from "@/components/common/DefinitionTable.vue";

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

const props = defineProps(["v-cache-config", "v-is-location", "v-is-group", "v-cache-policy", "v-web-id"])

const cacheRefsConfigBoxRef = ref()
const searchBoxRef = ref()
const {
	cacheConfig,
	moreOptionsVisible,
	enablePolicyRefs,
	maxBytes,
	searchBoxVisible,
	searchKeyword,
	keyOptionsVisible
} = (function () {
	let cacheConfig = props.vCacheConfig
	if (cacheConfig == null) {
		cacheConfig = {
			isPrior: false,
			isOn: false,
			addStatusHeader: true,
			addAgeHeader: false,
			enableCacheControlMaxAge: false,
			cacheRefs: [],
			purgeIsOn: false,
			purgeKey: "",
			disablePolicyRefs: false
		}
	}
	if (cacheConfig.cacheRefs == null) {
		cacheConfig.cacheRefs = []
	}

	let maxBytes = null
	if (props.vCachePolicy != null && props.vCachePolicy.maxBytes != null) {
		maxBytes = props.vCachePolicy.maxBytes
	}

	// key
	if (cacheConfig.key == null) {
		cacheConfig["key"] = {
			isOn: false,
			scheme: "https",
			host: ""
		}
	}

	return {
		cacheConfig: ref(cacheConfig),
		moreOptionsVisible: ref(false),
		enablePolicyRefs: ref(!cacheConfig.disablePolicyRefs),
		maxBytes: ref(maxBytes),

		searchBoxVisible: ref(false),
		searchKeyword: ref(""),

		keyOptionsVisible: ref(false)
	}
})()

const isOn = function () {
	return ((!props.vIsLocation && !props.vIsGroup) || cacheConfig.value.isPrior) && cacheConfig.value.isOn
}

const isPlus = function () {
	return utils.CURRENT_CTX.teaCommon.teaIsPlus
}

const generatePurgeKey = function () {
	let r = Math.random().toString() + Math.random().toString()
	let s = r.replace(/0\./g, "")
		.replace(/\./g, "")
	let result = ""
	for (let i = 0; i < s.length; i++) {
		result += String.fromCharCode(parseInt(s.substring(i, i + 1)) + ((Math.random() < 0.5) ? "a" : "A").charCodeAt(0))
	}
	cacheConfig.value.purgeKey = result
}

const showMoreOptions = function () {
	moreOptionsVisible.value = !moreOptionsVisible.value
}

const changeStale = function (stale) {
	cacheConfig.value.stale = stale
}

const showSearchBox = function () {
	searchBoxVisible.value = !searchBoxVisible.value
	if (searchBoxVisible.value) {
		setTimeout(function () {
			searchBoxRef.value.focus()
		})
	} else {
		searchKeyword.value = ""
	}
}

watch(enablePolicyRefs, function (v) {
	cacheConfig.value.disablePolicyRefs = !v
})

watch(searchKeyword, function (v) {
	cacheRefsConfigBoxRef.value.search(v)
})

</script>

<template>
	<div>
		<input type="hidden" name="cacheJSON" :value="JSON.stringify(cacheConfig)"/>

		<DefinitionTable>
			<PriorCheckbox :v-config="cacheConfig" v-if="vIsLocation || vIsGroup"></PriorCheckbox>
			<tbody v-show="(!vIsLocation && !vIsGroup) || cacheConfig.isPrior">
			<tr>
				<td class="title">启用缓存</td>
				<td>
					<TCheckboxBinary v-model="cacheConfig.isOn"/>
				</td>
			</tr>
			</tbody>
			<tbody v-show="isOn() && !vIsGroup">
			<tr>
				<td>缓存主域名</td>
				<td>
					<div v-show="!cacheConfig.key.isOn">默认 &nbsp;
						<a href="" @click.prevent="keyOptionsVisible = !keyOptionsVisible"><span class="small">[修改]</span></a>
					</div>
					<div v-show="cacheConfig.key.isOn">使用主域名：{{ cacheConfig.key.scheme }}://{{ cacheConfig.key.host }} &nbsp;
						<a href="" @click.prevent="keyOptionsVisible = !keyOptionsVisible"><span class="small">[修改]</span></a>
					</div>
					<div v-show="keyOptionsVisible" style="margin-top: 1em">
						<TDivider></TDivider>
						<DefinitionTable>
							<tbody>
							<tr>
								<td class="title">启用主域名</td>
								<td>
									<TCheckboxBinary v-model="cacheConfig.key.isOn"></TCheckboxBinary>
									<p class="comment">启用主域名后，所有缓存键值中的协议和域名部分都会修改为主域名，用来实现缓存不区分域名。</p>
								</td>
							</tr>
							<tr v-show="cacheConfig.key.isOn">
								<td>主域名 *</td>
								<td>
									<div class="ui fields inline">
										<div class="ui field">
											<TSelect v-model="cacheConfig.key.scheme">
												<TOption value="https">https://</TOption>
												<TOption value="http">http://</TOption>
											</TSelect>
										</div>
										<div class="ui field">
											<TInputText type="text" v-model="cacheConfig.key.host" placeholder="example.com" @keyup.enter="keyOptionsVisible = false" @keypress.enter.prevent="1"/>
										</div>
									</div>
									<p class="comment">此域名<strong>必须</strong>是当前网站已绑定域名，在刷新缓存时也需要使用此域名。
									</p>
								</td>
							</tr>
							</tbody>
						</DefinitionTable>
						<TButton secondary="" size="small" type="button" @click.prevent="keyOptionsVisible = false">完成</TButton>
					</div>
				</td>
			</tr>
			</tbody>
			<tbody v-show="isOn()">
			<tr>
				<td colspan="2">
					<a href="" @click.prevent="showMoreOptions"><span v-if="moreOptionsVisible">收起选项</span><span v-else>更多选项</span><i class="icon angle" :class="{up: moreOptionsVisible, down:!moreOptionsVisible}"></i></a>
				</td>
			</tr>
			</tbody>
			<tbody v-show="isOn() && moreOptionsVisible">
			<tr>
				<td>使用默认缓存条件</td>
				<td>
					<TCheckboxBinary v-model="enablePolicyRefs"></TCheckboxBinary>
					<p class="comment">选中后使用系统全局缓存策略中已经定义的默认缓存条件。</p>
				</td>
			</tr>
			<tr>
				<td>添加X-Cache报头</td>
				<td>
					<TCheckboxBinary v-model="cacheConfig.addStatusHeader"></TCheckboxBinary>
					<p class="comment">选中后自动在响应报头中增加
						<CodeLabel>X-Cache: BYPASS|MISS|HIT|PURGE</CodeLabel>
						；在浏览器端查看X-Cache值时请先禁用浏览器缓存，避免影响观察。
					</p>
				</td>
			</tr>
			<tr>
				<td>添加Age报头</td>
				<td>
					<TCheckboxBinary v-model="cacheConfig.addAgeHeader"></TCheckboxBinary>
					<p class="comment">选中后自动在响应报头中增加
						<CodeLabel>Age: [存活时间秒数]</CodeLabel>
						。
					</p>
				</td>
			</tr>
			<tr>
				<td>支持源站控制有效时间</td>
				<td>
					<TCheckboxBinary v-model="cacheConfig.enableCacheControlMaxAge"></TCheckboxBinary>
					<p class="comment">选中后表示支持源站在报头中设置的
						<CodeLabel>Cache-Control: max-age=[有效时间秒数]</CodeLabel>
						。
					</p>
				</td>
			</tr>
			<tr>
				<td class="color-border">允许PURGE</td>
				<td>
					<TCheckboxBinary v-model="cacheConfig.purgeIsOn"></TCheckboxBinary>
					<p class="comment">允许使用PURGE方法清除某个URL缓存。</p>
				</td>
			</tr>
			<tr v-show="cacheConfig.purgeIsOn">
				<td class="color-border">PURGE Key *</td>
				<td>
					<TInputText type="text" maxlength="200" v-model="cacheConfig.purgeKey" class="w-full"/>
					<p class="comment"><a href="" @click.prevent="generatePurgeKey">[随机生成]</a>。需要在PURGE方法调用时加入
						<CodeLabel>X-Cloud-Purge-Key: {{ cacheConfig.purgeKey }}</CodeLabel>
						报头。只能包含字符、数字、下划线。
					</p>
				</td>
			</tr>
			</tbody>
		</DefinitionTable>

		<div v-if="isOn() && moreOptionsVisible && isPlus()">
			<h5 class="group-header">过时缓存策略</h5>
			<HTTPCacheStaleConfig :v-cache-stale-config="cacheConfig.stale" @change="changeStale"></HTTPCacheStaleConfig>
		</div>

		<div v-show="isOn()">
			<SubmitButton class="mt-4"></SubmitButton>
			<TDivider></TDivider>
		</div>

		<div v-show="isOn()" style="margin-top: 1em">
			<h5 class="group-header relative">缓存条件 &nbsp;
				<a href="" @click.prevent="cacheRefsConfigBoxRef.addRef(false)">[添加]</a> &nbsp;
				<a href="" @click.prevent="showSearchBox" v-show="!searchBoxVisible">[搜索]</a>
				<TInputGroup class="search-box" v-show="searchBoxVisible">
					<TInputText type="text" placeholder="搜索..." ref="searchBoxRef" @keypress.enter.prevent="1" @keydown.esc="showSearchBox" v-model="searchKeyword" size="20" style="width: 14em"/>

					<TInputGroupAddon>
						<a href="" @click.prevent="showSearchBox"><i class="icon remove small"></i></a>
					</TInputGroupAddon>
				</TInputGroup>
			</h5>
			<HTTPCacheRefsConfigBox ref="cacheRefsConfigBoxRef" :v-cache-config="cacheConfig" :v-cache-refs="cacheConfig.cacheRefs" :v-web-id="vWebId" :v-max-bytes="maxBytes"></HTTPCacheRefsConfigBox>
		</div>
	</div>
</template>

<style scoped>
.search-box {
	position: absolute;
	top: -0.3em;
	left: 8em;
	transform-origin: left;
	transform: scale(0.8)
}
</style>
