import {
	Box,
	Divider,
	Stack,
	Table,
	TableBody,
	TableCell,
	TableContainer,
	TableHead,
	TableRow,
	Typography,
} from "@mui/material";
import { isWeekend } from "date-fns";
import { FC, Fragment } from "react";
import { useTranslation } from "react-i18next";

import { ReportType } from "@/contracts/client.schemas";
import { useContactId } from "@/hooks/use-contact-id";
import { formatDate, formatTime, getDayName } from "@/services/time.service";

import { LogGroupModel } from "../models/LogGroupModel";
import { LogModel } from "../models/LogModel";
import { Report } from "../models/Report";

interface Props {
	logGroup: LogGroupModel;
	report: Report;
}

interface LogPack {
	day: DayData;
	logs: LogItem[];
}

interface DayData {
	value: Date;
	text: string;
	backgroundColor: string;
}

interface LogItem {
	time: string;
	log: LogItemData;
}

interface LogItemData {
	message: string;
	foregroundColor?: string;
	backgroundColor?: string;
}

const alarmBackgroundColor = "#ed5f5c";
const recoveryBackgroundColor = "#b2dbab";

export const JournalReportDetailsItem: FC<Props> = ({ logGroup, report }) => {
	const { t, i18n } = useTranslation();
	const { getMessage } = useContactId();

	if (report.type !== ReportType.Journal) {
		throw new Error("JournalDetailsItem requires the journal report type");
	}

	const getMessageText = (log: LogModel): string => {
		if (log.Message) {
			if (log.Username) {
				return `${log.Username}: ${log.Message}`;
			}

			return log.Message;
		}

		return getMessage(log.Code);
	};

	const getLogs = (): LogPack[] => {
		const resultList: LogPack[] = [];

		for (const dayLogs of logGroup.Days) {
			const logs = dayLogs.Logs;
			const day = new Date(dayLogs.Date);
			const backgroundColor = isWeekend(day) ? "#edbfbe" : "#99db99";
			const dayOfWeekName = getDayName(day, i18n.language);

			resultList.push({
				day: {
					value: day,
					text: `${formatDate(day)} (${dayOfWeekName})`,
					backgroundColor: backgroundColor,
				},
				logs: logs.map((log) => {
					return {
						time: formatTime(log.CreatedAt),
						log: {
							message: getMessageText(log),
							backgroundColor:
								log.IsAlarm === null
									? undefined
									: log.IsAlarm
										? alarmBackgroundColor
										: recoveryBackgroundColor,
						},
					};
				}),
			});
		}

		return resultList.sort();
	};

	return (
		<Stack border="1px solid #ddd" borderRadius={2} padding={1} spacing={1}>
			<Typography fontWeight={500}>
				<b>{logGroup.AssetName}</b> (#{logGroup.AssetId})
			</Typography>
			<Divider color="grey" variant="fullWidth" />

			<Stack>
				<Typography fontWeight={500}>
					{t("allRecordsInJournal")}{" "}
					<b>{logGroup.TotalRecordCount}</b>
				</Typography>
				<Stack paddingX={2}>
					<Typography>
						{t("ofAlarms")} <b>{logGroup.TotalAlarmCount}</b>
					</Typography>
				</Stack>
			</Stack>

			<Stack>
				<Typography fontWeight={500}>
					{t("totalUserCount")} <b>{logGroup.Users.length}</b>
				</Typography>
				<Stack paddingX={2}>
					{logGroup.Users.map((user) => (
						<Typography key={user.Name}>
							{user.Name}: <b>{user.LogCount}</b>
						</Typography>
					))}
				</Stack>
			</Stack>

			<Box>
				<TableContainer>
					<Table size="small">
						<TableHead>
							<TableRow>
								<TableCell>{t("time")}</TableCell>
								<TableCell>{t("event")}</TableCell>
							</TableRow>
						</TableHead>
						<TableBody>
							{getLogs().map((pack: LogPack, index) => (
								<Fragment key={`pack-${index}`}>
									<TableRow
										key={`pack-${index}`}
										sx={{
											backgroundColor:
												pack.day.backgroundColor,
										}}
									>
										<TableCell colSpan={2}>
											{pack.day.text}
										</TableCell>
									</TableRow>

									{pack.logs.length > 0 ? (
										pack.logs.map((item, index) => (
											<TableRow
												key={`log-${index}`}
												sx={{
													color: item.log
														.foregroundColor,
													backgroundColor:
														item.log
															.backgroundColor,
												}}
											>
												<TableCell>
													{item.time}
												</TableCell>
												<TableCell>
													{item.log.message}
												</TableCell>
											</TableRow>
										))
									) : (
										<TableRow key={`nodata-${index}`}>
											<TableCell colSpan={2}>
												{t("hasNoDataOfTheDay")}
											</TableCell>
										</TableRow>
									)}
								</Fragment>
							))}
						</TableBody>
					</Table>
				</TableContainer>
			</Box>
		</Stack>
	);
};
