<template>
	<sgc-modal :title="title" @sgcCloseModal="closeModal" :toolbars="toolbars" scrollMode="fix">
		<sgc-loading :loadStatus="loadStatus" loadType="view">
			<div class="sign-content" ref="content" v-if="loadStatus === 'loaded'">
				<div v-if="params.signMode === 'view'" class="preview">
					<img v-if="params.fileBucket && params.fileBucket.thumbnail" :src="params.fileBucket.thumbnail.imageSrc" />
					<span v-else>No Sign</span>
				</div>
				<div v-if="params.signMode === 'sign'" class="sign-pad">
					<span v-if="params.signShowGuide">Sign Here</span>
					<vue-signature-pad :width="params.offsetWidth" :height="params.offsetHeight" ref="signaturePad" :options="params.signOptions"></vue-signature-pad>
				</div>
			</div>
		</sgc-loading>
	</sgc-modal>
</template>

<script lang="ts">
import { commonService, defineComponent, Icon, IonFormModules, IonPageModules, modalController, utils } from '../../../services/index';

import { FileBucketVo, ViewDataVo } from '../../../services/common.interface';

/**
 * 공통 - 고객 서명
 *
 * 고객 서명을 관리함
 * 임직원인 경우 서명 열람만 가능하고
 * 협력업체의 경우 하자의 상태가 진행 중인 경우에 한해서 고객 서명이 활성화 됨
 */
