<template>
	<div class="panel panel-default">
		<div class="panel-body">
			<div class="kehadiran-actions clearfix">
				<button class="btn btn-success" @click="refreshVoter()">
					<i class="fa fa-refresh"></i> Kemaskini Pengundi
				</button>

				<a class="btn btn-warning pull-right" :href="getPDFKehadiranurl(1)">
					<i class="fa fa-download"></i> Muat Turun PDF
				</a>
			</div>

			<div class="kehadiran-search">
				<div class="kehadiran-search__label">Carian pantas (kaunter):</div>
				<input class="form-control kehadiran-search__input" v-model.trim="searchNoAnggota"
					placeholder="No. Anggota" />
				<input class="form-control kehadiran-search__input" v-model.trim="searchNoKp"
					placeholder="No. Kad Pengenalan" />
				<button class="btn btn-primary" @click="applySearch()">Cari</button>
				<button class="btn btn-default" @click="clearSearch()" :disabled="!hasAnySearch">Reset</button>
			</div>

			<div class="kehadiran-filter-panel">
				<div class="kehadiran-filter-panel__title">Penapis</div>
				<div class="kehadiran-filter-groups">
					<div class="kehadiran-filter-group">
						<div class="kehadiran-filter-group__title">Kaedah kehadiran</div>
						<div class="kehadiran-filter-group__chips">
							<button type="button" class="kehadiran-chip" :class="{ 'is-active': !current_kehadiran }"
								@click="setKehadiranFilter(null)">
								Semua
							</button>
							<button type="button" class="kehadiran-chip"
								:class="{ 'is-active': String(current_kehadiran) === 'unset' }"
								@click="setKehadiranFilter('unset')">
								Belum Ditetapkan
							</button>
							<button type="button" class="kehadiran-chip"
								:class="{ 'is-active': Number(current_kehadiran) === 1 }"
								@click="setKehadiranFilter(1)">
								Fizikal
							</button>
							<button type="button" class="kehadiran-chip"
								:class="{ 'is-active': Number(current_kehadiran) === 2 }"
								@click="setKehadiranFilter(2)">
								Maya
							</button>
						</div>
					</div>
					<div class="kehadiran-filter-group">
						<div class="kehadiran-filter-group__title">Pendaftaran fizikal</div>
						<div class="kehadiran-filter-group__chips">
							<button type="button" class="kehadiran-chip" :class="{ 'is-active': !current_fizikal_reg }"
								@click="setFizikalRegFilter(null)">
								Semua
							</button>
							<button type="button" class="kehadiran-chip"
								:class="{ 'is-active': current_fizikal_reg === 'pending' }"
								@click="setFizikalRegFilter('pending')">
								Menunggu pengesahan
							</button>
							<button type="button" class="kehadiran-chip"
								:class="{ 'is-active': current_fizikal_reg === 'verified' }"
								@click="setFizikalRegFilter('verified')">
								Disahkan
							</button>
						</div>
					</div>
					<div class="kehadiran-filter-group">
						<div class="kehadiran-filter-group__title">Undi</div>
						<div class="kehadiran-filter-group__chips">
							<button type="button" class="kehadiran-chip" :class="{ 'is-active': !current_has_voted }"
								@click="setHasVotedFilter(null)">
								Semua
							</button>
							<button type="button" class="kehadiran-chip"
								:class="{ 'is-active': current_has_voted === '1' }"
								@click="setHasVotedFilter('1')">
								Undi
							</button>
							<button type="button" class="kehadiran-chip"
								:class="{ 'is-active': current_has_voted === '0' }"
								@click="setHasVotedFilter('0')">
								Belum
							</button>
						</div>
					</div>
					<div class="kehadiran-filter-group">
						<div class="kehadiran-filter-group__title">Bayaran tunai (elaun)</div>
						<div class="kehadiran-filter-group__chips">
							<button type="button" class="kehadiran-chip" :class="{ 'is-active': !current_cash_status }"
								@click="setCashStatusFilter(null)">
								Semua
							</button>
							<button type="button" class="kehadiran-chip"
								:class="{ 'is-active': current_cash_status === 'paid' }"
								@click="setCashStatusFilter('paid')">
								Sudah Bayar
							</button>
							<button type="button" class="kehadiran-chip"
								:class="{ 'is-active': current_cash_status === 'unpaid' }"
								@click="setCashStatusFilter('unpaid')">
								Belum Bayar
							</button>
						</div>
					</div>
				</div>
			</div>

			<!-- Attendance stats -->
			<div class="kehadiran-stats">
				<div class="kehadiran-stat">
					<div class="kehadiran-stat__label">Fizikal</div>
					<div class="kehadiran-stat__value">{{ attendanceStats.fizikalCount }}</div>
					<div class="kehadiran-stat__meta">{{ attendanceStats.fizikalPct }}%</div>
				</div>
				<div class="kehadiran-stat">
					<div class="kehadiran-stat__label">Maya</div>
					<div class="kehadiran-stat__value">{{ attendanceStats.mayaCount }}</div>
					<div class="kehadiran-stat__meta">{{ attendanceStats.mayaPct }}%</div>
				</div>
				<div class="kehadiran-stat kehadiran-stat--muted">
					<div class="kehadiran-stat__label">Jumlah Kehadiran</div>
					<div class="kehadiran-stat__value">{{ attendanceStats.totalAttendance }}</div>
					<div class="kehadiran-stat__meta">{{ attendanceStats.totalPct }}%</div>
				</div>
			</div>

			<!-- <a class="btn btn-warning" :href="getPDFKehadiranurl(1)">Muat Turun PDF</a> -->

			<admin-data-table :headers="kehadiranTableHeaders" :items="voterListItems" :loading="voterLoading"
				:show-pagination="true" index-title="Bil." empty-text="Tiada rekod kehadiran" :exportable="true">
				<template v-slot:item-kehadiran="{ item }">
					{{ getKehadiranString(item.kehadiran) }}
				</template>
				<template v-slot:item-fizikal_reg="{ item }">
					<span v-if="Number(item.kehadiran) !== 1" class="text-muted">—</span>
					<span v-else-if="item.fizikal_registration_verified_at"
						class="kehadiran-pill kehadiran-pill--success">
						<i class="fa fa-check-circle" aria-hidden="true"></i>
						<span>Disahkan</span>
					</span>
					<span v-else class="kehadiran-pill kehadiran-pill--warn">
						<i class="fa fa-clock-o" aria-hidden="true"></i>
						<span>Menunggu</span>
					</span>
				</template>
				<template v-slot:item-has_voted="{ item }">
					<span class="kehadiran-pill"
						:class="Number(item.votes_count) > 0 ? 'kehadiran-pill--success' : 'kehadiran-pill--muted'">
						<i class="fa" :class="Number(item.votes_count) > 0 ? 'fa-check-circle' : 'fa-times-circle'"
							aria-hidden="true"></i>
						<span>{{ Number(item.votes_count) > 0 ? 'Undi' : 'Belum' }}</span>
					</span>
				</template>
				<template v-slot:item-allowance="{ item }">
					<span class="kehadiran-pill"
						:class="isCashPaid(item) ? 'kehadiran-pill--success' : 'kehadiran-pill--warn'">
						<i class="fa" :class="isCashPaid(item) ? 'fa-money' : 'fa-exclamation-circle'"
							aria-hidden="true"></i>
						<span>{{ isCashPaid(item) ? 'Sudah Bayar' : 'Belum Bayar' }}</span>
					</span>
				</template>
				<template v-slot:item-action="{ item }">
					<div class="kehadiran-action-cell">
						<button type="button" class="btn btn-xs btn-primary kehadiran-action-btn"
							@click.stop="openDetail(item)">
							<i class="fa fa-eye" aria-hidden="true"></i>
							<span>Detail</span>
						</button>
						<button v-if="canVerifyFizikalRegistration(item)" type="button"
							class="btn btn-xs btn-success kehadiran-action-btn"
							@click.stop="openFizikalVerifyModal(item)">
							<i class="fa fa-check" aria-hidden="true"></i>
							<span>Sahkan</span>
						</button>
					</div>
				</template>
			</admin-data-table>

			<!-- Allowance Modal -->
			<div class="modal fade app-modal" id="allowance-modal" tabindex="-1" role="dialog" aria-hidden="true">
				<div class="modal-dialog modal-lg" role="document">
					<div class="modal-content">
						<div class="modal-header">
							<h4 class="modal-title">Butiran Pembayaran Elaun</h4>
							<button type="button" class="close" data-dismiss="modal" aria-label="Close">
								<span aria-hidden="true">&times;</span>
							</button>
						</div>

						<div class="modal-body" v-if="selectedVoter">
							<div class="row">
								<div class="col-md-6">
									<table class="table table-condensed">
										<tbody>
											<tr>
												<th style="width: 160px;">Nama</th>
												<td>{{ selectedVoter.name }}</td>
											</tr>
											<tr>
												<th>No. KP</th>
												<td>{{ selectedVoter.no_kp }}</td>
											</tr>
											<tr>
												<th>No. Anggota</th>
												<td>{{ selectedVoter.no_anggota }}</td>
											</tr>
											<tr>
												<th>Unit</th>
												<td>{{ selectedVoter.unit }}</td>
											</tr>
										</tbody>
									</table>
								</div>

								<div class="col-md-6">
									<table class="table table-condensed">
										<tbody>
											<tr>
												<th style="width: 160px;">Kehadiran</th>
												<td><b>{{ getKehadiranString(selectedVoter.kehadiran) }}</b></td>
											</tr>
											<tr v-if="Number(selectedVoter.kehadiran) === 1">
												<th>Pendaftaran</th>
												<td>
													<span v-if="selectedVoter.fizikal_registration_verified_at"
														class="label label-success">Disahkan</span>
													<span v-else class="label label-warning">Menunggu pengesahan</span>
												</td>
											</tr>
											<tr>
												<th>Saham (RM)</th>
												<td>{{ formatRmDisplay(selectedVoter.saham) }}</td>
											</tr>
											<tr>
												<th>Yuran (RM)</th>
												<td>{{ formatRmDisplay(selectedVoter.yuran) }}</td>
											</tr>
											<tr>
												<th>Status Undi</th>
												<td>
													<span class="label"
														:class="Number(selectedVoter.votes_count) > 0 ? 'label-success' : 'label-default'">
														{{ Number(selectedVoter.votes_count) > 0 ? 'Ya' : 'Tidak' }}
													</span>
													<span v-if="selectedVoterShowsNoVoteEligibleNote"
														class="label label-info" style="margin-left: 6px;">Tidak layak
														mengundi (saham)</span>
												</td>
											</tr>
											<tr>
												<th>Bayaran Tunai</th>
												<td>
													<span class="label"
														:class="isCashPaid(selectedVoter) ? 'label-success' : 'label-warning'">
														{{ isCashPaid(selectedVoter) ? ('Sudah (' +
															selectedVoter.cash_paid_at +
															')') : 'Belum' }}
													</span>
												</td>
											</tr>
										</tbody>
									</table>
								</div>
							</div>

							<hr />

							<div class="row">
								<div class="col-md-4">
									<label>Kod Tuntutan (Claim Code)</label>
									<input type="text" class="form-control" v-model.trim="claimCodeInput"
										placeholder="Contoh: 482913" />
									<small class="text-muted">Voter akan tunjuk kod ini. Wajib untuk bayaran
										tunai.</small>
								</div>
								<div class="col-md-4">
									<label>Jumlah Tunai (RM)</label>
									<input type="text" class="form-control kehadiran-tunai-readonly" readonly disabled
										:value="allowanceTunaiDisplay" />
								</div>
								<div class="col-md-4">
									<label>Rujukan (optional)</label>
									<input type="text" class="form-control" v-model.trim="payoutReference"
										maxlength="80" placeholder="Wakil/Sendiri" />
								</div>
							</div>

							<div class="row" style="margin-top: 10px;">
								<div class="col-md-12">
									<label>Nota (optional)</label>
									<input type="text" class="form-control" v-model.trim="payoutNote"
										placeholder="Nama Wakil" />
								</div>
							</div>

							<div v-if="isCashPaid(selectedVoter)" class="well well-sm" style="margin-top: 14px;">
								<div style="font-weight: 800; margin-bottom: 8px;">Maklumat Bayaran</div>
								<div>
									Dibayar oleh:
									<b>{{ selectedVoter.cash_paid_by_admin_name || '—' }}</b>
									<span v-if="selectedVoter.cash_paid_by_admin_email" class="text-muted">
										({{ selectedVoter.cash_paid_by_admin_email }})
									</span>
								</div>
							</div>

							<div class="alert alert-danger" v-if="detailError" style="margin-top: 12px;">
								{{ detailError }}
							</div>
						</div>

						<div class="modal-footer">
							<button type="button" class="btn btn-default" data-dismiss="modal">Tutup</button>
							<button type="button" class="btn btn-danger"
								v-if="selectedVoter && isCashPaid(selectedVoter)" :disabled="detailLoading"
								@click="voidCashPayout()">
								Batal Bayaran Tunai
							</button>
							<button type="button" class="btn btn-success"
								v-if="selectedVoter && canPayCash(selectedVoter)" :disabled="detailLoading"
								@click="payCash()">
								Bayar Tunai
							</button>
						</div>
					</div>
				</div>
			</div>

			<!-- Fizikal Verify Modal -->
			<div class="modal fade app-modal" id="fizikal-verify-modal" tabindex="-1" role="dialog"
				aria-labelledby="fizikal-verify-title" aria-hidden="true">
				<div class="modal-dialog" role="document">
					<div class="modal-content">
						<div class="modal-header">
							<h4 class="modal-title" id="fizikal-verify-title">Pengesahan pendaftaran fizikal</h4>
							<button type="button" class="close" data-dismiss="modal" aria-label="Close">
								<span aria-hidden="true">&times;</span>
							</button>
						</div>
						<div class="modal-body" v-if="verifyModalVoter">
							<p class="kehadiran-verify-lead" v-if="verifyModalVoterNeedsLowSahamNote">
								Pengundi fizikal ini mempunyai saham di bawah <strong>RM 500</strong> dan
								<strong>tidak dibenarkan mengundi</strong>. Sahkan pendaftaran untuk mengesahkan
								kehadiran
								di kaunter dan membolehkan mereka menuntut elaun tunai (mengikut peraturan portal).
							</p>
							<p class="kehadiran-verify-lead" v-else>
								Sahkan bahawa pengundi ini hadir di kaunter. Selepas ini, pengundi boleh mengundi.
							</p>
							<table class="table table-condensed table-bordered kehadiran-verify-summary">
								<tbody>
									<tr>
										<th style="width: 140px;">Nama</th>
										<td>{{ verifyModalVoter.name }}</td>
									</tr>
									<tr>
										<th>No. KP</th>
										<td>{{ verifyModalVoter.no_kp }}</td>
									</tr>
									<tr>
										<th>No. Anggota</th>
										<td>{{ verifyModalVoter.no_anggota }}</td>
									</tr>
									<tr>
										<th>Unit</th>
										<td>{{ verifyModalVoter.unit }}</td>
									</tr>
									<tr>
										<th>Saham (RM)</th>
										<td>{{ formatRmDisplay(verifyModalVoter.saham) }}</td>
									</tr>
									<tr>
										<th>Yuran (RM)</th>
										<td>{{ formatRmDisplay(verifyModalVoter.yuran) }}</td>
									</tr>
								</tbody>
							</table>
							<div class="alert alert-danger" v-if="verifyModalError" style="margin-bottom: 0;">
								{{ verifyModalError }}
							</div>
						</div>
						<div class="modal-footer">
							<button type="button" class="btn btn-default" data-dismiss="modal">Tutup</button>
							<button type="button" class="btn btn-primary" :disabled="verifyModalLoading"
								@click="submitFizikalVerify">
								<i class="fa fa-check" aria-hidden="true"></i> Sahkan pendaftaran
							</button>
						</div>
					</div>
				</div>
			</div>

			<!-- Display attendance percentage -->
			<div class="text-right">
				<h5><b>{{ attendancePercentage }}% Kehadiran Pengundi</b></h5>
			</div>

			<ul class="pagination" v-if="pages.length > 1">
				<router-link tag="li" v-for="page in pages" :key="page.page"
					:to="{ query: paginationQueryForPage(page.page) }"
					:class="{ active: Number(current_page) === page.page }" exact>
					<a href="#">{{ page.page }}</a>
				</router-link>
			</ul>
		</div>
	</div>
