import { Button, ButtonGroup } from "@mui/material";
import dayjs from "dayjs";
import isoWeek from "dayjs/plugin/isoWeek";
import { useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import { toast } from "react-toastify";

import { DateRange } from "@/models/DateRange";
import { DateRangeType } from "@/models/DateRangeType";

import { DateTimePicker } from "./DateTimePicker";

dayjs.extend(isoWeek);

interface Props {
	name: string;
	onChange: (name: string, value: DateRange) => void;
}

const initialRangeType = DateRangeType.today;

export function DateTimeRangePicker({ name, onChange }: Props) {
	const { t } = useTranslation("translation");
	const [rangeType, setRangeType] = useState<DateRangeType | undefined>(
		initialRangeType,
	);
	const [range, setRange] = useState<DateRange>({
		from: dayjs().toDate(),
		to: dayjs().toDate(),
	});

	useEffect(() => {
		if (rangeType === undefined) {
			return;
		}

		setRange(getDateRange(rangeType));
	}, [rangeType]);

	useEffect(() => {
		onChange(name, range);
	}, [range]);

	const handleToggleRangeType = (rangeType: DateRangeType) => () => {
		setRangeType(rangeType);
	};

	const getVariant = (name: DateRangeType) => {
		return rangeType === name ? "contained" : "outlined";
	};

	return (
		<div className="flex flex-col gap-4 border rounded-[10px] p-4">
			<div className="flex gap-4 items-baseline">
				{t("timeFrom")}
				<DateTimePicker
					name="from"
					value={range.from}
					onChange={(name, value) => {
						if (value > range.to) {
							toast.warning(
								t(
									"The start time cannot be greater than the end time",
								),
							);
							return;
						}

						const newValue = {
							from: value,
							to: range.to,
						};
						setRange(newValue);
						onChange(name, newValue);
					}}
				/>
				<span>-</span>
				{t("timeTo")}
				<DateTimePicker
					name="to"
					value={range.to}
					onChange={(name, value) => {
						if (value < range.from) {
							toast.warning(
								t(
									"The end time cannot be less than the start time",
								),
							);
							return;
						}

						const newValue = {
							from: range.from,
							to: value < range.from ? range.from : value,
						};
						setRange(newValue);
						onChange(name, newValue);
					}}
				/>
			</div>

			<ButtonGroup variant="outlined">
				<Button
					type="button"
					onClick={handleToggleRangeType(DateRangeType.today)}
					variant={getVariant(DateRangeType.today)}
				>
					{t("today")}
				</Button>
				<Button
					type="button"
					onClick={handleToggleRangeType(DateRangeType.yesterday)}
					variant={getVariant(DateRangeType.yesterday)}
				>
					{t("yesterday")}
				</Button>
				<Button
					type="button"
					onClick={handleToggleRangeType(DateRangeType.currentMonth)}
					variant={getVariant(DateRangeType.currentMonth)}
				>
					{t("currentMonth")}
				</Button>
				<Button
					type="button"
					onClick={handleToggleRangeType(DateRangeType.lastMonth)}
					variant={getVariant(DateRangeType.lastMonth)}
				>
					{t("lastMonth")}
				</Button>
			</ButtonGroup>
		</div>
	);
}

function getDateRange(rangeType: DateRangeType): DateRange {
	if (rangeType === DateRangeType.today) {
		return {
			from: dayjs().startOf("day").toDate(),
			to: dayjs().endOf("day").toDate(),
		};
	}

	if (rangeType === DateRangeType.yesterday) {
		return {
			from: dayjs().subtract(1, "day").startOf("day").toDate(),
			to: dayjs().subtract(1, "day").endOf("day").toDate(),
		};
	}

	if (rangeType === DateRangeType.currentMonth) {
		return {
			from: dayjs().startOf("month").toDate(),
			to: dayjs().endOf("month").toDate(),
		};
	}

	if (rangeType === DateRangeType.lastMonth) {
		return {
			from: dayjs().subtract(1, "month").startOf("month").toDate(),
			to: dayjs().subtract(1, "month").endOf("month").toDate(),
		};
	}

	throw new Error("Unknown rangeType");
}
