<template>
	<el-row :gutter="8" style="margin-bottom: 5px">
		<el-col :span="4">
			<!-- 流程下拉 模板选择 -->
			<el-select v-model="state.mode" showSearch @change="changeMode" :defaultValue="0" option-label-prop="label" class="w100">
				<el-option v-for="(opt, idx) in state.modeList" :key="idx" :label="opt.name" :value="idx">
					{{ opt.name }}
				</el-option>
			</el-select>
		</el-col>

		<el-col :span="20">
			<!-- 纸张设置 -->
			<el-button-group style="margin: 0 2px">
				<el-button v-for="(value, type) in state.paperTypes" :type="curPaperType === type ? 'primary' : ''" @click="setPaper(type, value)" :key="type">
					{{ type }}
				</el-button>
				<el-popover v-model="state.paperPopVisible" placement="bottom" width="300" title="设置纸张宽高(mm)">
					<div style="display: flex; align-items: center; justify-content: space-between; margin-bottom: 10px">
						<el-input type="number" v-model="state.paperWidth" style="width: 100px; text-align: center" place="宽（mm）"></el-input>~
						<el-input type="number" v-model="state.paperHeight" style="width: 100px; text-align: center" place="高（mm）"></el-input>
					</div>
					<div>
						<el-button type="primary" style="width: 100%" @click="otherPaper">确定</el-button>
					</div>
					<template #reference>
						<el-button :type="'other' == curPaperType ? 'primary' : ''" style="margin: 0 10px">自定义宽高</el-button>
					</template>
				</el-popover>
			</el-button-group>
			<el-input-number style="margin-right: 8px" v-model="state.scaleValue" :precision="2" :step="0.1" :min="state.scaleMin" :max="state.scaleMax" @change="changeScale"></el-input-number>

			<el-button-group>
				<el-tooltip content="左对齐" placement="bottom">
					<el-button icon="ele-Back" @click="setElsAlign('left')"> </el-button>
				</el-tooltip>
				<el-tooltip content="居中" placement="bottom">
					<el-button icon="ele-FullScreen" @click="setElsAlign('vertical')"> </el-button>
				</el-tooltip>
				<el-tooltip content="右对齐" placement="bottom">
					<el-button icon="ele-Right" @click="setElsAlign('right')"> </el-button>
				</el-tooltip>
				<el-tooltip content="顶对齐" placement="bottom">
					<el-button icon="ele-Top" @click="setElsAlign('top')"> </el-button>
				</el-tooltip>
				<el-tooltip content="垂直居中" placement="bottom">
					<el-button icon="ele-DCaret" @click="setElsAlign('horizontal')"> </el-button>
				</el-tooltip>
				<el-tooltip content="底对齐" placement="bottom">
					<el-button icon="ele-Bottom" @click="setElsAlign('bottom')"> </el-button>
				</el-tooltip>
				<el-tooltip content="横向分散" placement="bottom">
					<el-button icon="ele-Sort" @click="setElsAlign('distributeHor')"> </el-button>
				</el-tooltip>
				<el-tooltip content="纵向分散" placement="bottom">
					<el-button icon="ele-Switch" @click="setElsAlign('distributeVer')"> </el-button>
				</el-tooltip>
			</el-button-group>

			<!-- 预览/打印 -->
			<el-button-group style="margin-left: 8px">
				<el-button type="primary" icon="ele-RefreshRight" @click="rotatePaper"> 旋转 </el-button>
				<el-button type="primary" icon="ele-View" @click="preView"> 预览 </el-button>
				<el-button type="primary" icon="ele-Printer" @click="print"> 直接打印 </el-button>
				<el-button type="primary" icon="ele-CircleCheck" @click="viewJson"> 模板JSON </el-button>
				<el-button type="danger" icon="ele-Delete" @click="clearPaper"> 清空模板 </el-button>
			</el-button-group>
		</el-col>
	</el-row>

	<el-row :gutter="8">
		<el-col :span="4">
			<el-card style="height: 100%" shadow="never" :body-style="{ padding: '0px 0 5px 7px' }">
				<el-row>
					<el-col :span="24" id="hiprintEpContainer" class="rect-printElement-types hiprintEpContainer"> </el-col>
				</el-row>
			</el-card>
		</el-col>
		<el-col :span="14">
			<el-card shadow="never" class="card-design" :body-style="{ padding: '18px' }">
				<div id="hiprint-printTemplate" class="hiprint-printTemplate"></div>
			</el-card>
		</el-col>
		<el-col :span="6" class="params_setting_container">
			<el-card shadow="never" :body-style="{ padding: '0px' }">
				<el-row class="hinnn-layout-sider">
					<div id="PrintElementOptionSetting"></div>
				</el-row>
			</el-card>
		</el-col>
	</el-row>

	<el-drawer title="打印模板" v-model="state.templateDialogVisible">
		<vue-json-pretty :data="state.templateContent" showLength showIcon showLineNumber showSelectController />
	</el-drawer>

	<!-- 预览 -->
	<PrintPreview ref="preViewRef" />
