<template>
	<div class="panel panel-default voter-add-page">
		<div class="panel-body">
			<div class="voter-add-page__header clearfix">
				<h4 class="pull-left">Tambah Pengundi</h4>
				<div class="pull-right voter-add-page__header-actions">
					<button type="button" class="btn btn-success" @click="openManualModal">
						<i class="fa fa-user-plus"></i> Daftar pengundi baru
					</button>
					<router-link :to="{ name: 'Manage Voter' }" class="btn btn-default">
						<i class="fa fa-arrow-left"></i> Kembali
					</router-link>
				</div>
			</div>

			<p class="text-muted small voter-add-page__intro">
				Kiri: keseluruhan pengundi (ikut No. KP, data terkini). Kanan: yang ditanda layak untuk pilihan raya
				semasa.
				Yang tidak berada di senarai kanan akan dipadam daripada pilihan raya ini apabila anda simpan.
			</p>

			<div class="voter-add-split row">
				<div class="col-md-6 voter-add-split__col">
					<div class="panel panel-default voter-add-split__panel">
						<div class="panel-heading clearfix">
							<strong class="pull-left">Semua pengundi</strong>
							<span v-if="catalogLoading" class="text-muted small pull-left voter-add-heading__loading">
								<i class="fa fa-spinner fa-spin"></i>
							</span>
							<span class="badge pull-right" title="Jumlah pengundi unik (No. KP)">{{ catalog.length
								}}</span>
							<span v-if="catalogFilter"
								class="text-muted small pull-right voter-add-heading__filter-hint">
								{{ filteredCatalog.length }} dipaparkan ·
							</span>
						</div>
						<div class="panel-body">
							<div class="form-inline voter-batch-toolbar">
								<input type="text" class="form-control" v-model.trim="catalogFilter"
									placeholder="Tapis nama / No. KP / No. anggota…" />
								<button type="button" class="btn btn-default btn-sm" @click="selectAllFiltered">Tanda
									semua (ditapis)</button>
								<button type="button" class="btn btn-default btn-sm" @click="clearAllFiltered">Nyahtanda
									(ditapis)</button>
							</div>
							<div v-if="catalogError" class="alert alert-danger">{{ catalogError }}</div>
							<div class="table-responsive voter-add-table-wrap">
								<table class="table table-bordered table-condensed table-striped"
									v-if="!catalogLoading || catalog.length">
									<thead>
										<tr>
											<th style="width:44px;">
												<input type="checkbox" :checked="headerChecked"
													@change="toggleHeader($event)" />
											</th>
											<th>Nama</th>
											<th>No. KP</th>
											<th>No. Anggota</th>
											<th>Unit</th>
											<th style="width:88px;">PR semasa</th>
										</tr>
									</thead>
									<tbody>
										<tr v-for="row in filteredCatalog" :key="row.no_kp">
											<td>
												<input type="checkbox" :checked="isSelected(row.no_kp)"
													@change="toggleRow(row.no_kp, $event)" />
											</td>
											<td>{{ row.name }}</td>
											<td>{{ row.no_kp }}</td>
											<td>{{ row.no_anggota }}</td>
											<td>{{ row.unit }}</td>
											<td>
												<span v-if="row.in_current_election"
													class="label label-success">Ya</span>
												<span v-else class="label label-default">—</span>
											</td>
										</tr>
									</tbody>
								</table>
							</div>
							<p v-if="!catalogLoading && !catalog.length" class="text-muted">Tiada rekod pengundi dalam
								pangkalan data.</p>
						</div>
					</div>
				</div>

				<div class="col-md-6 voter-add-split__col">
					<div class="panel panel-info voter-add-split__panel">
						<div class="panel-heading clearfix">
							<strong class="pull-left">Layak mengundi (pilihan raya semasa)</strong>
							<span class="badge pull-right" title="Jumlah ditanda layak">{{ selectedNoKp.length }}</span>
							<span v-if="selectedFilter"
								class="text-muted small pull-right voter-add-heading__filter-hint">
								{{ filteredSelectedRows.length }} dipaparkan ·
							</span>
						</div>
						<div class="panel-body">
							<div class="form-inline voter-batch-toolbar voter-batch-toolbar--right">
								<input type="text" class="form-control" v-model.trim="selectedFilter"
									placeholder="Tapis senarai dipilih…" />
								<button type="button" class="btn btn-default btn-sm" @click="clearAllSelected"
									:disabled="!selectedNoKp.length">
									Kosongkan semua
								</button>
								<button type="button" class="btn btn-primary"
									:disabled="catalogSaving || catalogLoading" @click="saveApplicable()">
									Simpan pilihan
								</button>
							</div>
							<div class="table-responsive voter-add-table-wrap voter-add-table-wrap--selected">
								<table class="table table-bordered table-condensed table-striped"
									v-if="filteredSelectedRows.length">
									<thead>
										<tr>
											<th>Nama</th>
											<th>No. KP</th>
											<th>No. Anggota</th>
											<th style="width:52px;"></th>
										</tr>
									</thead>
									<tbody>
										<tr v-for="row in filteredSelectedRows" :key="row.no_kp">
											<td>{{ row.name }}</td>
											<td>{{ row.no_kp }}</td>
											<td>{{ row.no_anggota }}</td>
											<td class="text-center">
												<button type="button" class="btn btn-xs btn-danger" title="Buang"
													@click="removeSelected(row.no_kp)">
													<i class="fa fa-times"></i>
												</button>
											</td>
										</tr>
									</tbody>
								</table>
								<p v-else class="text-muted voter-add-empty-selected">Tiada pengundi ditanda. Tandakan
									pada jadual kiri.</p>
							</div>
						</div>
					</div>
				</div>
			</div>

			<!-- Modal for adding new voter -->
			<modal id="add-voter-manual-modal">
				<modal-header>Daftar pengundi baru</modal-header>
				<modal-body>
					<form @submit.prevent="add()" id="add-form">
						<div class="form-group">
							<label for="add-form-name">Nama Anggota</label>
							<input id="add-form-name" type="text" name="name" class="form-control" required>
						</div>
						<div class="form-group">
							<label for="add-form-no_kp">No. Kad Pengenalan</label>
							<input id="add-form-no_kp" type="text" name="no_kp" class="form-control" required>
						</div>
						<div class="form-group">
							<label for="add-form-no_anggota">No. Anggota</label>
							<input id="add-form-no_anggota" type="text" name="no_anggota" class="form-control" required>
						</div>
						<div class="form-group">
							<label for="add-form-unit">Unit</label>
							<input id="add-form-unit" type="text" name="unit" class="form-control" required>
						</div>
						<div class="form-group">
							<label for="add-form-alamat">Alamat</label>
							<input id="add-form-alamat" type="text" name="alamat" class="form-control" required>
						</div>
						<div class="form-group">
							<label for="add-form-status_anggota">Status Anggota</label>
							<select id="add-form-status_anggota" name="status_anggota" class="form-control" required>
								<option value="inactive">-- Pilih Status --</option>
								<option value="active">Aktif</option>
								<option value="inactive">Berhenti</option>
							</select>
						</div>
						<div class="form-group">
							<label for="add-form-telefon">No. Telefon</label>
							<input id="add-form-telefon" type="text" name="telefon" class="form-control" required>
						</div>
						<div class="form-group">
							<label for="add-form-saham">Saham</label>
							<input id="add-form-saham" type="text" name="saham" class="form-control" required>
						</div>
						<div class="form-group">
							<label for="add-form-yuran">Yuran</label>
							<input id="add-form-yuran" type="text" name="yuran" class="form-control" required>
						</div>
					</form>
				</modal-body>
				<modal-footer>
					<button type="button" class="btn btn-success" :disabled="loading" @click="add()">Hantar</button>
					<button type="button" class="btn btn-default" @click="closeManualModal">Batal</button>
				</modal-footer>
			</modal>
		</div>
	</div>