</template>

<style>
.kehadiran-actions {
	margin-bottom: 10px;
}

.kehadiran-stats {
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: 10px;
	margin: 10px 0 14px;
}

.kehadiran-stat {
	border: 1px solid #e5e7eb;
	background: #fff;
	border-radius: 10px;
	padding: 10px 12px;
}

.kehadiran-stat--muted {
	background: #f9fafb;
}

.kehadiran-stat__label {
	color: #6b7280;
	font-size: 12px;
	font-weight: 800;
	letter-spacing: 0.2px;
}

.kehadiran-stat__value {
	margin-top: 4px;
	font-size: 22px;
	font-weight: 900;
	color: #111827;
	line-height: 1.1;
}

.kehadiran-stat__meta {
	margin-top: 4px;
	color: #374151;
	font-size: 12px;
	font-weight: 700;
}

.kehadiran-search {
	margin: 10px 0 12px;
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: 8px;
}

.kehadiran-search__label {
	color: #6b7280;
	font-size: 12px;
	font-weight: 700;
}

.kehadiran-search__input {
	max-width: 220px;
	height: 34px;
}

.kehadiran-filter-panel {
	margin: 10px 0 14px;
	border: 1px solid #e5e7eb;
	border-radius: 10px;
	background: #f9fafb;
	padding: 12px 14px;
}

