<template>
	<ion-page>
		<sgc-page :title="title" :useRefresh="true" :toolbars="toolbars" @sgcRefresh="onSearch">
			<form novalidate @submit.prevent="onSearch">
				<ion-list class="item-form">
					<div class="ion-justify-content-center ion-align-items-center">
						<ion-button slot="start" type="button" size="small" color="primary" @click="setDate('PREV')">
							<ion-icon :icon="Icon.chevronBackOutline"></ion-icon>
							{{ $t('ROOM.BTN_PREV') }}
						</ion-button>
						<sgc-item-input
							type="datetime"
							:required="true"
							v-model="searchModel.reYyyymmdd"
							@sgcChange="onSearch()"
							ref="reYyyymmdd"
							class="ion-margin-start"
						></sgc-item-input>
						<ion-button slot="end" type="button" size="small" color="primary" @click="setDate('NEXT')">
							{{ $t('ROOM.BTN_NEXT') }}
							<ion-icon :icon="Icon.chevronForwardOutline"></ion-icon>
						</ion-button>
					</div>
				</ion-list>
			</form>
			<div class="table-wrap" v-if="params.calHours && params.selectLoc">
				<div class="virtual-scroll">
					<table class="cal-table fixed">
						<thead>
							<tr>
								<th class="cell-location">{{ $t('ROOM.LBL_LOCATION') }}</th>
								<th class="cell-room">{{ $t('ROOM.LBL_ROOM') }}</th>
							</tr>
						</thead>
						<tbody v-for="(location, l) in params.selectLoc" :key="l">
							<tr v-for="(room, j) in location.children" :key="j">
								<th v-if="j === 0" class="cell-location" :rowspan="location.children.length">
									{{ location.mrLocation }}
								</th>
								<th class="cell-room">
									{{ room.bunho }}
								</th>
							</tr>
						</tbody>
					</table>
					<table class="cal-table">
						<thead>
							<tr>
								<th v-for="(hour, i) in params.calHours" :key="i" colspan="2">
									{{ hour }}
								</th>
							</tr>
						</thead>
						<tbody v-for="(location, l) in params.selectLoc" :key="l">
							<tr v-for="(room, j) in location.children" :key="j">
								<td v-for="(cell, k) in room.dayCells" :key="k" :colspan="cell.colspan" :style="{ backgroundColor: cell.color }">
									<ion-text class="room-rev" v-if="cell.reservationId" @click="viewRemMeetingCon(null, cell.reservationId)">{{ cell.text }}</ion-text>
									<ion-text v-else>-</ion-text>
								</td>
							</tr>
						</tbody>
					</table>
				</div>
			</div>
			<sgc-loading :loadStatus="loadStatus" loadType="list">
				<ion-list class="item-list">
					<ion-list-header>
						<ion-label>{{ $t('ROOM.LBL_ROOMREV') }}</ion-label>
					</ion-list-header>
					<ion-item v-for="(item, i) in dataList" :key="i">
						<ion-label @click="viewRemMeetingCon(item)">
							<h3>
								<ion-badge slot="end">{{ item.statusNm }}</ion-badge>
								{{ item.meetingName }}
							</h3>
							<h4>{{ item.locationNm }} -{{ item.bunho }}</h4>
							<p>{{ item.pymd }}<br />{{ item.phm }}</p>
							<p>
								{{ item.subscName }}
								<span v-if="item.attendNum">({{ item.attendNum }} 명)</span>
							</p>
						</ion-label>
						<ion-text slot="end">
							<ion-button fill="solid" @click="setCancelClose(item, 'CANCEL')" :disabled="item?.cancelYn != 'Y' || !item.myRomResrv">{{
								$t('ROOM.BTN_REV_CANCEL')
							}}</ion-button
							><br />
							<ion-button fill="solid" @click="setCancelClose(item, 'CLOSE')" :disabled="item?.closeYn != 'Y' || !item.myRomResrv">{{
								$t('ROOM.BTN_REV_END')
							}}</ion-button>
						</ion-text>
					</ion-item>
				</ion-list>
			</sgc-loading>
		</sgc-page>
	</ion-page>
</template>

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

import { ListDataVo, RoomDayInfoVo, RoomInfoVo, RoomLocationVo, RoomRemInfoVo, RoomDayCellVo } from '../../services/common.interface';

import { PoRoomRevRegModal, PoRoomRevViewModal } from './modals/index';

/**
 * 임직원 - 회의실 예약
 *
 * 회의실 일자별 예약 목록 과 예약을 진행하는 페이지
 */
