<script setup lang="ts">
import {computed, ref, watch} from 'vue';
import {api} from '../services/api';

const props = defineProps<{metricKey: string | null}>();
const emit  = defineEmits<{(e: 'close'): void}>();

const mode = ref<'hourly' | 'daily'>('hourly');
const rows = ref<any[]>([]);
const W = 600, H = 200, PAD = 30;

watch([() => props.metricKey, mode], async ([key]) => {
	if(!key) return;
	const past = new Date(), future = new Date();
	if(mode.value === 'hourly') {
		past.setHours(past.getHours() - 24);
		future.setHours(future.getHours() + 24);
		rows.value = await api.hourly(past, future);
	} else {
		past.setDate(past.getDate() - 3);
		future.setDate(future.getDate() + 3);
		rows.value = await api.daily(past, future);
	}
}, {immediate: true});

const now = new Date();

const points = computed(() => {
	if(!rows.value.length || !props.metricKey) return [];
	return rows.value.map(r => ({
		t: new Date(r.time as string).getTime(),
		v: r[props.metricKey!] as number | null,
	})).filter(p => p.v != null);
});

const chart = computed(() => {
	const pts = points.value;
	if(!pts.length) return {minT:0, maxT:1, minV:0, maxV:1, path:{hist:'',fut:''}, currentX:0, dot:null as any, yLabels:[] as any[]};

	const ts = pts.map(p => p.t), vs = pts.map(p => p.v as number);
	const minT = Math.min(...ts), maxT = Math.max(...ts);
	const rawMin = Math.min(...vs), rawMax = Math.max(...vs);
	const pad = (rawMax - rawMin) * 0.1 || 1;
	const minV = rawMin - pad, maxV = rawMax + pad;

	const xOf = (t: number) => PAD + ((t - minT) / (maxT - minT || 1)) * (W - PAD * 2);
	const yOf = (v: number) => H - PAD - ((v - minV) / (maxV - minV || 1)) * (H - PAD * 2);
	const nowT = now.getTime();
	const currentX = Math.max(PAD, Math.min(W - PAD, xOf(nowT)));

	const hist = pts.filter(p => p.t <= nowT);
	const fut  = pts.filter(p => p.t >= nowT);

	// stitch current point into both paths so lines meet
	const nearest = pts.reduce((a, b) => Math.abs(a.t - nowT) < Math.abs(b.t - nowT) ? a : b);
	const dot = {x: xOf(nearest.t), y: yOf(nearest.v as number), v: nearest.v};

	const toPath = (arr: typeof pts) =>
		arr.map((p, i) => `${i===0?'M':'L'} ${xOf(p.t).toFixed(1)} ${yOf(p.v as number).toFixed(1)}`).join(' ');

	// y-axis labels (5 ticks)
	const yLabels = Array.from({length: 5}, (_, i) => {
		const frac = i / 4;
		const v = minV + frac * (maxV - minV);
		return {y: yOf(v), label: v.toFixed(1)};
	});

	// x-axis labels
	const xLabels: {x: number, label: string}[] = [];
	const span = maxT - minT;
	const tickCount = mode.value === 'hourly' ? 9 : 7;
	for(let i = 0; i <= tickCount; i++) {
		const t = minT + (i / tickCount) * span;
		const d = new Date(t);
		const label = mode.value === 'hourly'
			? d.toLocaleTimeString([], {hour: '2-digit', minute: '2-digit'})
			: d.toLocaleDateString([], {month: 'short', day: 'numeric'});
		xLabels.push({x: xOf(t), label});
	}

	return {minV, maxV, path: {hist: toPath(hist), fut: toPath(fut)}, currentX, dot, yLabels, xLabels};
});
</script>

