<script lang="ts">
    import type { PageProps } from "./$types";

	import { untrack } from "svelte";
	import { enhance } from "$app/forms";
	import { page } from "$app/state"

	import type { RecordEntry } from "$lib/db_types"
    import { MONTHS, toInt, padInt, parseDate, calculateDuration, weekday_of } from "$lib/util";

	import type { RowState } from "./record_input_row.svelte"
	import RecordInputRow from "./record_input_row.svelte"
	

	let { data, form } : PageProps = $props();

	//$inspect(data);

	const HEADERS: string[] = [ "Datum", "Wochentag", "Beginn", "Ende", "Dauer", "Anmerkung" ];

	const status_ok			= "ok";
	const status_missing	= "missing";
	const status_invalid	= "invalid";

	let new_state = $state() as RowState;

	let editing: RecordEntry | null = $state(null);
	let edit_state = $state() as RowState;

	setNewState();
	setEditing();

	$effect(() => {
		if (form) {
			untrack(() => setNewState());
		}
	})
	$effect(() => {
		if (form) {
			untrack(() => setEditing(null));
		}
	})

	function setNewState() {
		new_state = {
			date: {
				valid: form?.new_entry?.date?.value !== "" || form?.new_entry?.date?.valid,
				value: form?.new_entry?.date?.value ?? "",
			},
			start: {
				valid: form?.new_entry?.start?.value !== "" || form?.new_entry?.start?.valid,
				value: form?.new_entry?.start?.value ?? "",
			},
			end: {
				valid: form?.new_entry?.end?.value !== "" || form?.new_entry?.end?.valid,
				value: form?.new_entry?.end?.value ?? "",
			},
			comment: {
				value: form?.new_entry?.date?.comment ?? "",
			},
		}
	}

	function setEditing(entry: RecordEntry | null = null) {
		if (entry) {
			editing = entry;
		} else if (form?.edit_entry) {
			editing = form.edit_entry
		} else if (page.url.searchParams.get("edit")) {
			let id = toInt(page.url.searchParams.get("edit")!)
			let entry = Array.from(data.records.values().map((months) => Array.from(months.values()))).flat(2).find((entry) => entry.id == id);
			editing = entry ?? null;
		} else {
			editing = null;
		}
		
		edit_state = {
			date: {
				valid: editing?.id != form?.edit_entry?.id || !(form?.edit_entry?.date?.status && form.edit_entry.date.status != status_ok),
				value: editing?.date ?? ""
			},
			start: {
				valid: editing?.id != form?.edit_entry?.id || !(form?.edit_entry?.start?.status && form.edit_entry.start.status != status_ok),
				value: editing?.start ?? ""
			},
			end: {
				valid: editing?.id != form?.edit_entry?.id || !(form?.edit_entry?.end?.status && form.edit_entry.end.status != status_ok),
				value: editing?.end ?? ""
			},
			comment: {
				value: editing?.comment ?? ""
			},
		}
	}

	function validateForm(event: Event, state: RowState): boolean {
		let valid = state.date.valid  && state.date.value.length !== 0
			&& state.start.valid && state.start.value.length !== 0
			&& state.end.valid && state.end.value.length !== 0;
		
		if (!valid) {
			event.preventDefault();
		}
		return valid;
	}

</script>

<form id="form_new_entry" method="POST" action="?/new_entry" onsubmit={(e) => validateForm(e, new_state)} use:enhance></form>
<form id="form_edit_entry" method="POST" action="?/edit_entry" onsubmit={(e) => validateForm(e, edit_state)} use:enhance></form>
<form id="form_remove_entry" method="POST" action="?/remove_entry" use:enhance></form>

<h1>Stundenliste</h1>

<table>
	<colgroup>
		<col style:width="5ex" class="cyear" />
		<col style:width="5ex" class="cmonth" />
		<col style:width="12ch" class="cdate" />
		<col style:width="12ch" class="cweekday" />
		<col style:width="7ch" class="cstart" />
		<col style:width="7ch" class="cend" />
		<col style:width="7ch" class="cduration" />
		<col                    class="ccomment" />
		<col style:width="12ch" class="caction" />
		<col style:width="fit-content" class="month_stat" />
	</colgroup>
	<thead>
		<tr>
			<th></th>
			<th></th>
			<th>Datum</th>
			<th>Wochentag</th>
			<th>Beginn</th>
			<th>Ende</th>
			<th>Dauer</th>
			<th>Anmerkung</th>
			<th>Actions</th>
			<th></th>
		</tr>
	</thead>
	<tbody>
		<tr style:border="none">
			<td style:border="none"></td>
			<td style:border="none"></td>
			<RecordInputRow targetForm="form_new_entry" bind:states={new_state} enabled={editing == null}>	
				<button
					type="submit"
					form="form_new_entry"
					disabled={editing != null}>
					+
				</button>
			</RecordInputRow>
		</tr>

