import { JSX, onMount, VoidComponent } from 'solid-js';
import { timeline } from '@motionone/dom';

import { Line } from './types';

// Thanks to https://dev.to/ycmjason/how-to-create-range-in-javascript-539i
export function* range(start: number, end: number): Generator<number> {
	for (let i = start; i <= end; i++) {
		yield i;
	}
}

const validTransportModes = ["bus", "tram", "metro", "rer", "transilien", "funicular", "ter", "unknown"];

export const TransportModeWeights: Record<string, number> = {
	bus: 1,
	tram: 2,
	val: 3,
	funicular: 4,
	metro: 5,
	rer: 6,
	transilien: 7,
	ter: 8,
};

export function getTransportModeSrc(mode: string, color: boolean = true): string | undefined {
	let ret = undefined;
	if (validTransportModes.includes(mode)) {
		return `/symbole_${mode}_${color ? "" : "support_fonce_"}RVB.svg`;
	}
	return ret;
}

export function renderLineTransportMode(line: Line): JSX.Element {
	return <img src={getTransportModeSrc(line.transportMode)} />
}

function renderBusLinePicto(line: Line): JSX.Element {
	return (
		<div class="busLinePicto">
			<svg viewBox="0 0 31.5 14">
				<rect x="0" y="0" width="31.5" height="14" rx="1.5" ry="1.5" style={{ fill: `#${line.backColorHexa}` }} />
				<text x="50%"
					y="55%"
					dominant-baseline="middle"
					text-anchor="middle"
					font-size="7.4"
					style={{ fill: `#${line.foreColorHexa}` }}>
					{line.shortName}
				</text>
			</svg>
		</div>
	);
}

function renderTramLinePicto(line: Line): JSX.Element {
	const lineStyle = { fill: `#${line.backColorHexa}` };
	return (
		<div class="tramLinePicto">
			<svg viewBox="0 0 20 20">
				<rect x="0" y="0" width="20" height="3" rx="1" ry="1" style={lineStyle} />
				<rect x="0" y="17" width="20" height="3" rx="1" ry="1" style={lineStyle} />
				<text x="50%"
					y="55%"
					dominant-baseline="middle"
					text-anchor="middle"
					font-size="11"
					style={{ fill: "#00000" }}>
					{line.shortName}
				</text>
			</svg>
		</div>
	);
}

function renderMetroLinePicto(line: Line): JSX.Element {
	return (
		<div class="metroLinePicto">
			<svg viewBox="0 0 20 20">
				<circle cx="10" cy="10" r="10" style={{ fill: `#${line.backColorHexa}` }} />
				<text x="50%"
					y="55%"
					dominant-baseline="middle"
					text-anchor="middle"
					font-size="11" style={{ fill: `#${line.foreColorHexa}` }}>
					{line.shortName}
				</text>
			</svg>
		</div>
	);
}

function renderTrainLinePicto(line: Line): JSX.Element {
	return (
		<div class="trainLinePicto">
			<svg viewBox="0 0 20 20">
				<rect x="0" y="0" width="20" height="20" rx="4.5" ry="4.5" style={{ fill: `#${line.backColorHexa}` }} />
				<text x="50%"
					y="55%"
					dominant-baseline="middle"
					text-anchor="middle"
					font-size="11"
					style={{ fill: `#${line.foreColorHexa}` }}>
					{line.shortName}
				</text>
			</svg>
		</div>
	);
}

export function renderLinePicto(line: Line): JSX.Element {
	switch (line.transportMode) {
		case "bus":
		case "funicular":
			return renderBusLinePicto(line);
		case "tram":
			return renderTramLinePicto(line);
		/* case "val": */
		case "metro":
			return renderMetroLinePicto(line);
		case "transilien":
		case "rer":
		case "ter":
			return renderTrainLinePicto(line);
	}
}

export type PositionedPanel = {
	position: number;
	// TODO: Should be PassagesPanelComponent ?
	panel: JSX.Element;
};


export const ScrollingText: VoidComponent<{ height: number, width: number, content: string }> = (props) => {

	let viewBoxRef: SVGSVGElement | undefined = undefined;
	let textRef: SVGTextElement | undefined = undefined;

	onMount(() => {
		if (viewBoxRef !== undefined && textRef !== undefined) {
			const overlap = textRef.getComputedTextLength() - viewBoxRef.viewBox.baseVal.width;
			if (overlap > 0) {
				timeline(
					[
						[textRef, { x: [-overlap] }, { duration: 5 }],
						[textRef, { x: [0] }, { duration: 2 }],
					],
					{ repeat: Infinity },
				);
			}
		}
	});

	return (
		<svg ref={viewBoxRef} viewBox={`0 0 ${props.width} ${props.height}`}>
			<text
				ref={textRef}
				x="0%" y="55%"
				dominant-baseline="middle"
				font-size={`${props.height}px`}>
				{props.content}
			</text>
		</svg >
	);
}