</template>

<script lang="ts" setup name="hiprintDesign">
import { computed, onMounted, ref, reactive } from 'vue';
import { ElMessage, ElMessageBox } from 'element-plus';
import VueJsonPretty from 'vue-json-pretty';
import 'vue-json-pretty/lib/styles.css';

import { hiprint } from 'vue-plugin-hiprint';
import providers from './providers';
import PrintPreview from './preview.vue';
import printData from './print-data';

let hiprintTemplate = ref();

const preViewRef = ref();
const state = reactive({
	// 模板选择
	mode: 0,
	modeList: [] as any,
	// 当前纸张
	curPaper: {
		type: 'A4',
		width: 220,
		height: 296.6,
	},
	// 纸张类型
	paperTypes: {
		A3: {
			width: 420,
			height: 296.6,
		},
		A4: {
			width: 210,
			height: 296.6,
		},
		A5: {
			width: 210,
			height: 147.6,
		},
		B3: {
			width: 500,
			height: 352.6,
		},
		B4: {
			width: 250,
			height: 352.6,
		},
		B5: {
			width: 250,
			height: 175.6,
		},
	},
	scaleValue: 1,
	scaleMax: 5,
	scaleMin: 0.5,
	// 自定义纸张
	paperPopVisible: false,
	paperWidth: 220,
	paperHeight: 80,

	templateDialogVisible: false,
	templateContent: '',
});

// 计算当前纸张类型
const curPaperType = computed(() => {
	let type = 'other';
	let types: any = state.paperTypes;
	for (const key in types) {
		let item = types[key];
		let { width, height } = state.curPaper;
		if (item.width === width && item.height === height) {
			type = key;
		}
	}
	return type;
});

// 选择模板
const changeMode = () => {
	let provider = providers[state.mode];
	hiprint.init({
		providers: [provider.f],
	});
	// 渲染自定义选项
	const hiprintEpContainerEl = document.getElementById('hiprintEpContainer');
	if (hiprintEpContainerEl) {
		hiprintEpContainerEl.innerHTML = '';
	}
	hiprint.PrintElementTypeManager.build('.hiprintEpContainer', provider.value);

	// 渲染绘画模板
	const hiprintPrintTemplate = document.getElementById('hiprint-printTemplate');
	if (hiprintPrintTemplate) {
		hiprintPrintTemplate.innerHTML = '';
	}
	// 初始化打印模板设计器
	let template = {};
	hiprintTemplate.value = new hiprint.PrintTemplate({
		template: template,
		settingContainer: '#PrintElementOptionSetting',
		paginationContainer: '.hiprint-printPagination',
		fontList: [
			{ title: '微软雅黑', value: 'Microsoft YaHei' },
			{ title: '黑体', value: 'STHeitiSC-Light' },
			{ title: 'Arial', value: 'Arial' },
			{ title: '宋体', value: 'SimSun' },
			{ title: '华为楷体', value: 'STKaiti' },
			{ title: 'cursive', value: 'cursive' },
			{ title: 'Vector', value: 'Vector' },
		],
	});
	hiprintTemplate.value.design('#hiprint-printTemplate');
	// 获取当前放大比例, 当zoom时传true才会有
	state.scaleValue = hiprintTemplate.value.editingPanel?.scale ?? 1;
};

/**
 * 设置纸张大小
 * @param type [A3, A4, A5, B3, B4, B5, other]
 * @param value {width,height} mm
 */