</template>

<style>
.voter-add-page__header {
	margin-bottom: 12px;
}

.voter-add-page__header h4 {
	margin-top: 0;
}

.voter-add-page__header-actions .btn {
	margin-left: 6px;
}

.voter-add-page__intro {
	margin-bottom: 16px;
}

.voter-add-split__col {
	margin-bottom: 16px;
}

.voter-add-split__panel {
	margin-bottom: 0;
}

.voter-batch-toolbar .form-control {
	min-width: 180px;
	margin-right: 8px;
	margin-bottom: 8px;
}

.voter-batch-toolbar .btn {
	margin-right: 6px;
	margin-bottom: 8px;
}

.voter-add-table-wrap {
	max-height: min(520px, calc(100vh - 280px));
	overflow: auto;
	margin-top: 10px;
}

.voter-add-table-wrap--selected {
	min-height: 120px;
}

.voter-add-empty-selected {
	margin: 16px 0 0;
}

.voter-add-heading__loading {
	margin-left: 8px;
	margin-top: 3px;
}

.voter-add-heading__filter-hint {
	margin-right: 8px;
	margin-top: 4px;
}
</style>

<script>
export default {
	data: function () {
		return {
			loading: false,
			catalog: [],
			catalogLoading: false,
			catalogSaving: false,
			catalogError: '',
			catalogFilter: '',
			selectedFilter: '',
			selectedNoKp: []
		}
	},

	computed: {
		catalogByKp: function () {
			var map = {};
			var i;
			for (i = 0; i < this.catalog.length; i++) {
				map[this.catalog[i].no_kp] = this.catalog[i];
			}
			return map;
		},

		selectedRows: function () {
			var map = this.catalogByKp;
			var out = [];
			var i;
			for (i = 0; i < this.selectedNoKp.length; i++) {
				var kp = this.selectedNoKp[i];
				if (map[kp]) out.push(map[kp]);
			}
			return out;
		},

		filteredCatalog: function () {
			var q = (this.catalogFilter || '').toLowerCase();
			if (!q) return this.catalog;
			return this.catalog.filter(function (row) {
				return (row.name && String(row.name).toLowerCase().indexOf(q) !== -1)
					|| (row.no_kp && String(row.no_kp).toLowerCase().indexOf(q) !== -1)
					|| (row.no_anggota && String(row.no_anggota).toLowerCase().indexOf(q) !== -1)
					|| (row.unit && String(row.unit).toLowerCase().indexOf(q) !== -1);
			});
		},

		filteredSelectedRows: function () {
			var rows = this.selectedRows;
			var q = (this.selectedFilter || '').toLowerCase();
			if (!q) return rows;
			return rows.filter(function (row) {
				return (row.name && String(row.name).toLowerCase().indexOf(q) !== -1)
					|| (row.no_kp && String(row.no_kp).toLowerCase().indexOf(q) !== -1)
					|| (row.no_anggota && String(row.no_anggota).toLowerCase().indexOf(q) !== -1)
					|| (row.unit && String(row.unit).toLowerCase().indexOf(q) !== -1);
			});
		},

		headerChecked: function () {
			var rows = this.filteredCatalog;
			if (!rows.length) return false;
			var vm = this;
			return rows.every(function (r) { return vm.isSelected(r.no_kp); });
		}
	},

	created: function () {
		this.loadMemberCatalog();
	},

	methods: {
		openManualModal: function () {
			this.util.showModal('#add-voter-manual-modal');
		},

		closeManualModal: function () {
			this.util.hideModal('#add-voter-manual-modal');
		},

		resetManualForm: function () {
			var el = document.getElementById('add-form');
			if (el) el.reset();
		},

		loadMemberCatalog: function () {
			var vm = this;
			this.catalogLoading = true;
			this.catalogError = '';
			axios.get(config.API + 'voter/member-catalog')
				.then(function (res) {
					vm.catalog = (res.data && res.data.catalog) ? res.data.catalog : [];
					vm.selectedNoKp = vm.catalog.filter(function (r) { return r.in_current_election; }).map(function (r) { return r.no_kp; });
				})
				.catch(function (err) {
					vm.catalogError = (err.response && err.response.data && err.response.data.message)
						? err.response.data.message
						: 'Gagal memuatkan senarai.';
					vm.util.showResult(err);
				})
				.finally(function () {
					vm.catalogLoading = false;
				});
		},

		isSelected: function (noKp) {
			return this.selectedNoKp.indexOf(noKp) !== -1;
		},

		toggleRow: function (noKp, evt) {
			var arr = this.selectedNoKp.slice();
			var i = arr.indexOf(noKp);
			if (evt.target.checked) {
				if (i === -1) arr.push(noKp);
			} else {
				if (i !== -1) arr.splice(i, 1);
			}
			this.selectedNoKp = arr;
		},

		toggleHeader: function (evt) {
			var want = evt.target.checked;
			var keys = this.filteredCatalog.map(function (r) { return r.no_kp; });
			var set = {};
			var i;
			for (i = 0; i < this.selectedNoKp.length; i++) {
				set[this.selectedNoKp[i]] = true;
			}
			if (want) {
				for (i = 0; i < keys.length; i++) set[keys[i]] = true;
			} else {
				for (i = 0; i < keys.length; i++) delete set[keys[i]];
			}
			this.selectedNoKp = Object.keys(set);
		},

		selectAllFiltered: function () {
			var set = {};
			var i;
			for (i = 0; i < this.selectedNoKp.length; i++) {
				set[this.selectedNoKp[i]] = true;
			}
			var rows = this.filteredCatalog;
			for (i = 0; i < rows.length; i++) set[rows[i].no_kp] = true;
			this.selectedNoKp = Object.keys(set);
		},

		clearAllFiltered: function () {
			var remove = {};
			var i;
			var rows = this.filteredCatalog;
			for (i = 0; i < rows.length; i++) remove[rows[i].no_kp] = true;
			this.selectedNoKp = this.selectedNoKp.filter(function (kp) { return !remove[kp]; });
		},

		removeSelected: function (noKp) {
			this.selectedNoKp = this.selectedNoKp.filter(function (kp) { return kp !== noKp; });
		},

		clearAllSelected: function () {
			this.selectedNoKp = [];
		},

		saveApplicable: function () {
			if (this.catalogSaving) return;
			var vm = this;
			this.catalogSaving = true;
			this.util.notify('Menyimpan…', 'loading');
			axios.post(config.API + 'voter/sync-applicable', { selected_no_kp: this.selectedNoKp })
				.then(function (res) {
					$.notifyClose();
					if (vm.util.showResult(res, 'success')) {
						vm.$router.push({ name: 'Manage Voter' });
					}
				})
				.catch(function (err) {
					$.notifyClose();
					vm.util.showResult(err);
				})
				.finally(function () {
					vm.catalogSaving = false;
				});
		},

		add: function () {
			if (this.loading) return;
			this.loading = true;
			var vm = this;
			this.util.notify('Adding Voter', 'loading');
			axios.post(config.API + 'voter', $('#add-form').serialize())
				.then(function (response) {
					$.notifyClose();
					vm.loading = false;
					if (vm.util.showResult(response, 'success')) {
						vm.closeManualModal();
						vm.resetManualForm();
						vm.$router.push({ name: 'Manage Voter' });
					}
				})
				.catch(function (error) {
					$.notifyClose();
					vm.loading = false;
					vm.util.showResult(error);
				});
		}
	}
}
</script>
