<?= $this->extend('layouts/main.php') ?>

<?= $this->section('content') ?>
<div class="page-wrapper">
	<div class="container-fluid">
		<div class="row page-titles">
			<div class="col-md-6 align-self-center">
				<h4 class="text-themecolor">Gitea Dashboard (DB)</h4>
			</div>
			<div class="col-md-6 text-end">
				<?php if (!empty($isAdmin)): ?>
					<button id="btnSync" class="btn btn-primary">Sync Now</button>
				<?php endif; ?>
			</div>
		</div>

		<div class="row g-3 mb-3">
			<div class="col-md-3">
				<label class="form-label">User</label>
				<select id="filterUser" class="form-select"><option value="">All User</option></select>
			</div>
			<div class="col-md-3">
				<label class="form-label">Repository</label>
				<select id="filterRepo" class="form-select"><option value="">All Repository</option></select>
			</div>
			<div class="col-md-2">
				<label class="form-label">Start Date</label>
				<input type="date" id="filterStart" class="form-control">
			</div>
			<div class="col-md-2">
				<label class="form-label">End Date</label>
				<input type="date" id="filterEnd" class="form-control">
			</div>
			<div class="col-md-2 d-flex align-items-end">
				<button id="btnApplyFilter" class="btn btn-success w-100">Apply</button>
			</div>
		</div>

		<div class="row">
			<div class="col-12 mb-3">
				<div class="card">
					<div class="card-body">
						<div class="d-flex justify-content-between align-items-center mb-2">
							<h5 class="mb-0">Latest Commits</h5>
							<div><strong>Total Commits:</strong> <span id="totalCommits">0</span></div>
						</div>
						<div class="table-responsive">
							<table class="table table-sm table-bordered" id="tableCommits">
								<thead>
									<tr>
										<th>Date</th>
										<th>Repository</th>
										<th>User</th>
										<th>SHA</th>
										<th>Message</th>
									</tr>
								</thead>
								<tbody></tbody>
							</table>
						</div>
						<div class="d-flex justify-content-between align-items-center mt-2">
							<button id="commitPrev" class="btn btn-outline-secondary btn-sm">Prev</button>
							<div id="commitPageInfo" class="small text-muted">Page 0 of 0</div>
							<button id="commitNext" class="btn btn-outline-secondary btn-sm">Next</button>
						</div>
					</div>
				</div>
			</div>

			<div class="col-12">
				<div class="card">
					<div class="card-body">
						<div class="d-flex justify-content-between align-items-center mb-2">
							<h5 class="mb-0">Latest Pull Requests</h5>
							<div><strong>Total Pull Requests:</strong> <span id="totalPullRequests">0</span></div>
						</div>
						<div class="table-responsive">
							<table class="table table-sm table-bordered" id="tablePrs">
								<thead>
									<tr>
										<th>Updated</th>
										<th>Repository</th>
										<th>User</th>
										<th>PR</th>
										<th>State</th>
									</tr>
								</thead>
								<tbody></tbody>
							</table>
						</div>
						<div class="d-flex justify-content-between align-items-center mt-2">
							<button id="prPrev" class="btn btn-outline-secondary btn-sm">Prev</button>
							<div id="prPageInfo" class="small text-muted">Page 0 of 0</div>
							<button id="prNext" class="btn btn-outline-secondary btn-sm">Next</button>
						</div>
					</div>
				</div>
			</div>
		</div>
	</div>
</div>
<?= $this->endSection() ?>