{#each data.estimates as estimates_pair}
	{@const year = estimates_pair[0] }
	{@const mmonths = estimates_pair[1] }
	{@const yentries = data.records.get(year)}
	
	{#each mmonths as month_pair, mindex}
		{@const month = month_pair[0] }
		{@const estimate = month_pair[1] }
		{@const entries = yentries.get(month) ?? [ null ] }

		{#each entries as entry, eindex}
			{@const record_sum = entries.reduce((acc, val) => acc + (val != null ? calculateDuration(val.start, val.end) : 0), 0)}
			<!--<tr><td>{$inspect(year)}{$inspect(months)}{$inspect(month)}{$inspect(entries)}</td></tr>-->
			<tr style:border-bottom={entries[0] == null ? "none" : ""} >
				{#if mindex == 0 && eindex == 0}
					<td class="year" rowspan={Array.from(yentries.values()).reduce((acc, val) => acc + ((val?.length ?? 0) < 4 ? 4 : val.length), 0) + 4 * (mmonths.size - yentries.size)}>{year}</td>
				{/if}
				{#if eindex == 0}
					<td class={["month", month % 3 == 2 ? "quarter" : ""]} rowspan={entries.length < 4 ? 4 : entries.length }>{MONTHS[month]}</td>
				{/if}
				{#if entry == null}
					<td style:text-align="center" colspan="7"></td>	
				{:else if editing?.id != entry.id }
					<td>{entry.date}</td>
					<td>{weekday_of(parseDate(entry.date))}</td>
					<td class="start">{entry.start}</td>
					<td class="end">{entry.end}</td>
					<td class="duration">{padInt(calculateDuration(entry.start, entry.end), 2, 2, '\u2007;')}</td>
					<td>{entry.comment ?? ""}</td>
					<td class="action">
						<form 
							id="form_edit" 
							method="GET" 
							onsubmit={(event) => {
								event.preventDefault();
								setEditing(entry);
							}}
						>
							<button type="submit" name="edit" value={entry.id}>Edit</button>
						</form>
					</td>
				{:else}
					<RecordInputRow targetForm="form_edit_entry" bind:states={edit_state} enabled={true} >
						<input type="hidden" form="form_edit_entry" name="id" value={entry.id} />
						<button
							type="submit"
							form="form_edit_entry">
							Save
						</button>
						<form
							id="form_edit_cancel"
							method="GET"
							onsubmit={(event) => {
								event.preventDefault();
								setEditing(null);
							}}
						>	
								<button type="submit">Cancel</button>
						</form>
						<input type="hidden" form="form_remove_entry" name="id" value={entry.id} />
						<button
							type="submit"
							form="form_remove_entry">
							Delete
						</button>
					</RecordInputRow>
				{/if}
				{#if eindex == 0}
					{@const document = data?.documents?.get(year)?.get(month)}

					<td rowspan={entries.length < 4 ? 4 : entries.length} class="stats">
						<table>
							<colgroup>
								<col style:width="10ch" class="col_labels" />
								<col style:width="7ch" class="col_values" />
							</colgroup>
							<tbody>
								<tr>
									<td>Ist</td>
									<td>{padInt(record_sum, 1, 2, "0", false, false)}</td>
								</tr>
								<tr>
									<td>Soll</td>
									<td>{padInt(estimate, 1, 2, "0", false, false)}</td>
								</tr>
								<tr class="diff">
									<td>Differenz</td>
									<td>{padInt(record_sum - estimate, 3, 2, "\u2007", true, false)}</td>
								</tr>
								<tr>
									<td colspan="2" class="doc_action">
										{#if document == null}
											<form id="form_create_rec" method="POST" action="/dokumente?/create_record">
												<input type="hidden" name="month" value={month + 1} />
												<input type="hidden" name="year" value={year} />
												<button type="submit">Stundenliste erstellen</button>
											</form>
										{:else}
											<form id="form_download" method="GET" action={`/dokumente/${document.path}`}>
												<input type="hidden" name="month" value={month + 1} />
												<input type="hidden" name="year" value={year} />
												<button type="submit">Download</button>
											</form>
										{/if}
									</td>
								</tr>
							</tbody>
						</table>
					</td>
				{/if}
			</tr>
		{/each}
		{#if entries.length > 0 && entries.length < 4}
			{#each { length:  4 - entries.length }, i }
				<tr style="border: none;"><td><span style:visibility="hidden">#</span></td></tr>
			{/each}
		{/if}
		
	{/each} <!-- months -->

{/each} <!-- data.estimates -->
		<tr></tr>
	</tbody>
{#if data.records === undefined || data.records.length === 0}
	<tfoot>
		<tr>
			<td class="td-no-elements" colspan="999">No records</td>
		</tr>
	</tfoot>
{/if}
</table>



<style>

form {
	width: fit-content;
	border: none;
}

table {
	width: 80%;
	margin: auto;

	border-collapse: collapse;
}

tbody > :global(tr) {
	border-top: 1px solid black;
	border-bottom: 1px solid black;
}

tbody > :global(tr:has(> td.year):has(td.month)) {
	border-top: 3px double black;
}
tbody > :global(tr:has(> td.month)) {
	border-top: 1.5px solid black;
}

tbody .year {
	vertical-align: middle;
	writing-mode: sideways-lr;
	text-orientation: mixed;
}

tbody .month {
	vertical-align: middle;
	writing-mode: sideways-lr;
	text-orientation: mixed;
}

.start, .end, .duration {
	text-align: right;
}

tbody .action {
	display: inline-flex;
}

tbody .stats {
	min-height: fit-content;
	vertical-align: middle;
}

tbody .stats table tr {
	border: none;
}
tbody .stats table .diff {
	border-top:	1px solid black;
}
tbody .stats table tr td:first-of-type {
	text-align: right;
}
tbody .stats table tr td:last-of-type {
	text-align: right;
	white-space: nowrap;
}

.doc_action * {
	width: 100%;
}

tbody tr td {
	vertical-align: text-bottom;
	padding-left: 10px;
	padding-right: 10px;
}

tfoot > tr {
	border-top: 1px solid red;
}

.td-no-elements {
	text-align: center;
}

</style>