.kehadiran-filter-panel__title {
	font-size: 11px;
	font-weight: 800;
	text-transform: uppercase;
	letter-spacing: 0.06em;
	color: #6b7280;
	margin-bottom: 10px;
}

.kehadiran-filter-groups {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
	gap: 12px;
}

.kehadiran-filter-group {
	background: #fff;
	border: 1px solid #e5e7eb;
	border-radius: 8px;
	padding: 10px 12px;
}

.kehadiran-filter-group__title {
	font-size: 12px;
	font-weight: 700;
	color: #374151;
	margin-bottom: 8px;
	line-height: 1.3;
}

.kehadiran-filter-group__chips {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 8px;
}

.kehadiran-chip {
	border: 1px solid #d1d5db;
	background: #fff;
	color: #374151;
	padding: 6px 12px;
	border-radius: 999px;
	font-size: 12px;
	font-weight: 700;
	line-height: 1;
}

.kehadiran-chip:hover {
	background: #f3f4f6;
}

.kehadiran-chip.is-active {
	background: #1976d2;
	border-color: #1976d2;
	color: #fff;
}

.kehadiran-action-cell {
	display: inline-flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 6px;
}

.kehadiran-action-btn {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	font-weight: 700;
}

.kehadiran-action-btn>i {
	line-height: 1;
}

