import { Dispatch, SetStateAction, useCallback, useEffect } from 'react';
import { Typography } from 'antd';
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
import { useGetQueryLabels } from 'hooks/useGetQueryLabels';
import { isEmpty } from 'lodash-es';
import { ColumnUnit } from 'types/api/dashboard/getAll';

import YAxisUnitSelectorV2 from '../DashboardYAxisUnitSelectorWrapper';

import './ColumnUnitSelector.styles.scss';

interface ColumnUnitSelectorProps {
	columnUnits: ColumnUnit;
	setColumnUnits: Dispatch<SetStateAction<ColumnUnit>>;
	isNewDashboard: boolean;
	'data-testid'?: string;
}

export function ColumnUnitSelector(
	props: ColumnUnitSelectorProps,
): JSX.Element {
	const { currentQuery } = useQueryBuilder();
	const { columnUnits, setColumnUnits, isNewDashboard } = props;

	const aggregationQueries = useGetQueryLabels(currentQuery);

	const handleColumnUnitSelect = useCallback(
		(queryName: string, value: string): void => {
			setColumnUnits((prev) => ({
				...prev,
				[queryName]: value,
			}));
		},
		[setColumnUnits],
	);

	const getValues = (value: string): string => {
		const currentValue = columnUnits[value];
		if (currentValue) {
			return currentValue;
		}

		// if base query has value, return it
		const baseQuery = value.split('.')[0];

		if (columnUnits[baseQuery]) {
			return columnUnits[baseQuery];
		}

		// if we have value as base query i.e. value = B, but the columnUnit have let say B.count(): 'h' then we need to return B.count()
		// get the queryName B.count() from the columnUnits keys based on the B that we have (first match - 0th aggregationIndex)
		const newQueryWithExpression = Object.keys(columnUnits).find(
			(key) =>
				key.startsWith(baseQuery) &&
				!isEmpty(aggregationQueries.find((query) => query.value === key)),
		);
		if (newQueryWithExpression) {
			return columnUnits[newQueryWithExpression];
		}

		return '';
	};

	useEffect(() => {
		const newColumnUnits = aggregationQueries.reduce(
			(acc, query) => {
				acc[query.value] = getValues(query.value);
				return acc;
			},
			{} as Record<string, string>,
		);
		setColumnUnits(newColumnUnits);
		// eslint-disable-next-line react-hooks/exhaustive-deps
	}, [aggregationQueries]);

	return (
		<section className="column-unit-selector">
			<Typography.Text className="heading">Column Units</Typography.Text>
			<div className="column-unit-selector-content">
				{aggregationQueries.map(({ value, label }) => {
					const baseQueryName = value.split('.')[0];
					return (
						<YAxisUnitSelectorV2
							value={columnUnits[value] || ''}
							onSelect={(unitValue: string): void =>
								handleColumnUnitSelect(value, unitValue)
							}
							fieldLabel={label}
							key={value}
							data-testid={props['data-testid']}
							selectedQueryName={baseQueryName}
							// Update the column unit value automatically only in create mode
							shouldUpdateYAxisUnit={isNewDashboard}
						/>
					);
				})}
			</div>
		</section>
	);
}