<?= $this->section('script') ?>
<script>
document.addEventListener('DOMContentLoaded', async () => {
	const totalCommits = document.getElementById('totalCommits');
	const totalPullRequests = document.getElementById('totalPullRequests');

	const filterRepo = document.getElementById('filterRepo');
	const filterUser = document.getElementById('filterUser');
	const filterStart = document.getElementById('filterStart');
	const filterEnd = document.getElementById('filterEnd');
	const btnApplyFilter = document.getElementById('btnApplyFilter');
	const btnSync = document.getElementById('btnSync');

	const commitPrev = document.getElementById('commitPrev');
	const commitNext = document.getElementById('commitNext');
	const commitPageInfo = document.getElementById('commitPageInfo');

	const prPrev = document.getElementById('prPrev');
	const prNext = document.getElementById('prNext');
	const prPageInfo = document.getElementById('prPageInfo');

	const commitsState = {
		page: 1,
		perPage: 25,
		total: 0,
		totalPages: 0,
		loaded: false,
	};

	const prsState = {
		page: 1,
		perPage: 25,
		total: 0,
		totalPages: 0,
		loaded: false,
	};

	setDefaultDateRange();
	setInitialPlaceholders();
	await loadUsers();
	await loadRepos();
	updatePager(commitPrev, commitNext, commitPageInfo, commitsState);
	updatePager(prPrev, prNext, prPageInfo, prsState);

	btnApplyFilter.addEventListener('click', async () => {
		commitsState.page = 1;
		prsState.page = 1;
		commitsState.loaded = true;
		prsState.loaded = true;
		await loadTables();
	});

	commitPrev.addEventListener('click', async () => {
		if (commitsState.page > 1) {
			commitsState.page--;
			await loadCommits();
		}
	});

	commitNext.addEventListener('click', async () => {
		if (commitsState.page < commitsState.totalPages) {
			commitsState.page++;
			await loadCommits();
		}
	});

	prPrev.addEventListener('click', async () => {
		if (prsState.page > 1) {
			prsState.page--;
			await loadPullRequests();
		}
	});

	prNext.addEventListener('click', async () => {
		if (prsState.page < prsState.totalPages) {
			prsState.page++;
			await loadPullRequests();
		}
	});

	if (btnSync) {
		btnSync.addEventListener('click', async () => {
			btnSync.disabled = true;
			btnSync.innerText = 'Syncing...';

			try {
				const response = await fetch(`<?= base_url('api/git/sync') ?>`, {
					method: 'POST'
				});
				const result = await response.json();
				if (response.ok) {
					alert('Sync complete');
					if (commitsState.loaded || prsState.loaded) {
						await loadTables();
					}
				} else {
					alert(result.message || 'Sync failed');
				}
			} catch (error) {
				alert('Sync request failed');
			}

			btnSync.disabled = false;
			btnSync.innerText = 'Sync Now';
		});
	}

	function setDefaultDateRange() {
		const today = new Date();
		const startOfYear = new Date(today.getFullYear(), 0, 1);
		filterStart.value = toInputDate(startOfYear);
		filterEnd.value = toInputDate(today);
	}

	function toInputDate(date) {
		const year = date.getFullYear();
		const month = String(date.getMonth() + 1).padStart(2, '0');
		const day = String(date.getDate()).padStart(2, '0');
		return `${year}-${month}-${day}`;
	}

	function escapeHtml(value) {
		return String(value ?? '')
			.replace(/&/g, '&amp;')
			.replace(/</g, '&lt;')
			.replace(/>/g, '&gt;')
			.replace(/"/g, '&quot;')
			.replace(/'/g, '&#039;');
	}

	function setInitialPlaceholders() {
		document.querySelector('#tableCommits tbody').innerHTML = '<tr><td colspan="5">Submit filter to load data</td></tr>';
		document.querySelector('#tablePrs tbody').innerHTML = '<tr><td colspan="5">Submit filter to load data</td></tr>';
		totalCommits.innerText = '0';
		totalPullRequests.innerText = '0';
	}

	function updatePager(prevBtn, nextBtn, infoEl, state) {
		const totalPages = state.loaded ? state.totalPages : 0;
		const page = state.loaded && totalPages > 0 ? state.page : 0;

		prevBtn.disabled = !state.loaded || page <= 1;
		nextBtn.disabled = !state.loaded || page >= totalPages || totalPages <= 1;
		infoEl.innerText = `Page ${page} of ${totalPages}`;
	}

	function getBaseParams(page, perPage) {
		const params = new URLSearchParams();
		if (filterRepo.value) params.set('repo_id', filterRepo.value);
		if (filterUser.value) params.set('user_id', filterUser.value);
		if (filterStart.value) params.set('start_date', filterStart.value);
		if (filterEnd.value) params.set('end_date', filterEnd.value);
		params.set('page', String(page));
		params.set('per_page', String(perPage));
		return params.toString();
	}

	async function loadUsers() {
		const response = await fetch(`<?= base_url('api/git/users') ?>`);
		const result = await response.json();
		if (!response.ok || !Array.isArray(result.data)) {
			return;
		}

		result.data.forEach(item => {
			const option = document.createElement('option');
			option.value = item.id;
			option.textContent = item.username;
			filterUser.appendChild(option);
		});
	}

	async function loadRepos() {
		const response = await fetch(`<?= base_url('api/git/repositories') ?>`);
		const result = await response.json();
		if (!response.ok || !Array.isArray(result.data)) {
			return;
		}

		result.data.forEach(item => {
			const option = document.createElement('option');
			option.value = item.id;
			option.textContent = item.full_name;
			filterRepo.appendChild(option);
		});
	}

	async function loadTables() {
		await loadCommits();
		await loadPullRequests();
	}

	async function loadCommits() {
		const tbody = document.querySelector('#tableCommits tbody');
		tbody.innerHTML = '<tr><td colspan="5">Loading...</td></tr>';

		const response = await fetch(`<?= base_url('api/git/commits') ?>?${getBaseParams(commitsState.page, commitsState.perPage)}`);
		const result = await response.json();
		if (!response.ok || !Array.isArray(result.data)) {
			commitsState.total = 0;
			commitsState.totalPages = 0;
			totalCommits.innerText = '0';
			tbody.innerHTML = '<tr><td colspan="5">Failed loading commits</td></tr>';
			updatePager(commitPrev, commitNext, commitPageInfo, commitsState);
			return;
		}

		commitsState.total = Number(result.meta?.total ?? result.data.length ?? 0);
		commitsState.totalPages = Number(result.meta?.total_pages ?? 0);
		commitsState.page = Number(result.meta?.page ?? commitsState.page);
		commitsState.perPage = Number(result.meta?.per_page ?? commitsState.perPage);
		commitsState.loaded = true;
		totalCommits.innerText = String(commitsState.total);

		if (commitsState.totalPages > 0 && commitsState.page > commitsState.totalPages) {
			commitsState.page = commitsState.totalPages;
			await loadCommits();
			return;
		}

		if (!result.data.length) {
			tbody.innerHTML = '<tr><td colspan="5">No commits found</td></tr>';
			updatePager(commitPrev, commitNext, commitPageInfo, commitsState);
			return;
		}

		tbody.innerHTML = result.data.map(item => {
			const msg = escapeHtml((item.message || '').slice(0, 120));
			const sha = escapeHtml(item.short_sha || '');
			const link = item.html_url ? `<a href="${escapeHtml(item.html_url)}" target="_blank">${sha}</a>` : sha;
			return `<tr>
				<td>${escapeHtml(item.committed_at || '')}</td>
				<td>${escapeHtml(item.repository_full_name || '')}</td>
				<td>${escapeHtml(item.user_username || item.author_name || '')}</td>
				<td>${link}</td>
				<td>${msg}</td>
			</tr>`;
		}).join('');

		updatePager(commitPrev, commitNext, commitPageInfo, commitsState);
	}

	async function loadPullRequests() {
		const tbody = document.querySelector('#tablePrs tbody');
		tbody.innerHTML = '<tr><td colspan="5">Loading...</td></tr>';

		const response = await fetch(`<?= base_url('api/git/pull-requests') ?>?${getBaseParams(prsState.page, prsState.perPage)}`);
		const result = await response.json();
		if (!response.ok || !Array.isArray(result.data)) {
			prsState.total = 0;
			prsState.totalPages = 0;
			totalPullRequests.innerText = '0';
			tbody.innerHTML = '<tr><td colspan="5">Failed loading pull requests</td></tr>';
			updatePager(prPrev, prNext, prPageInfo, prsState);
			return;
		}

		prsState.total = Number(result.meta?.total ?? result.data.length ?? 0);
		prsState.totalPages = Number(result.meta?.total_pages ?? 0);
		prsState.page = Number(result.meta?.page ?? prsState.page);
		prsState.perPage = Number(result.meta?.per_page ?? prsState.perPage);
		prsState.loaded = true;
		totalPullRequests.innerText = String(prsState.total);

		if (prsState.totalPages > 0 && prsState.page > prsState.totalPages) {
			prsState.page = prsState.totalPages;
			await loadPullRequests();
			return;
		}

		if (!result.data.length) {
			tbody.innerHTML = '<tr><td colspan="5">No pull requests found</td></tr>';
			updatePager(prPrev, prNext, prPageInfo, prsState);
			return;
		}

		tbody.innerHTML = result.data.map(item => {
			const title = escapeHtml((item.title || '').slice(0, 100));
			const prText = `#${escapeHtml(item.number || '')} ${title}`;
			const link = item.html_url ? `<a href="${escapeHtml(item.html_url)}" target="_blank">${prText}</a>` : prText;
			return `<tr>
				<td>${escapeHtml(item.updated_at_gitea || '')}</td>
				<td>${escapeHtml(item.repository_full_name || '')}</td>
				<td>${escapeHtml(item.user_username || '')}</td>
				<td>${link}</td>
				<td>${escapeHtml(item.state || '')}</td>
			</tr>`;
		}).join('');

		updatePager(prPrev, prNext, prPageInfo, prsState);
	}
});
</script>
<?= $this->endSection() ?>