.kehadiran-verify-lead {
	margin-bottom: 12px;
	color: #374151;
	line-height: 1.5;
}

.kehadiran-verify-summary {
	margin-bottom: 0;
}

.kehadiran-tunai-readonly {
	background-color: #f3f4f6 !important;
	cursor: not-allowed;
	color: #1f2937;
}

.kehadiran-pill {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	padding: 3px 10px;
	border-radius: 999px;
	font-size: 12px;
	font-weight: 800;
	line-height: 1.4;
	border: 1px solid transparent;
	white-space: nowrap;
}

.kehadiran-pill>i {
	line-height: 1;
}

.kehadiran-pill--success {
	color: #0f5132;
	background: #d1e7dd;
	border-color: #badbcc;
}

.kehadiran-pill--warn {
	color: #664d03;
	background: #fff3cd;
	border-color: #ffecb5;
}

.kehadiran-pill--muted {
	color: #374151;
	background: #f3f4f6;
	border-color: #e5e7eb;
}
</style>

<script>
export default {
	data: function () {
		var vm = this;
		return {
			id: 0,
			voterLoading: false,
			searchNoAnggota: '',
			searchNoKp: '',
			selectedVoter: null,
			verifyModalVoter: null,
			verifyModalLoading: false,
			verifyModalError: '',
			detailLoading: false,
			detailError: '',
			claimCodeInput: '',
			payoutReference: '',
			payoutNote: '',
			kehadiranTableHeaders: [
				{ title: 'Nama Anggota', key: 'name', sortable: true },
				{ title: 'No. Kad Pengenalan', key: 'no_kp', sortable: true },
				{ title: 'No. Anggota', key: 'no_anggota', sortable: true },
				{ title: 'Unit', key: 'unit', sortable: true },
				{
					title: 'Kehadiran',
					key: 'kehadiran',
					sortable: true,
					exportValue: function (item) {
						return vm.getKehadiranString(item ? item.kehadiran : null);
					}
				},
				{
					title: 'Pendaftaran',
					key: 'fizikal_reg',
					sortable: false,
					exportValue: function (item) {
						if (!item) return '';
						if (Number(item.kehadiran) !== 1) return '—';
						return item.fizikal_registration_verified_at ? 'Disahkan' : 'Menunggu';
					}
				},
				{
					title: 'Undi',
					key: 'has_voted',
					sortable: false,
					exportValue: function (item) {
						return Number(item && item.votes_count) > 0 ? 'Undi' : 'Belum';
					}
				},
				{
					title: 'Status',
					key: 'allowance',
					sortable: false,
					exportValue: function (item) {
						return vm.isCashPaid(item) ? 'Sudah Bayar' : 'Belum Bayar';
					}
				},
				{ title: 'Tindakan', key: 'action', sortable: false },
			]
		}
	},

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

	methods: {
		search: function () {

		},

		refreshVoter: function () {
			var vm = this;
			this.voterLoading = true;
			this.util.notify('Refreshing Voter', 'loading');
			axios.get(config.API + 'voter', {
				params: {
					page: this.current_page,
					kehadiran: this.current_kehadiran || undefined,
					fizikal_reg: this.current_fizikal_reg || undefined,
					has_voted: this.current_has_voted || undefined,
					cash_status: this.current_cash_status || undefined,
					no_anggota: this.searchNoAnggota || undefined,
					no_kp: this.searchNoKp || undefined
				}
			})
				.then(response => {
					console.log(response)
					$.notifyClose();
					vm.data.voters = response.data;
				})
				.catch(error => {
					$.notifyClose();
					vm.util.showResult(error);
				})
				.finally(function () {
					vm.voterLoading = false;
				})
		},

		applySearch: function () {
			// Reset to first page when searching
			var q = Object.assign({}, this.$route.query);
			q.page = 1;
			this.$router.replace({ query: q });
			this.refreshVoter();
		},

		clearSearch: function () {
			this.searchNoAnggota = '';
			this.searchNoKp = '';
			this.applySearch();
		},

		setKehadiranFilter: function (val) {
			var q = Object.assign({}, this.$route.query);
			if (val === 1 || val === 2) q.kehadiran = String(val);
			else if (val === 'unset') q.kehadiran = 'unset';
			else delete q.kehadiran;
			q.page = 1;
			this.$router.replace({ query: q });
		},

		setFizikalRegFilter: function (val) {
			var q = Object.assign({}, this.$route.query);
			if (val === 'pending' || val === 'verified') q.fizikal_reg = val;
			else delete q.fizikal_reg;
			q.page = 1;
			this.$router.replace({ query: q });
		},

		setHasVotedFilter: function (val) {
			var q = Object.assign({}, this.$route.query);
			if (val === '1' || val === '0') q.has_voted = val;
			else delete q.has_voted;
			q.page = 1;
			this.$router.replace({ query: q });
		},

		setCashStatusFilter: function (val) {
			var q = Object.assign({}, this.$route.query);
			if (val === 'paid' || val === 'unpaid') q.cash_status = val;
			else delete q.cash_status;
			q.page = 1;
			this.$router.replace({ query: q });
		},

		paginationQueryForPage: function (pageNum) {
			var q = { page: pageNum };
			if (this.current_kehadiran) q.kehadiran = this.current_kehadiran;
			if (this.current_fizikal_reg) q.fizikal_reg = this.current_fizikal_reg;
			if (this.current_has_voted) q.has_voted = this.current_has_voted;
			if (this.current_cash_status) q.cash_status = this.current_cash_status;
			return q;
		},

		canVerifyFizikalRegistration: function (voter) {
			if (!voter) return false;
			return Number(voter.kehadiran) === 1 && !voter.fizikal_registration_verified_at;
		},

		openFizikalVerifyModal: function (item) {
			if (!item || !this.canVerifyFizikalRegistration(item)) return;
			this.verifyModalError = '';
			this.verifyModalVoter = Object.assign({}, item);
			this.util.showModal('#fizikal-verify-modal');
		},

		submitFizikalVerify: function () {
			var vm = this;
			if (!this.verifyModalVoter) return;
			this.verifyModalError = '';
			this.verifyModalLoading = true;
			axios.post(config.API + 'voter/' + this.verifyModalVoter.id + '/verify-fizikal-registration')
				.then(function (response) {
					if (response && response.data && response.data.status && response.data.status !== 'success') {
						vm.verifyModalError = response.data.message || 'Permintaan gagal.';
						vm.util.notify(vm.verifyModalError, 'error');
						return;
					}
					if (vm.util.showResult(response, 'success')) {
						var v = response.data.voter;
						if (v && vm.selectedVoter && vm.selectedVoter.id === v.id) {
							vm.selectedVoter.fizikal_registration_verified_at = v.fizikal_registration_verified_at;
						}
						vm.util.hideModal('#fizikal-verify-modal');
						vm.verifyModalVoter = null;
						vm.refreshVoter();
					}
				})
				.catch(function (error) {
					vm.verifyModalError =
						(error && error.response && error.response.data && error.response.data.message)
							? error.response.data.message
							: (error && error.message ? error.message : 'Gagal mengesahkan pendaftaran.');
					if (error && error.response) vm.util.showResult(error, 'error');
					else vm.util.notify(vm.verifyModalError, 'error');
				})
				.finally(function () {
					vm.verifyModalLoading = false;
				});
		},

		getKehadiranString(kehadiran) {
			// Map integer values to corresponding string representations
			switch (kehadiran) {
				case 1:
					return 'Fizikal';
				case 2:
					return 'Maya';
				default:
					return '-';
			}
		},

		getPDFKehadiranurl(Id) {
			// Construct and return the URL based on the item ID
			return `/kehadiranpdf/${Id}`;
		},

		isCashPaid: function (voter) {
			return Boolean(voter && voter.cash_paid_at);
		},

		canPayCash: function (voter) {
			if (!voter) return false;
			if (this.isCashPaid(voter)) return false;
			if (Number(voter.kehadiran) !== 1) return false;
			if (Number(voter.votes_count) > 0) return true;
			return this.canClaimAllowanceWithoutVoteAdmin(voter);
		},

		openDetail: function (item) {
			this.detailError = '';
			this.selectedVoter = Object.assign({}, item);
			this.claimCodeInput = '';
			this.payoutReference =
				item.cash_payout_reference != null && item.cash_payout_reference !== undefined
					? String(item.cash_payout_reference)
					: '';
			this.payoutNote =
				item.cash_payout_note != null && item.cash_payout_note !== undefined
					? String(item.cash_payout_note)
					: '';
			this.util.showModal('#allowance-modal');
		},

		/** Saham / Yuran — same RM formatting as voter portal. */
		formatRmDisplay: function (val) {
			if (val === null || val === undefined || val === '') {
				return '—';
			}
			var n = Number(val);
			if (Number.isNaN(n)) {
				return String(val);
			}
			return n.toLocaleString('en-MY', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
		},

		canClaimAllowanceWithoutVoteAdmin: function (voter) {
			if (!voter || Number(voter.kehadiran) !== 1) {
				return false;
			}
			if (Number(voter.votes_count) > 0) {
				return false;
			}
			var s = Number(voter.saham);
			var canVoteBySaham = !Number.isNaN(s) && s >= 500;
			var canProceed =
				Number(voter.kehadiran) !== 0 &&
				(Number(voter.kehadiran) !== 1 || voter.fizikal_registration_verified_at);
			return canProceed && !canVoteBySaham;
		},

		payCash: function () {
			if (!this.selectedVoter) return;
			this.detailError = '';
			this.detailLoading = true;

			let payload = {
				voter_id: this.selectedVoter.id,
				method: 'cash',
				claim_code: this.claimCodeInput || undefined,
				reference: this.payoutReference || undefined,
				note: this.payoutNote || undefined,
			};

			var rm = this.allowanceTunaiAmountRM;
			if (rm !== null && rm !== undefined && !Number.isNaN(Number(rm))) {
				payload.amount_cents = Math.round(Number(rm) * 100);
			}

			axios.post(config.API + 'allowance/payout', payload)
				.then((response) => {
					// Some endpoints return 200 with {status:'failed', message:'...'}
					if (response && response.data && response.data.status && response.data.status !== 'success') {
						this.detailError = response.data.message || 'Permintaan gagal.';
						this.util.notify(this.detailError, 'error');
						return;
					}

					if (this.util.showResult(response, 'success')) {
						// refresh list so cash_paid_at & cash_payout_id updates
						this.refreshVoter();
						// keep modal open but reflect paid state (best effort)
						if (response && response.data && response.data.payout) {
							var p = response.data.payout;
							this.selectedVoter.cash_paid_at = p.paid_at;
							this.selectedVoter.cash_payout_id = p.id;
							this.selectedVoter.cash_paid_by_admin_name =
								(response && response.data && response.data.paid_by_admin_name)
									? response.data.paid_by_admin_name
									: this.selectedVoter.cash_paid_by_admin_name;
							this.selectedVoter.cash_paid_by_admin_email =
								(response && response.data && response.data.paid_by_admin_email)
									? response.data.paid_by_admin_email
									: this.selectedVoter.cash_paid_by_admin_email;
							if (p.reference != null) {
								this.selectedVoter.cash_payout_reference = p.reference;
								this.payoutReference = p.reference ? String(p.reference) : '';
							}
							if (p.note != null) {
								this.selectedVoter.cash_payout_note = p.note;
								this.payoutNote = p.note ? String(p.note) : '';
							}
						} else {
							this.selectedVoter.cash_paid_at = (new Date()).toISOString();
						}
					}
				})
				.catch((error) => {
					this.detailError =
						(error && error.response && error.response.data && error.response.data.message)
							? error.response.data.message
							: (error && error.message ? error.message : 'Gagal merekod bayaran.');
					// Only pass actual axios error objects into showResult
					if (error && error.response) this.util.showResult(error, 'error');
					else this.util.notify(this.detailError, 'error');
				})
				.finally(() => {
					this.detailLoading = false;
				});
		},

		voidCashPayout: function () {
			if (!this.selectedVoter || !this.selectedVoter.cash_payout_id) {
				this.detailError = 'Rekod bayaran tidak dijumpai untuk dibatalkan.';
				return;
			}
			this.detailError = '';
			this.detailLoading = true;

			axios.post(config.API + 'allowance/void/' + this.selectedVoter.cash_payout_id, {
				note: this.payoutNote || undefined
			})
				.then((response) => {
					if (response && response.data && response.data.status && response.data.status !== 'success') {
						this.detailError = response.data.message || 'Permintaan gagal.';
						this.util.notify(this.detailError, 'error');
						return;
					}

					if (this.util.showResult(response, 'success')) {
						this.refreshVoter();
						this.selectedVoter.cash_paid_at = null;
						this.selectedVoter.cash_payout_id = null;
						this.selectedVoter.cash_payout_reference = null;
						this.selectedVoter.cash_payout_note = null;
						this.payoutReference = '';
						this.payoutNote = '';
					}
				})
				.catch((error) => {
					this.detailError =
						(error && error.response && error.response.data && error.response.data.message)
							? error.response.data.message
							: (error && error.message ? error.message : 'Gagal membatalkan bayaran.');
					if (error && error.response) this.util.showResult(error, 'error');
					else this.util.notify(this.detailError, 'error');
				})
				.finally(() => {
					this.detailLoading = false;
				});
		}


	},

	watch: {
		'$route.query.page': function () {
			$.notifyClose();
			this.refreshVoter();
		},
		'$route.query.kehadiran': function () {
			$.notifyClose();
			this.refreshVoter();
		},
		'$route.query.fizikal_reg': function () {
			$.notifyClose();
			this.refreshVoter();
		},
		'$route.query.has_voted': function () {
			$.notifyClose();
			this.refreshVoter();
		},
		'$route.query.cash_status': function () {
			$.notifyClose();
			this.refreshVoter();
		}
	},

	computed: {
		/** RM300 fizikal, RM150 Maya — used for tunai payout amount. */
		allowanceTunaiAmountRM: function () {
			if (!this.selectedVoter) return null;
			var k = Number(this.selectedVoter.kehadiran);
			if (k === 1) return 300;
			if (k === 2) return 150;
			return null;
		},

		allowanceTunaiDisplay: function () {
			var rm = this.allowanceTunaiAmountRM;
			if (rm === null || rm === undefined) return '';
			return Number(rm).toFixed(2);
		},

		hasAnySearch: function () {
			return Boolean((this.searchNoAnggota && this.searchNoAnggota.length) || (this.searchNoKp && this.searchNoKp.length));
		},

		voterListItems: function () {
			var v = this.data.voters;
			if (v && Array.isArray(v.data)) {
				return v.data;
			}
			return [];
		},

		pages: function () {
			var pages = [];
			if (this.data.voters.last_page)
				for (var i = 1; i <= this.data.voters.last_page; i++) {
					let x = {};
					x['page'] = i;
					pages.push(x);
				}
			return pages;
		},

		current_page: function () {
			return this.$route.query.page ? this.$route.query.page : 1;
		},

		current_kehadiran: function () {
			return this.$route.query.kehadiran ? this.$route.query.kehadiran : null;
		},

		current_fizikal_reg: function () {
			return this.$route.query.fizikal_reg ? this.$route.query.fizikal_reg : null;
		},

		current_has_voted: function () {
			var v = this.$route.query.has_voted;
			if (v === '1' || v === '0') {
				return v;
			}
			return null;
		},

		current_cash_status: function () {
			var v = this.$route.query.cash_status;
			if (v === 'paid' || v === 'unpaid') {
				return v;
			}
			return null;
		},

		verifyModalVoterNeedsLowSahamNote: function () {
			if (!this.verifyModalVoter) return false;
			var v = this.verifyModalVoter;
			if (Number(v.kehadiran) !== 1) return false;
			var s = Number(v.saham);
			return !Number.isNaN(s) && s < 500;
		},

		selectedVoterShowsNoVoteEligibleNote: function () {
			if (!this.selectedVoter) return false;
			return this.canClaimAllowanceWithoutVoteAdmin(this.selectedVoter);
		},

		// Calculate total attendance percentage
		attendancePercentage() {
			// Count total members who attended physically (Fizikal)
			const fizikalCount = this.voterListItems.reduce((total, voter) => {
				return Number(voter && voter.kehadiran) === 1 ? total + 1 : total;
			}, 0);

			// Count total members who attended virtually (Maya)
			const mayaCount = this.voterListItems.reduce((total, voter) => {
				return Number(voter && voter.kehadiran) === 2 ? total + 1 : total;
			}, 0);

			// Calculate total attendance percentage
			const totalAttendance = fizikalCount + mayaCount;
			const totalMembers = this.voterListItems.length;
			return totalMembers === 0 ? 0 : ((totalAttendance / totalMembers) * 100).toFixed(2);
		},

		attendanceStats: function () {
			var items = this.voterListItems || [];
			var fizikalCount = items.reduce(function (total, voter) {
				return Number(voter && voter.kehadiran) === 1 ? total + 1 : total;
			}, 0);
			var mayaCount = items.reduce(function (total, voter) {
				return Number(voter && voter.kehadiran) === 2 ? total + 1 : total;
			}, 0);

			var totalAttendance = fizikalCount + mayaCount;
			var totalMembers = items.length;
			var denom = totalMembers === 0 ? 1 : totalMembers;

			return {
				fizikalCount: fizikalCount,
				mayaCount: mayaCount,
				totalAttendance: totalAttendance,
				fizikalPct: totalMembers === 0 ? '0.00' : ((fizikalCount / denom) * 100).toFixed(2),
				mayaPct: totalMembers === 0 ? '0.00' : ((mayaCount / denom) * 100).toFixed(2),
				totalPct: totalMembers === 0 ? '0.00' : ((totalAttendance / denom) * 100).toFixed(2),
			};
		},


	}

}
</script>