import {
	memo,
	MouseEvent,
	MouseEventHandler,
	useCallback,
	useMemo,
} from 'react';
import { Color } from '@signozhq/design-tokens';
import { Tooltip } from 'antd';
import { VIEW_TYPES } from 'components/LogDetail/constants';
import { DATE_TIME_FORMATS } from 'constants/dateTimeFormats';
import {
	getBodyDisplayString,
	getSanitizedLogBody,
} from 'container/LogDetailedView/utils';
import { useCopyLogLink } from 'hooks/logs/useCopyLogLink';
// hooks
import { useIsDarkMode } from 'hooks/useDarkMode';
import { FlatLogData } from 'lib/logs/flatLogData';
import { isEmpty, isNumber, isUndefined } from 'lodash-es';
import { useTimezone } from 'providers/Timezone';

import LogLinesActionButtons from '../LogLinesActionButtons/LogLinesActionButtons';
import LogStateIndicator from '../LogStateIndicator/LogStateIndicator';
import { getLogIndicatorType } from '../LogStateIndicator/utils';
// styles
import { InfoIconWrapper, RawLogContent, RawLogViewContainer } from './styles';
import { RawLogViewProps } from './types';

function RawLogView({
	isActiveLog,
	isReadOnly,
	data,
	linesPerRow,
	isTextOverflowEllipsisDisabled,
	isHighlighted,
	helpTooltip,
	selectedFields = [],
	fontSize,
	onLogClick,
	onSetActiveLog,
	onClearActiveLog,
}: RawLogViewProps): JSX.Element {
	const {
		isHighlighted: isUrlHighlighted,
		isLogsExplorerPage,
		onLogCopy,
	} = useCopyLogLink(data.id);
	const flattenLogData = useMemo(() => FlatLogData(data), [data]);

	const isDarkMode = useIsDarkMode();
	const isReadOnlyLog = !isLogsExplorerPage || isReadOnly;

	const logType = getLogIndicatorType(data);

	const updatedSelecedFields = useMemo(
		() => selectedFields.filter((e) => e.name !== 'id'),
		[selectedFields],
	);

	const attributesValues = updatedSelecedFields
		.filter((field) => !['timestamp', 'body'].includes(field.name))
		.map((field) => flattenLogData[field.name])
		.filter((attribute) => {
			// loadash isEmpty doesnot work with numbers
			if (isNumber(attribute)) {
				return true;
			}

			return !isUndefined(attribute) && !isEmpty(attribute);
		});

	let attributesText = attributesValues.join(' | ');

	if (attributesText.length > 0) {
		attributesText += ' | ';
	}

	const { formatTimezoneAdjustedTimestamp } = useTimezone();

	const text = useMemo(() => {
		const parts = [];

		// Check if timestamp is selected
		const showTimestamp = selectedFields.some(
			(field) => field.name === 'timestamp',
		);
		if (showTimestamp) {
			const date =
				typeof data.timestamp === 'string'
					? formatTimezoneAdjustedTimestamp(
							data.timestamp,
							DATE_TIME_FORMATS.ISO_DATETIME_MS,
						)
					: formatTimezoneAdjustedTimestamp(
							data.timestamp / 1e6,
							DATE_TIME_FORMATS.ISO_DATETIME_MS,
						);
			parts.push(date);
		}

		// Check if body is selected
		const showBody = selectedFields.some((field) => field.name === 'body');
		if (showBody) {
			parts.push(`${attributesText} ${getBodyDisplayString(data.body)}`);
		} else {
			parts.push(attributesText);
		}

		return parts.join(' | ');
	}, [
		selectedFields,
		attributesText,
		data.timestamp,
		data.body,
		formatTimezoneAdjustedTimestamp,
	]);

	const handleClickExpand = useCallback(
		(event: MouseEvent) => {
			if (isReadOnly) {
				return;
			}

			// Use custom click handler if provided, otherwise use default behavior
			if (onLogClick) {
				onLogClick(data, event);
				return;
			}
			if (isActiveLog) {
				onClearActiveLog?.();
				return;
			}

			onSetActiveLog?.(data);
		},
		[isReadOnly, onLogClick, isActiveLog, onSetActiveLog, data, onClearActiveLog],
	);

	const handleShowContext: MouseEventHandler<HTMLElement> = useCallback(
		(event) => {
			event.preventDefault();
			event.stopPropagation();

			onSetActiveLog?.(data, VIEW_TYPES.CONTEXT);
		},
		[data, onSetActiveLog],
	);

	const html = useMemo(
		() => ({
			__html: getSanitizedLogBody(text, { shouldEscapeHtml: true }),
		}),
		[text],
	);

	return (
		<RawLogViewContainer
			onClick={handleClickExpand}
			wrap={false}
			align="middle"
			$isDarkMode={isDarkMode}
			$isReadOnly={isReadOnly}
			$isHightlightedLog={isUrlHighlighted}
			$isActiveLog={isActiveLog}
			$isCustomHighlighted={isHighlighted}
			$logType={logType}
			fontSize={fontSize}
		>
			<LogStateIndicator
				fontSize={fontSize}
				severityText={data.severity_text}
				severityNumber={data.severity_number}
			/>
			{helpTooltip && (
				<Tooltip title={helpTooltip} placement="top" mouseEnterDelay={0.5}>
					<InfoIconWrapper
						size={14}
						className="help-tooltip-icon"
						color={Color.BG_VANILLA_400}
					/>
				</Tooltip>
			)}

			<RawLogContent
				className="raw-log-content"
				$isReadOnly={isReadOnly}
				$isActiveLog={isActiveLog}
				$isDarkMode={isDarkMode}
				$isTextOverflowEllipsisDisabled={isTextOverflowEllipsisDisabled}
				linesPerRow={linesPerRow}
				fontSize={fontSize}
				dangerouslySetInnerHTML={html}
			/>

			{!isReadOnlyLog && (
				<LogLinesActionButtons
					handleShowContext={handleShowContext}
					onLogCopy={onLogCopy}
				/>
			)}
		</RawLogViewContainer>
	);
}
RawLogView.defaultProps = {
	isActiveLog: false,
	isReadOnly: false,
	isTextOverflowEllipsisDisabled: false,
	isHighlighted: false,
};

export default memo(RawLogView);