const setPaper = (type: string, value: { width: number; height: number }) => {
	try {
		if (Object.keys(state.paperTypes).includes(type)) {
			state.curPaper = { type: type, width: value.width, height: value.height };
			hiprintTemplate.value.setPaper(value.width, value.height);
			
		} else {
			state.curPaper = { type: 'other', width: value.width, height: value.height };
			hiprintTemplate.value.setPaper(value.width, value.height);
		}
	} catch (error) {
		ElMessage.error(`操作失败: ${error}`);
	}
};

// 改变缩放比例
const changeScale = (currentValue: number, oldValue: number) => {
	let big = false;
	currentValue <= oldValue ? (big = false) : (big = true);

	let scaleVal = currentValue;
	if (big) {
		if (scaleVal > state.scaleMax) scaleVal = 5;
	} else {
		if (scaleVal < state.scaleMin) scaleVal = 0.5;
	}
	if (hiprintTemplate.value) {
		// scaleVal: 放大缩小值, false: 不保存(不传也一样), 如果传 true, 打印时也会放大
		hiprintTemplate.value.zoom(scaleVal);
		state.scaleValue = scaleVal;
	}
};

// 旋转模板
const rotatePaper = () => {
	if (hiprintTemplate.value) {
		hiprintTemplate.value.rotatePaper();
	}
};

// 对齐模板
const setElsAlign = (e: any) => {
	hiprintTemplate.value.setElsAlign(e);
};

// 清空模板
const clearPaper = () => {
	ElMessageBox.confirm('是否确认清空模板信息?', '警告', {
		confirmButtonText: '确定',
		cancelButtonText: '取消',
		type: 'warning',
	})
		.then(() => {
			try {
				hiprintTemplate.value.clear();
			} catch (error) {
				ElMessage.error(`操作失败: ${error}`);
			}
		})
		.catch((err) => {
			console.log(err);
		});
};

// 自定义纸张
const otherPaper = () => {
	let value = {
		width: 0,
		height: 0,
	};
	value.width = state.paperWidth;
	value.height = state.paperHeight;
	state.paperPopVisible = false;
	setPaper('other', value);
};

const setOtherPaper = (width:number,height:number) => {
	let value = {
		width: width,
		height: height,
	};
	state.paperWidth = width;
	state.paperHeight = height;
	state.paperPopVisible = false;
	setPaper('other', value);
};

// 预览
const preView = () => {
	let { width } = state.curPaper;
	preViewRef.value.showDialog(hiprintTemplate.value, printData, width);
};
// 直接打印
const print = () => {
	console.log('直接打印');
};

// 查看模板JSON
const viewJson = () => {
	if (hiprintTemplate.value) {
		var templateJson = JSON.stringify(hiprintTemplate.value.getJson() || {});
		state.templateContent = JSON.parse(templateJson);
		state.templateDialogVisible = true;
	}
};

onMounted(() => {
	state.modeList = providers.map((e) => {
		return { type: e.type, name: e.name, value: e.value };
	});
	changeMode();
	// otherPaper(); // 默认纸张
});

// 导出对象
defineExpose({ hiprintTemplate,setOtherPaper });
</script>

<style lang="scss" scoped>
:deep(.rect-printElement-types .hiprint-printElement-type > li > ul > li > a) {
	// padding: 4px 4px;
	//color: #1296db;
	// line-height: 1;
	height: auto;
	text-overflow: ellipsis;
	color: var(--el-color-primary);
	box-shadow: none !important;
	border: 1px dashed var(--el-color-primary);
}

// 默认图片
:deep(.hiprint-printElement-image-content) {
	img {
		content: url('~@/assets/logo.png');
	}
}

// 设计容器
.card-design {
	overflow: hidden;
	overflow-x: auto;
	overflow-y: auto;
}

:deep(.hiprint-option-item-submitBtn) {
	background: var(--el-color-primary);
}
:deep(.hiprint-option-item-deleteBtn) {
	background: var(--el-color-danger);
}
:deep(.prop-tabs .prop-tab-items li.active) {
	color: var(--el-color-primary);
	border-bottom: 2px solid var(--el-color-primary);
}
</style>
