<script lang="ts">
	import { ApiPisObject, ApiTrainsTrainDetails } from '@owlboard/api-schema-types';
	import { formatTrainStatusMessage } from '$lib/utils/delayCancelMsg';
	import { formatUkTime, estClass, calculateDelay } from '$lib/utils/time';

	interface props {
		trainDetail: ApiTrainsTrainDetails.TrainDetailsResponse;
	}

	let { trainDetail }: props = $props();

	let pisData = $derived(
		trainDetail.pis ? (trainDetail.pis as unknown as ApiPisObject.PisObjects) : undefined
	);

	const activityMap: Record<string, string> = {
		'-D': 'Vehicles detatched',
		'-T': 'Vehicles attached & detached',
		'-U': 'Vehicles attached',
		AE: 'Assist locomotive attached',
		C: 'Traincrew change only',
		D: 'Set down only',
		E: 'Stops for examination',
		K: 'Passenger count point',
		KC: 'Ticket collection point',
		KE: 'Ticket examination point',
		KF: 'First class ticket examination point',
		KS: 'Selective ticket examination point',
		L: 'Locomotive changed',
		N: 'Unadvertised stop',
		OP: 'Operational stop only',
		OR: 'Locomotive attached on rear',
		R: 'Request stop',
		RM: 'Train changes direction',
		RR: 'Locomotive run round',
		S: 'Staff only stop',
		TW: 'Stops for token/staff/tablet',
		U: 'Pick up only',
		W: 'Watering coaches',
		X: 'Passes another train'
	};

	const activityRegex = new RegExp(
		Object.keys(activityMap)
			.sort((a, b) => b.length - a.length) // Longest codes first
			.map((key) => key.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&')) // Escape special chars
			.join('|'),
		'g'
	);

	const getRelevantActivities = (act: string) => {
		if (!act) return [];

		// Find all matches in the string
		const matches = act.match(activityRegex) || [];

		// Map to labels and remove duplicates
		return [...new Set(matches)].map((code) => activityMap[code]);
	};
</script>

<div class="trainServiceContainer">
	{#if trainDetail.header.cr}
		<span class="cancelReason"
			>{formatTrainStatusMessage(
				trainDetail.header.cr,
				trainDetail.header.cl,
				trainDetail.header.cn
			)}</span
		>
	{/if}
	{#if trainDetail.header.dr}
		<span class="delayReason"
			>{formatTrainStatusMessage(
				trainDetail.header.dr,
				trainDetail.header.dl,
				trainDetail.header.dn
			)}</span
		>
	{/if}
	{#if pisData}
		<div class="pisData">
			<span class="pisCode">PIS: {pisData.code}</span>
			{#if pisData.skip?.skip}
				<span class="pis-skip">
					(skip {pisData.skip.position === 'head' ? 'first' : 'last'}
					{pisData.skip.skip}
					{pisData.skip.skip === 1 ? 'stop' : 'stops'}
					)
				</span>
			{/if}
		</div>
	{/if}

	<div class="tableContainer">
		<table class="table">
			<thead>
				<tr>
					<th colspan="2"></th>
					<th colspan="2">Arr</th>
					<th colspan="2">Dep</th>
				</tr>
				<tr>
					<th class="tiploc-col">Location</th>
					<th>Plat</th>
					<th>Sch</th>
					<th>Act</th>
					<th>Sch</th>
					<th>Act</th>
					<th></th>
				</tr>
			</thead>
			{#each trainDetail.locations as loc}
				<tbody class="LocGroup">
					<tr class:pass={loc.r === 'PASS'} class:canc={loc.can}>
						<td class="tiploc-col tpl" class:stop={loc.r !== 'PASS'}>
							{loc.t}
						</td>
						<td class="plat" class:platchange={loc.pc}>
							{loc.p}
						</td>
						{#if loc.r === 'PASS'}
							<td colspan="2">Pass</td>
							<td class="actual">{formatUkTime(loc.wtp)}</td>
							<td class={estClass(loc.atp, loc.etp)}>{formatUkTime(loc.atp || loc.etp || '--')}</td>
						{:else}
							<td class="actual">{formatUkTime(loc.pta || loc.wta)}</td>
							<td class={estClass(loc.ata, loc.eta)}>{formatUkTime(loc.ata || loc.eta || '--')}</td>
							<td class="actual">{formatUkTime(loc.ptd || loc.wtd)}</td>
							<td class={estClass(loc.atd, loc.etd)}>{formatUkTime(loc.atd || loc.etd || '--')}</td>
						{/if}
						{#if loc}
							{@const delay = calculateDelay(loc)}
							{@const arrType = estClass(loc.ata, loc.eta)}
							{@const depType = estClass(loc.atd, loc.etd)}
							{@const passType = estClass(loc.atp, loc.etp)}
							{@const classType = depType || arrType || passType}
							<td class="delay-{delay.type} {classType}">{delay.val}</td>
						{/if}
					</tr>
					{#if loc.act && getRelevantActivities(loc.act).length > 0}
						<tr class="activity-row">
							<td colspan="7">
								<div class="activity-container">
									{#each getRelevantActivities(loc.act) as note}
										<span class="activity-tag">{note}</span>
									{/each}
								</div>
							</td>
						</tr>
					{/if}
				</tbody>
			{/each}
		</table>
	</div>
</div>

<style>
	.trainServiceContainer {
		width: 100%;
		margin: 0 auto;
		display: flex;
		justify-items: center;
		flex-direction: column;
	}

	.cancelReason {
		color: var(--cancel-red);
		text-align: center;
	}
	.delayReason {
		color: var(--delay-orange);
		text-align: center;
	}
	.pisData {
		margin: auto;
		text-align: center;
		font-family: 'URW Gothic', sans-serif;
		font-weight: 600;
		font-size: 1.25rem;
	}
	.pis-skip {
		font-weight: 200;
		font-size: 1rem;
	}

	.tableContainer {
		width: 100%;
		margin: 0 auto;
		padding-top: 10px;
	}

	.table {
		width: 97%;
		margin: 0 auto;
	}

	tr th {
		font-family: 'URW Gothic', sans-serif;
		text-align: center;
	}

	tr td {
		font-family: 'Inconsolata Variable', monospace;
		font-size: 1.171rem;
		font-variant-ligatures: additional-ligatures;
		text-align: center;
	}

	tr.pass td {
		opacity: 0.5;
	}

	tr.canc {
		text-decoration: line-through;
		color: var(--cancel-red);
	}

	tr.canc .tpl {
		text-decoration: none;
		color: var(--cancel-red);
	}

	.tiploc-col {
		text-align: left;
	}

	.tpl {
		color: var(--location-yellow);
	}

	tr.pass td.pass-text {
		font-style: italic;
	}

	tr td.estimate {
		color: rgb(196, 189, 189);
		font-style: italic;
		font-weight: 350;
	}

	tr td.actual {
		font-weight: 700;
	}

	tr td.delay-late {
		color: var(--delay-orange);
	}

	tr td.delay-early {
		color: var(--early-blue);
	}

	.activity-container {
		display: flex;
		flex-wrap: wrap;
		gap: 0.35rem;
		padding-bottom: 5px;
	}

	.activity-tag {
		background: rgb(0 0 0 / 15%);
		font-family: 'URW Gothic', sans-serif;
		padding: 0.2rem 0.5rem;
		border-radius: 0.25rem;
		font-size: 1rem;
	}
</style>