import { useMemo, useState } from "react";
import { useTranslation } from "react-i18next";

import { useGetEventList } from "@/contracts/events";
import { ChartContainer } from "@/shared";

type Cell = { day: number; bucket: number; count: number };

type TimeBucketLabel = "Night" | "Morning" | "Lunch" | "Day" | "Evening";

type TimeBucket = {
	key: string;
	label: TimeBucketLabel;
	start: number;
	end: number;
};

const timeBuckets: TimeBucket[] = [
	{ key: "Night", label: "Night", start: 0, end: 5 }, // 00:00–05:59
	{ key: "Morning", label: "Morning", start: 6, end: 11 }, // 06:00–11:59
	{ key: "Lunch", label: "Lunch", start: 12, end: 13 }, // 12:00–13:59
	{ key: "Day", label: "Day", start: 14, end: 17 }, // 14:00–17:59
	{ key: "Evening", label: "Evening", start: 18, end: 23 }, // 18:00–23:59
];

const hourToBucket = (hour: number): number => {
	for (let i = 0; i < timeBuckets.length; i++) {
		if (hour >= timeBuckets[i].start && hour <= timeBuckets[i].end) {
			return i;
		}
	}
	return -1;
};

const bucketRangeLabel = (bucket: number): string => {
	const b = timeBuckets[bucket];
	return `${b.start.toString().padStart(2, "0")}:00–${b.end.toString().padStart(2, "0")}:59`;
};

export const AlarmsHeatmap = () => {
	const { t } = useTranslation("translation");

	const dayLabels = [
		t("Mon"),
		t("Tue"),
		t("Wed"),
		t("Thu"),
		t("Fri"),
		t("Sat"),
		t("Sun"),
	] as const;

	const { data, isFetching } = useGetEventList(
		{ AlarmsOnly: true, Take: 1000 },
		{ query: { staleTime: 60_000 } },
	);

	const { cells, max } = useMemo(() => {
		const matrix: number[][] = Array.from({ length: 7 }, () =>
			Array(timeBuckets.length).fill(0),
		);
		const events = data?.items ?? [];

		for (const e of events) {
			const d = new Date(e.createdAt);
			const day = (d.getDay() + 6) % 7;
			const hour = d.getHours();
			const bucket = hourToBucket(hour);
			if (bucket >= 0) matrix[day][bucket]++;
		}

		const max = matrix.reduce((m, row) => Math.max(m, ...row), 0);
		const res: Cell[] = [];
		for (let day = 0; day < 7; day++) {
			for (let bucket = 0; bucket < timeBuckets.length; bucket++) {
				res.push({ day, bucket, count: matrix[day][bucket] });
			}
		}
		return { cells: res, max };
	}, [data]);

	function colorFor(count: number, max: number) {
		if (max === 0) return "rgba(255,59,48,0.06)";
		const p = count / max;
		const eased = Math.pow(p, 0.8);
		const alpha = 0.15 + 0.85 * eased;
		return `rgba(255,59,48,${alpha.toFixed(3)})`;
	}

	const [hover, setHover] = useState<{
		d: number;
		b: number;
		c: number;
	} | null>(null);

	return (
		<ChartContainer titleKey={t("Alarm heatmap")} isFetching={isFetching}>
			<div className="flex flex-col gap-4">
				<div className="grid [grid-template-columns:80px_repeat(5,minmax(28px,1fr))] items-center">
					<div />
					{timeBuckets.map((b) => (
						<div
							key={b.key}
							className="text-[11px] md:text-sm text-center text-[var(--black-600)] dark:text-[var(--black-400)] select-none"
						>
							{t(b.label)}
						</div>
					))}

					{Array.from({ length: 7 }, (_, d) => (
						<div key={`row-${d}`} className="contents">
							<div className="text-xs md:text-sm text-right pr-2 text-[var(--black-800)] dark:text-[var(--black-100)]">
								{dayLabels[d]}
							</div>
							{timeBuckets.map((_, b) => {
								const c =
									cells.find(
										(x) => x.day === d && x.bucket === b,
									)?.count ?? 0;
								const dayText = dayLabels[d]; // используем прямой текст
								const bucketText = `${t(timeBuckets[b].label)} (${bucketRangeLabel(b)})`;
								const tooltip = `${dayText} • ${bucketText} — ${t("Alarms")}: ${c}`;

								return (
									<div
										key={`c-${d}-${b}`}
										className="h-5 md:h-6 rounded-lg border border-black/5 dark:border-white/10 transition-transform duration-150 hover:scale-[1.05] outline-none"
										style={{ background: colorFor(c, max) }}
										onMouseEnter={() =>
											setHover({ d, b, c })
										}
										onMouseLeave={() => setHover(null)}
										role="button"
										aria-label={tooltip}
										title={tooltip}
										tabIndex={0}
									/>
								);
							})}
						</div>
					))}
				</div>

				<div className="flex items-center gap-3">
					<div className="text-xs text-[var(--black-600)] dark:text-[var(--black-300)]">
						{t("Darker color means more alarms")}
					</div>
					<div className="flex-1" />
					<div className="flex items-center gap-2">
						<span className="text-[10px] text-[var(--black-600)] dark:text-[var(--black-300)]">
							{t("low")}
						</span>
						<div
							className="h-2 w-28 rounded-full"
							style={{
								background:
									"linear-gradient(90deg, rgba(255,59,48,0.15) 0%, rgba(255,59,48,1) 100%)",
							}}
						/>
						<span className="text-[10px] text-[var(--black-600)] dark:text-[var(--black-300)]">
							{t("high")}
						</span>
					</div>
				</div>

				<div className="min-h-5 text-[11px] text-[var(--black-700)] dark:text-[var(--black-200)]">
					{hover ? (
						<span>
							{dayLabels[hover.d]} •{" "}
							{t(timeBuckets[hover.b].label)} (
							{bucketRangeLabel(hover.b)}) — {t("Alarms")}:{" "}
							<b>{hover.c}</b>
						</span>
					) : (
						<span className="opacity-70">
							{t("Hover over a cell to see details")}
						</span>
					)}
				</div>
			</div>
		</ChartContainer>
	);
};
