<template>
	<div class="final-dashboard">
		<div class="container-fluid final-dashboard__container">
			<div class="row final-split-row">
				<div class="col-md-6 final-split-col final-split-col--dashboard">
					<div class="final-dashboard__shell">
						<div class="final-header">
							<div>
								<div class="final-kicker">Keputusan akhir</div>
								<h4 class="final-title">Dashboard keputusan</h4>
								<div class="final-subtitle">Carta interaktif mengikut jawatan</div>
							</div>
							<div class="final-actions">
								<button type="button" class="btn btn-info" :disabled="finalLoading" @click="loadData">
									<i class="fa" :class="finalLoading ? 'fa-refresh fa-spin' : 'fa-refresh'"></i>
									Kemaskini
								</button>
							</div>
						</div>

						<div class="final-vote-summary">
							<div class="final-section-title">Ringkasan undian</div>
							<div class="final-stats">
								<div class="final-stat">
									<div class="final-stat__label">Jumlah undi</div>
									<div class="final-stat__value">{{ dashboardTotalVotes }}</div>
								</div>
								<div class="final-stat">
									<div class="final-stat__label">Bil. jawatan</div>
									<div class="final-stat__value">{{ positions.length }}</div>
								</div>
								<div class="final-stat">
									<div class="final-stat__label">Calon terunggul</div>
									<div class="final-stat__value final-stat__value--text">{{ topOverallLabel }}</div>
									<div class="final-stat__hint">{{ topOverallVotes }} undi</div>
								</div>
							</div>
						</div>

						<div class="final-filters">
							<span class="final-filters__label">Jawatan:</span>
							<button type="button" class="final-chip" :class="{ 'is-active': selectedPositionId === 0 }" @click="setPosition(0)">
								Semua
							</button>
							<button
								v-for="position in positions"
								:key="position.id"
								type="button"
								class="final-chip"
								:class="{ 'is-active': selectedPositionId === position.id }"
								@click="setPosition(position.id)"
							>
								{{ position.name }}
							</button>
						</div>

						<div v-if="!finalLoading && positions.length === 0" class="final-empty">
							Tiada jawatan untuk pilihan raya ini.
						</div>

						<div v-else class="row final-charts-row final-charts-row--split">
							<div class="col-xs-12">
								<div class="panel panel-default final-card">
									<div class="panel-heading final-card__heading">
										<div class="final-card__title">{{ mainChartTitle }}</div>
										<div class="final-card__meta">{{ mainChartSubtitle }}</div>
									</div>
									<div class="panel-body final-card__body">
										<div class="final-chart-wrap">
											<bar-chart v-if="mainChartReady" v-bind="mainBarChartProps" />
										</div>
									</div>
								</div>
							</div>
							<div class="col-xs-12">
								<div class="panel panel-default final-card">
									<div class="panel-heading final-card__heading final-card__heading--alt">
										<div class="final-card__title">{{ sideChartTitle }}</div>
										<div class="final-card__meta">{{ sideChartSubtitle }}</div>
									</div>
									<div class="panel-body final-card__body">
										<div class="final-chart-wrap final-chart-wrap--doughnut">
											<pie-chart v-if="mainChartReady" v-bind="sidePieChartProps" />
										</div>
									</div>
								</div>
							</div>
						</div>
					</div>
				</div>
				<div class="col-md-6 final-split-col final-split-col--attendance">
					<div class="final-attendance-shell">
						<div class="final-attendance-shell__head">
							<div>
								<div class="final-attendance-shell__kicker">Kehadiran</div>
								<h4 class="final-attendance-shell__title">Ringkasan kehadiran</h4>
								<div v-if="attendanceSummary" class="final-attendance__meta">
									Kadar daftar: <b>{{ attendanceSummary.attendance_rate }}%</b>
									<span class="final-attendance__meta-sep">·</span>
									{{ attendanceSummary.marked_present }} / {{ attendanceSummary.total_registered }} pengundi
								</div>
							</div>
						</div>
						<div v-if="!attendanceSummaryReady" class="final-attendance__state">Memuatkan kehadiran…</div>
						<div v-else-if="attendanceSummary" class="final-attendance__body">
							<div
								v-if="attendanceSummary.total_registered > 0"
								class="final-attendance__charts final-attendance__charts--standalone"
							>
								<div class="final-attendance__chart-block">
									<div class="final-attendance__chart-caption">Taburan kaedah kehadiran</div>
									<div class="final-attendance__chart-wrap final-attendance__chart-wrap--donut">
										<pie-chart v-bind="attendanceBreakdownPieProps" />
									</div>
								</div>
								<div v-if="showAttendanceFizikalChart" class="final-attendance__chart-block">
									<div class="final-attendance__chart-caption">Status pendaftaran fizikal</div>
									<div class="final-attendance__chart-wrap final-attendance__chart-wrap--bar">
										<bar-chart v-bind="attendanceFizikalBarProps" />
									</div>
								</div>
							</div>
						</div>
						<div v-else class="final-attendance__state final-attendance__state--muted">
							Ringkasan kehadiran tidak dapat dimuatkan. Semak sambungan atau log masuk pentadbir.
						</div>
					</div>
				</div>
			</div>
		</div>
	</div>