<style scoped lang="scss">
.backdrop {
	position: fixed;
	inset: 0;
	background: rgba(0,0,0,0.6);
	z-index: 1000;
	display: flex;
	align-items: center;
	justify-content: center;
	padding: 16px;
	backdrop-filter: blur(4px);
}
.modal {
	background: var(--bg);
	border: 1px solid var(--border);
	border-radius: 16px;
	padding: 24px;
	width: 100%;
	max-width: 700px;
}
.modal-header {
	display: flex;
	align-items: center;
	justify-content: space-between;
	margin-bottom: 16px;
	.title { font-size: 16px; font-weight: 700; color: var(--text); text-transform: capitalize; }
	.close-btn {
		background: none;
		border: 1px solid var(--border);
		color: var(--text);
		border-radius: 8px;
		width: 32px;
		height: 32px;
		cursor: pointer;
		font-size: 16px;
		&:hover { background: var(--hover); }
	}
}
.mode-toggle {
	display: flex;
	gap: 6px;
	margin-bottom: 16px;
	button {
		font-size: 11px;
		padding: 4px 12px;
		border-radius: 6px;
		border: 1px solid var(--border);
		background: none;
		color: var(--text-muted);
		cursor: pointer;
		&.active { background: var(--accent); color: #fff; border-color: var(--accent); }
	}
}
.current-val {
	font-size: 13px;
	color: var(--text-muted);
	margin-bottom: 12px;
	span { color: var(--accent); font-weight: 700; }
}
svg { width: 100%; overflow: visible; }
.tick-label {
	font-size: 9px;
	fill: var(--text-muted);
}
</style>

<template>
	<Teleport to="body">
		<Transition name="fade">
			<div v-if="metricKey" class="backdrop" @click.self="emit('close')">
				<div class="modal">
					<div class="modal-header">
						<span class="title">{{ metricKey?.replace(/_/g, ' ') }}</span>
						<button class="close-btn" @click="emit('close')">✕</button>
					</div>

					<div class="mode-toggle">
						<button :class="{active: mode === 'hourly'}" @click="mode = 'hourly'">Hourly ±24h</button>
						<button :class="{active: mode === 'daily'}" @click="mode = 'daily'">Daily ±3d</button>
					</div>

					<div v-if="chart.dot" class="current-val">Now: <span>{{ (chart.dot.v as number).toFixed(2) }}</span></div>

					<svg :viewBox="`0 0 ${W} ${H}`" preserveAspectRatio="none">
						<!-- y-axis grid lines & labels -->
						<template v-for="tick in chart.yLabels" :key="tick.y">
							<line :x1="PAD" :y1="tick.y" :x2="W-PAD" :y2="tick.y" stroke="var(--border)" stroke-width="0.5" opacity="0.5"/>
							<text :x="PAD - 4" :y="tick.y + 3" text-anchor="end" class="tick-label">{{ tick.label }}</text>
						</template>

						<!-- x-axis labels -->
						<template v-for="tick in chart.xLabels" :key="tick.x">
							<text :x="tick.x" :y="H - 4" text-anchor="middle" class="tick-label">{{ tick.label }}</text>
						</template>

						<!-- axes -->
						<line :x1="PAD" :y1="PAD" :x2="PAD" :y2="H-PAD" stroke="var(--border)" stroke-width="1"/>
						<line :x1="PAD" :y1="H-PAD" :x2="W-PAD" :y2="H-PAD" stroke="var(--border)" stroke-width="1"/>

						<!-- now line -->
						<line :x1="chart.currentX" :y1="PAD" :x2="chart.currentX" :y2="H-PAD"
						      stroke="var(--accent)" stroke-width="1" stroke-dasharray="3 2" opacity="0.6"/>

						<!-- historic solid -->
						<path :d="chart.path.hist" fill="none" stroke="var(--accent)" stroke-width="2"/>
						<!-- future dashed -->
						<path :d="chart.path.fut" fill="none" stroke="var(--accent)" stroke-width="2" stroke-dasharray="5 3" opacity="0.5"/>

						<!-- current dot -->
						<circle v-if="chart.dot" :cx="chart.dot.x" :cy="chart.dot.y" r="4" fill="var(--accent)"/>
					</svg>
				</div>
			</div>
		</Transition>
	</Teleport>
</template>