export default defineComponent({
	name: 'PoRoomRevPage',
	components: {
		...IonPageModules,
		...IonFormModules,
	},
	mounted() {
		this.searchModel.reYyyymmdd = utils.getDate();
		commonService.getList('api/room/selectLoc', {}).then((selectLoc) => {
			this.params.selectLoc = selectLoc;
			commonService.getList('api/room/romInfo', {}).then((romInfo) => {
				this.params.romInfo = romInfo;
				this.changeMap();
				this.onSearch();
			});
		});
	},
	setup() {
		return {
			utils,
			Icon,
		};
	},
	data(): ListDataVo<
		RoomRemInfoVo,
		{
			reYyyymmdd: string;
		},
		{
			selectLoc: RoomLocationVo[];
			romInfo: RoomInfoVo[];
			listDay: RoomDayInfoVo[];
			selectLocMap: { [key: string | number]: RoomLocationVo };
			romInfoMap: { [key: string | number]: RoomInfoVo };
			remInfoMap: { [key: string | number]: RoomRemInfoVo };
			calHours: string[];
		}
	> {
		return {
			title: 'TIT_ROOMREV',
			loadStatus: 'ready',
			searchModel: {
				// 기준일자
				reYyyymmdd: '',
			},
			dataList: [],
			codeKey: {
				siteCd: 'SITECD',
				dong: '',
				hsno: '',
			},
			params: {
				selectLoc: [],
				romInfo: [],
				listDay: [],
				selectLocMap: {},
				romInfoMap: {},
				remInfoMap: {},
				calHours: ['07', '08', '09', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22'],
			},
			toolbars: [
				{
					color: 'primary',
					label: 'ROOM.BTN_REG_ONE',
					click: () => {
						this.setRoomRevReg('ONE');
					},
				},
				{
					color: 'primary',
					label: 'ROOM.BTN_REG_REP',
					click: () => {
						this.setRoomRevReg('REP');
					},
				},
				{
					color: 'primary',
					label: 'ROOM.BTN_REG_RANGE',
					click: () => {
						this.setRoomRevReg('RANGE');
					},
				},
			],
		};
	},
	methods: {
		/** 회의실 맵 변경 */
		changeMap() {
			if (this.params.selectLoc) {
				this.params.selectLoc.forEach((loc) => {
					this.params.selectLocMap[loc.locationId] = loc;
					loc.children = [];
				});
				this.params.romInfo.forEach((room) => {
					this.params.romInfoMap[room.meetingroomId] = room;
					const locationId = room.locationId;
					if (this.params.selectLocMap[locationId] !== undefined) {
						this.params.selectLocMap[locationId].children.push(room);
					}
				});
			}
		},
		/** 일별 회의실 예약 정보 변경 */
		changeDayMap() {
			this.params.remInfoMap = {};
			this.dataList.forEach((rem) => {
				this.params.remInfoMap['' + rem.reservationId] = rem;
			});
			this.params.romInfo.forEach((room) => {
				room.dayInfo = {};
				room.dayCells = [];
			});
			this.params.listDay.forEach((info) => {
				const meetingroomId = info.meetingroomId;
				if (this.params.romInfoMap[meetingroomId] !== undefined) {
					this.params.romInfoMap[meetingroomId].dayInfo = info;
				}
			});
			const hourAttrList = [
				't070',
				't073',
				't080',
				't083',
				't090',
				't093',
				't100',
				't103',
				't110',
				't113',
				't120',
				't123',
				't130',
				't133',
				't140',
				't143',
				't150',
				't153',
				't160',
				't163',
				't170',
				't173',
				't180',
				't183',
				't190',
				't193',
				't200',
				't203',
				't210',
				't213',
				't220',
				't223',
			];
			this.params.romInfo.forEach((room) => {
				room.dayCells = [];
				if (commonService.isNull(room.dayInfo) && commonService.isNull(room.dayInfo.bunho)) {
					hourAttrList.forEach(() => {
						room.dayCells.push({ color: 'inherit', reservationId: null, text: '-', colspan: 1 });
					});
				} else {
					const dayInfo: any = room.dayInfo;
					let lastCell: RoomDayCellVo = null;
					hourAttrList.forEach((attr) => {
						const attrText = dayInfo[attr];
						const attrId = dayInfo['id' + attr];
						if (commonService.isNull(attrText) || commonService.isNull(attrId)) {
							lastCell = null;
							room.dayCells.push({ color: 'inherit', reservationId: null, text: '-', colspan: 1 });
						} else {
							const [revId, cType] = attrId.split('/');
							if (lastCell !== null && lastCell.reservationId === revId) {
								lastCell.colspan++;
							} else {
								let cellColor = 'inherit';
								switch (cType) {
									case 'Q':
										cellColor = '#fbbca2';
										break;
									case 'E':
										cellColor = '#fbf8bd';
										break;
									case 'S':
										cellColor = '#c0c9f8';
										break;
									case 'P':
										cellColor = '#9cdcf8';
										break;
									case 'G':
										cellColor = '#f4b7f0';
										break;
									case 'L':
										cellColor = '#affabc';
										break;
								}
								lastCell = { color: cellColor, reservationId: revId, text: attrText, colspan: 1 };
								room.dayCells.push(lastCell);
							}
						}
					});
				}
			});
		},
		/** 회의실 예약 정보 보기 */
		viewRemMeetingCon(item: RoomRemInfoVo, id = '') {
			if (item === null && id !== null && id !== '') {
				const [reservationId] = id.split('/');
				if (this.params.remInfoMap[reservationId] !== undefined) {
					item = this.params.remInfoMap[reservationId];
				}
			}
			if (item !== null) {
				// 모달로 상세  내용 보여 줄 경우
				commonService.openModal(PoRoomRevViewModal, {
					remInfo: { reservationId: item.reservationId },
					showType: 'VIEW',
				});
				/*
				// Alert 으로 보여 줄 경우
				commonService.openAlert(item.meetingCon || item.meetingName, null, {
					header: 'ROOM.LBL_MEETING_CON',
					backdropDismiss: true,
				});
				*/
			}
		},
		/**
		 * 회의실 예약 하기
		 * @param type
		 */
		setRoomRevReg(type: string) {
			commonService.openModal(PoRoomRevRegModal, { remInfo: {}, showType: type }).then(() => {
				this.onSearch();
			});
		},
		/**
		 * 회의실 예약 취소, 종료하기
		 * @param item 예약 정보
		 * @param type  CANCEL,CLOSE
		 */
		setCancelClose(item: RoomRemInfoVo, type: string) {
			switch (type) {
				case 'CANCEL':
					if (item?.cancelYn !== 'Y') {
						commonService.openToast(item?.cancelCn || 'MSG_UNKNOWN', null, null, this.title, 'warning');
					} else {
						commonService
							.openModal(PoRoomRevViewModal, {
								remInfo: { reservationId: item.reservationId },
								showType: 'CANCEL',
							})
							.then(() => {
								this.onSearch();
							});
					}
					break;
				case 'CLOSE':
					if (item?.closeYn !== 'Y') {
						commonService.openToast(item?.closeCn || 'MSG_UNKNOWN', null, null, this.title, 'warning');
					} else {
						commonService
							.openModal(PoRoomRevViewModal, {
								remInfo: { reservationId: item.reservationId },
								showType: 'CLOSE',
							})
							.then(() => {
								this.onSearch();
							});
					}
					break;
			}
		},
		/**
		 * 이전 다음 일자 설정하기
		 * @param mode
		 */
		setDate(mode: string) {
			switch (mode) {
				case 'PREV':
					this.searchModel.reYyyymmdd = utils.getDateAddDay(this.searchModel.reYyyymmdd, -1);
					break;
				case 'NEXT':
					this.searchModel.reYyyymmdd = utils.getDateAddDay(this.searchModel.reYyyymmdd, 1);
					break;
			}
			this.onSearch();
		},
		/** 검색하기 */
		onSearch() {
			commonService.checkLoadStatusList(
				this,
				commonService
					.getList(
						'api/room/listDay',
						commonService.getSubmitData(this.searchModel, {
							reYyyymmdd: 'date',
						})
					)
					.then((list) => {
						this.params.listDay = list;
						const remParams = commonService.getSubmitData(
							this.searchModel,
							{
								reYyyymmdd: 'date',
							},
							{ meetingroomId: 'all', status: 'all' }
						);
						remParams.reYyyymmddF = remParams.reYyyymmdd;
						remParams.reYyyymmddT = remParams.reYyyymmdd;
						return commonService.getList('api/room/listRem', remParams);
					})
					.then((list) => {
						this.dataList = list || [];
					})
					.finally(() => {
						this.changeDayMap();
					})
			);
		},
	},
});
</script>
<style scoped lang="scss">
div.table-wrap {
	padding: 1rem;
	border-radius: 0.5rem;
	background: #fff;
	box-sizing: border-box;
	position: relative;

	div.virtual-scroll {
		max-width: 300vw;
		overflow-x: auto;
		overflow-y: hidden;
		font-size: 0.7em;
		padding-left: 8.1rem;
		border: 1px solid var(--ion-color-tertiary-tint);

		table.cal-table {
			border-collapse: collapse;
			border-spacing: 0;
			margin: 0;

			&.fixed {
				position: absolute;
				left: 1rem;
				top: 17px;
			}

			thead {
				th,
				td {
					background-color: var(--ion-color-tertiary);
					color: var(--ion-color-tertiary-contrast);
					padding: 0.5em 0.3em;
					height: 2rem;
				}
			}

			th,
			td {
				margin: 0;
				white-space: nowrap;
				padding: 0.2em 0.3em;
				border: 1px solid var(--ion-color-tertiary-tint);
				white-space: nowrap;
				text-align: center;
				min-width: 3em;

				ion-text {
					display: block;
					text-align: left;
				}
			}

			tbody {
				> tr {
					th,
					td {
						height: 1.6rem;
					}
				}
			}

			thead > tr,
			tbody > tr {
				th.cell-location,
				th.cell-room {
					width: 4rem;
				}
			}

			tbody > tr {
				th.cell-location,
				th.cell-room {
					background-color: var(--background);
				}
			}

			&:hover {
				tbody {
					th.cell-location,
					th.cell-room {
						opacity: 0.7;
					}
				}
			}
		}
	}
}

div.ion-justify-content-center {
	display: flex;
}
</style>