</template>

<script>
import BarChart from '../../../common/BarChart.vue';
import PieChart from '../../../common/PieChart.vue';

export default {
	components: {
		BarChart,
		PieChart
	},

	data: function () {
		return {
			nominees: [],
			results: [],
			positions: [],
			finalLoading: false,
			selectedPositionId: 0,
			attendanceSummary: null,
			attendanceSummaryReady: false
		};
	},

	computed: {
		election_id: function () {
			return this.$route.params.election_id;
		},

		no_votes: function () {
			var nominees = this.nominees;
			var results = this.results;
			var no_votes = [];
			for (var i in nominees) {
				var hasvote = false;
				for (var y in results) {
					if (results[y]['nominee_id'] == nominees[i]['id']) {
						hasvote = true;
					}
				}
				if (!hasvote) {
					no_votes.push(nominees[i]);
				}
			}
			return no_votes;
		},

		dashboardTotalVotes: function () {
			return this.results.reduce(function (s, r) {
				return s + Number(r.votes || 0);
			}, 0);
		},

		topOverallLabel: function () {
			if (!this.results.length) {
				return '—';
			}
			var best = this.results.reduce(function (a, b) {
				return Number(b.votes || 0) > Number(a.votes || 0) ? b : a;
			});
			var n = this.getNominee(best.nominee_id);
			return (n && n.name) ? n.name : '—';
		},

		topOverallVotes: function () {
			if (!this.results.length) {
				return 0;
			}
			return this.results.reduce(function (m, r) {
				return Math.max(m, Number(r.votes || 0));
			}, 0);
		},

		mainChartTitle: function () {
			if (this.selectedPositionId === 0) {
				return 'Jumlah undi mengikut jawatan';
			}
			var p = this.positions.find(function (x) {
				return Number(x.id) === Number(this.selectedPositionId);
			}, this);
			return (p && p.name) ? 'Undi calon — ' + p.name : 'Undi calon';
		},

		mainChartSubtitle: function () {
			return this.selectedPositionId === 0
				? 'Perbandingan antara jawatan'
				: 'Carta mengikut calon';
		},

		sideChartTitle: function () {
			return this.selectedPositionId === 0 ? 'Taburan undi (jawatan)' : 'Peratus undi';
		},

		sideChartSubtitle: function () {
			return this.selectedPositionId === 0 ? 'Perkongsian jumlah undi' : 'Bahagian setiap calon';
		},

		showAttendanceFizikalChart: function () {
			if (!this.attendanceSummary) {
				return false;
			}
			return Number(this.attendanceSummary.fizikal || 0) > 0;
		},

		mainChartReady: function () {
			return !this.finalLoading && this.positions.length > 0;
		},

		positionTotalRows: function () {
			var vm = this;
			return this.positions.map(function (pos) {
				var t = vm.results
					.filter(function (r) {
						return Number(r.position_id) === Number(pos.id);
					})
					.reduce(function (s, r) {
						return s + Number(r.votes || 0);
					}, 0);
				return { id: pos.id, name: pos.name, total: t };
			});
		},

		mainBarChartProps: function () {
			if (!this.mainChartReady) {
				return {};
			}
			if (this.selectedPositionId === 0) {
				var rows = this.positionTotalRows;
				return {
					labels: rows.map(function (r) {
						return r.name.length > 22 ? r.name.slice(0, 20) + '…' : r.name;
					}),
					values: rows.map(function (r) {
						return r.total;
					}),
					datasetLabel: 'Jumlah undi'
				};
			}
			var rows = this.getSinglePositionChartRows();
			return {
				labels: rows.map(function (r) {
					return r.label;
				}),
				values: rows.map(function (r) {
					return r.votes;
				}),
				datasetLabel: 'Undi'
			};
		},

		sidePieChartProps: function () {
			if (!this.mainChartReady) {
				return {};
			}
			if (this.selectedPositionId === 0) {
				var rows = this.positionTotalRows;
				return {
					labels: rows.map(function (r) {
						return r.name;
					}),
					values: rows.map(function (r) {
						return r.total;
					})
				};
			}
			var rows = this.getSinglePositionChartRows();
			return {
				labels: rows.map(function (r) {
					return r.label;
				}),
				values: rows.map(function (r) {
					return r.votes;
				})
			};
		},

		attendanceBreakdownPieProps: function () {
			if (!this.attendanceSummary || this.attendanceSummary.total_registered <= 0) {
				return { labels: [], values: [] };
			}
			var s = this.attendanceSummary;
			return {
				labels: ['Fizikal', 'Maya', 'Belum ditetapkan'],
				values: [
					Number(s.fizikal || 0),
					Number(s.maya || 0),
					Number(s.unset || 0)
				]
			};
		},

		attendanceFizikalBarProps: function () {
			if (!this.showAttendanceFizikalChart || !this.attendanceSummary) {
				return { labels: [], values: [] };
			}
			var s = this.attendanceSummary;
			return {
				labels: ['Menunggu pengesahan', 'Disahkan'],
				values: [
					Number(s.fizikal_registration_pending || 0),
					Number(s.fizikal_registration_verified || 0)
				],
				datasetLabel: 'Pengundi'
			};
		}
	},

	methods: {
		setPosition: function (id) {
			this.selectedPositionId = id === 0 ? 0 : Number(id);
		},

		getSinglePositionChartRows: function () {
			var pid = this.selectedPositionId;
			var vm = this;
			var rows = this.results
				.filter(function (r) {
					return Number(r.position_id) === Number(pid);
				})
				.map(function (r) {
					var n = vm.getNominee(r.nominee_id) || {};
					var label = n.name || ('#' + r.nominee_id);
					if (label.length > 28) {
						label = label.slice(0, 26) + '…';
					}
					return {
						label: label,
						votes: Number(r.votes || 0)
					};
				});
			this.no_votes.forEach(function (nv) {
				if (Number(nv.position_id) === Number(pid)) {
					var label = nv.name || '';
					if (label.length > 28) {
						label = label.slice(0, 26) + '…';
					}
					rows.push({
						label: label || 'Calon',
						votes: 0
					});
				}
			});
			rows.sort(function (a, b) {
				return b.votes - a.votes;
			});
			return rows;
		},

		loadData: function () {
			var vm = this;
			this.util.notify('Loading please wait...', 'loading');
			this.finalLoading = true;
			this.attendanceSummaryReady = false;
			this.attendanceSummary = null;

			axios
				.get(config.API + 'election/' + this.election_id + '/attendance-summary')
				.then(function (r) {
					vm.attendanceSummary = r.data;
				})
				.catch(function () {
					vm.attendanceSummary = null;
				})
				.finally(function () {
					vm.attendanceSummaryReady = true;
				});

			axios
				.get(config.API + 'election/result/' + this.election_id)
				.then(function (response) {
					$.notifyClose();
					vm.nominees = response.data.nominee || [];
					vm.results = response.data.result || [];
					vm.positions = response.data.position || [];
				})
				.catch(function (error) {
					$.notifyClose();
					vm.util.showResult(error, 'error');
				})
				.finally(function () {
					vm.finalLoading = false;
				});
		},

		getNominee: function (id) {
			var nominees = this.nominees;
			for (var i in nominees) {
				if (id == nominees[i]['id']) {
					return nominees[i];
				}
			}
			return {};
		}
	},

	created: function () {
		this.util.setTitle('MyKoPKB - Keputusan akhir');
		this.loadData();
	}
};
</script>

<style scoped src="./final.css"></style>