export default defineComponent({
	name: 'DeftPhotoModal',
	components: { ...IonPageModules, ...IonFormModules },
	props: ['deft'],
	setup() {
		return {
			Icon,
			utils,
		};
	},
	mounted() {
		this.loadDeft();
	},
	data(): ViewDataVo<
		{
			signAflList: FileBucketVo[];
		},
		{
			signAflId: string;
			fileBucket: FileBucketVo;
			deftNo: string;
			deftPrcgStusCd: string;
			offsetWidth: string;
			offsetHeight: string;
			signOptions: any;
			signShowGuide: boolean;
			signMode: string;
		}
	> {
		return {
			title: 'DEFT.TIT_CUSTSIGN',
			loadStatus: 'loading',
			dataView: {
				signAflList: null,
			},
			params: {
				signAflId: null,
				fileBucket: null,
				deftNo: '',
				deftPrcgStusCd: null,
				offsetWidth: '500px',
				offsetHeight: '500px',
				signMode: 'view',
				signShowGuide: true,
				signOptions: {
					dotSize: (0.5 + 2.5) / 2,
					minWidth: 0.5,
					maxWidth: 2.5,
					throttle: 16,
					minDistance: 5,
					backgroundColor: 'rgba(0,0,0,0)',
					penColor: 'black',
					velocityFilterWeight: 0.7,
				},
			},
			toolbars: [
				{
					color: 'danger',
					label: 'DEFT.BTN_SIGN_RESIGN',
					click: () => {
						this.changeMode('sign');
					},
				},
				{
					color: 'danger',
					label: 'DEFT.BTN_SIGN_CLEAR',
					click: () => {
						this.clearSign();
					},
				},
				{
					color: 'danger',
					label: 'DEFT.BTN_SIGN_SAVE',
					click: () => {
						this.saveSign();
					},
				},
				{
					color: 'danger',
					label: 'DEFT.BTN_SIGN_UNDO',
					click: () => {
						this.undoSign();
					},
				},
				{
					color: 'danger',
					label: 'DEFT.BTN_SIGN_CANCELSIGN',
					click: () => {
						this.changeMode('view');
					},
				},
			],
		};
	},
	watch: {
		deft() {
			this.loadDeft();
		},
	},
	methods: {
		/**  캔버스 사이즈 조정 */
		resizeCanvas() {
			const scrollElement: HTMLElement = commonService.getRef(this.$refs, 'content');
			if (scrollElement) {
				this.params.offsetWidth = scrollElement.offsetWidth + 'px';
				this.params.offsetHeight = scrollElement.offsetHeight + 'px';
				setTimeout(() => {
					this.getSignaturePad().resizeCanvas();
				}, 200);
			}
		},
		/** 싸인 버튼 활성화 */
		_signButtonActive() {
			const { isEmpty } = this.getSignaturePad().saveSignature();
			if (isEmpty) {
				this.toolbars[1].disabled = true;
				this.toolbars[2].disabled = true;
				this.toolbars[3].disabled = true;
			} else {
				this.toolbars[1].disabled = false;
				this.toolbars[2].disabled = false;
				this.toolbars[3].disabled = false;
			}
		},
		/** 모달 닫기 */
		closeModal() {
			return modalController.dismiss();
		},
		/** 싸인 패드 가져오기 */
		getSignaturePad(): any {
			return commonService.getRef(this.$refs, 'signaturePad');
		},
		/**  싸인 초기화 */
		clearSign() {
			this.getSignaturePad().clearSignature();
			this._signButtonActive();
		},
		/** 데이타 URL 을 파일 객체로 변환 */
		dataURLtoFile(dataUrl: string, fileName: string): File {
			var arr = dataUrl.split(','),
				mime = arr[0].match(/:(.*?);/)[1],
				bstr = atob(arr[1]),
				n = bstr.length,
				u8arr = new Uint8Array(n);
			while (n--) {
				u8arr[n] = bstr.charCodeAt(n);
			}
			return new File([u8arr], fileName, { type: mime });
		},
		/** 싸인 저장 */
		saveSign() {
			const { isEmpty, data } = this.getSignaturePad().saveSignature();
			if (isEmpty) {
				commonService.openToast('DEFT.MSG_EMPTY_SIGN', null, null, this.title, 'warning');
			} else {
				if (commonService.isNotNull(this.params.signAflId) && this.dataView.signAflList && this.dataView.signAflList.length > 0) {
					commonService.getDelete('api/files/' + this.params.signAflId + '/all').then(() => {
						this.dataView.signAflList = null;
						this.sendSign(data);
					});
				} else {
					this.sendSign(data);
				}
			}
		},
		/** 싸인 한단계 취소 */
		undoSign() {
			this.getSignaturePad().undoSignature();
			this._signButtonActive();
		},
		/** 싸인 전송 */
		sendSign(data: string) {
			const params: string[] = [];
			if (commonService.isNotNull(this.params.signAflId)) {
				params.push('id=' + this.params.signAflId);
			}
			params.push('others=runtime');
			params.push('others=files');
			const formData = new FormData();
			formData.append('file[0]', this.dataURLtoFile(data, 'sign.png'));
			commonService
				.getPost('api/files?' + params.join('&'), formData, {
					headers: {
						'Content-Type': 'multipart/form-data',
					},
				})
				.then((result: FileBucketVo[]) => {
					if (result && result.length > 0) {
						this.params.signAflId = result[0].id;
						commonService
							.getPost('api/updateTcsDeftCustsign/' + this.params.deftNo, {
								signAflId: this.params.signAflId,
							})
							.then(() => {
								commonService.openToast('DEFT.MSG_SAVE_SIGN', null, null, this.title, 'success');
								this.dataView.signAflList = null;
								this.loadData();
							});
					}
				});
		},
		/** 하자 정보 불러 오기 */
		loadDeft() {
			if (commonService.isNotNull(this.params.signAflId) || commonService.isNotNull(this.params.deftNo)) {
				this.loadData();
			} else if (commonService.isNotNull(this.deft)) {
				if (commonService.isNotNull(this.deft.signAflId) && commonService.isNotNull(this.deft.deftNo) && commonService.isNotNull(this.deft.deftPrcgStusCd)) {
					this.params.signAflId = this.deft.signAflId;
					this.params.deftNo = this.deft.deftNo;
					this.params.deftPrcgStusCd = this.deft.deftPrcgStusCd;
					this.loadData();
				} else if (commonService.isNotNull(this.deft.deftNo)) {
					this.params.deftNo = this.deft.deftNo;
					this.params.signAflId = null;
					this.loadData();
				} else {
					this.loadData();
				}
			} else {
				this.loadData();
			}
		},
		/** 기존 싸인 정보 불러 오기 */
		loadData() {
			if (commonService.isNotNull(this.params.deftNo) && (this.params.signAflId === null || this.params.deftPrcgStusCd === null)) {
				commonService.getView('api/selectTcsDeftCustsignView/' + this.params.deftNo).then((view: any) => {
					if (view && view.deftNo) {
						this.params.deftNo = view.deftNo;
						this.params.signAflId = view.signAflId || '';
						this.params.deftPrcgStusCd = view.deftPrcgStusCd;
						this.dataView.signAflList = null;
					} else {
						this.params.signAflId = '';
						this.params.deftPrcgStusCd = '';
						this.dataView.signAflList = null;
					}
					this.loadData();
				});
				return;
			} else if (commonService.isNotNull(this.params.signAflId) && this.dataView.signAflList === null) {
				this.loadStatus = 'loading';
				commonService.getList('api/files/' + this.params.signAflId + '/thumb/auto500').then((list: FileBucketVo[]) => {
					this.dataView.signAflList = list;
					if (this.dataView.signAflList.length > 0) {
						this.params.fileBucket = this.dataView.signAflList[this.dataView.signAflList.length - 1];
					} else {
						this.params.fileBucket = null;
					}
					this.loadData();
				});
				return;
			} else {
				if (commonService.isNotNull(this.params.fileBucket)) {
					this.params.signMode = 'view';
				} else {
					this.params.signMode = 'sign';
				}
			}
			this.params.signOptions.onBegin = () => {
				this.params.signShowGuide = false;
			};
			this.params.signOptions.onEnd = () => {
				this._signButtonActive();
			};
			const signMode = this.params.signMode;
			this.changeMode(signMode);
			this.loadStatus = 'loaded';
		},
		/** 싸인 모드 변경 */
		changeMode(mode: string) {
			switch (this.params.deftPrcgStusCd) {
				case 'A':
				case 'B':
				case 'C':
				case 'D':
					this.params.signMode = mode;
					switch (this.params.signMode) {
						case 'view':
							this.toolbars[0].hide = false;
							this.toolbars[1].hide = true;
							this.toolbars[2].hide = true;
							this.toolbars[3].hide = true;
							this.toolbars[4].hide = true;
							break;
						case 'sign':
							commonService.openToast('MSG_CUSTSIGN_GUIDE', null, null, this.title);
							this.params.signShowGuide = true;
							this.toolbars[0].hide = true;
							this.toolbars[1].hide = false;
							this.toolbars[2].hide = false;
							this.toolbars[3].hide = false;
							this.toolbars[4].hide = false;
							this.toolbars[1].disabled = true;
							this.toolbars[2].disabled = true;
							this.toolbars[3].disabled = true;
							this.toolbars[4].disabled = false;
							this.resizeCanvas();
							break;
					}
					break;
				case 'Z':
				case 'X':
				default:
					this.params.signMode = 'view';
					this.toolbars[0].hide = true;
					this.toolbars[1].hide = true;
					this.toolbars[2].hide = true;
					this.toolbars[3].hide = true;
					this.toolbars[4].hide = true;
					break;
			}
		},
	},
});
</script>

<style scoped lang="scss">
div.sign-content {
	display: block;
	width: 100%;
	height: 100%;
	position: relative;
	&:before {
		content: '';
		position: absolute;
		display: inline-block;
		left: 1rem;
		right: 1rem;
		top: 1rem;
		bottom: 1rem;
		background-color: white;
		border-radius: 3rem;
		border: 3px dashed rgba(0, 0, 0, 0.3);
		pointer-events: none;
	}
	div.sign-pad,
	div.preview {
		position: absolute;
		left: 0;
		right: 0;
		top: 0;
		bottom: 0;
		text-align: center;
		> span,
		> img {
			pointer-events: none;
			position: absolute;
			left: 50%;
			top: 50%;
			max-height: 100%;
			transform: translate(-50%, -50%);
		}
		> span {
			font-family: Georgia, serif;
			font-size: 2.5em;
			color: #d0d0d0;
			font-style: italic;
		}
	}
}
</style>
