import { useContext, useEffect, useState } from 'react';
import { useSelector } from 'react-redux';

import type { RootState } from '../../../../ReduxState/store';
import type { CashFlowMetricModel } from '../../../../Store/CashFlowAnalysis/CashFlowMetric/CashFlowMetric-context';
import { CashFlowMetricContext } from '../../../../Store/CashFlowAnalysis/CashFlowMetric/CashFlowMetric-context';
import { labelNames } from '../../../CashFlowAnalysis/CashFlowMetric/Components/CashFlowMetricTable2';
import type { CompanyDbModel } from '../../../Companies/Components/CompaniesComponents.helper';
import SimpleTimeline from './Components/SimpleTimeline';
import styles from './WorkingCapitalTimelineChart.module.scss';
import getCompanyType from '../../../../utils/getCompanyType';
import globalStyles from '../../../../Components/GlobalStyles/globals.module.scss';
import type { FinancialsModel } from '../../../Financials/Components/FinancialsForm/FinancialsForm.helper';

interface Event {
	value: number;
	label: string;
	labelPosition: string;
	color: string;
}

const WorkingCapitalTimelineChart = () => {
	const cashFlowContext: CashFlowMetricModel = useContext(CashFlowMetricContext);
	// const companyType: string | null = localStorage.getItem('companyType');
	const selectedCompany = useSelector(
		(state: RootState): CompanyDbModel | null => state.companies.selectedCompany
	);
	const selectedFinancials = useSelector(
		(state: RootState): FinancialsModel[] | null => state.financials.financialsList
	);
	const thirdSelectedFinancial = selectedFinancials!?.slice(-1)[0];
	const [currencyLabel, setCurrencyLabel] = useState<string>('GBP');
	const companyType: string | null = getCompanyType(selectedCompany);
	const labelType = companyType?.toLowerCase() === 'all other' ? 'allOther' : 'service';

	console.log(selectedFinancials, 'selectedFinancials in WC timeline');

	useEffect(() => {
		if (selectedCompany) {
			setCurrencyLabel(
				`${
					typeof selectedCompany?.currency_symbol === 'string'
						? 'GBP'
						: selectedCompany?.currency_symbol.value
				}`
			);
		}
	}, [selectedCompany]);

	const sortAndAdjustLabelPosition = (events: Event[]): Event[] => {
		// Make a shallow copy to avoid mutating original array
		const sortedArr = events.slice().sort((a, b) => a.value - b.value);

		// Iterate through sorted array to compare consecutive items
		for (let i = 1; i < sortedArr.length; i++) {
			const prevItem = sortedArr[i - 1];
			const currentItem = sortedArr[i];

			const diff = Math.abs(prevItem.value - currentItem.value);

			// If difference is less than 10, adjust labelPosition
			if (diff < 10) {
				// Toggle labelPosition between 'top' and 'bottom'
				currentItem.labelPosition = currentItem.labelPosition === 'top' ? 'bottom' : 'top';
			}
		}

		return sortedArr;
	};

	const mergeAndSortEventRecords = (events: Event[]) => {
		const grouped: { [key: number]: Event[] } = {};

		// Group objects by their value
		events.forEach((item) => {
			if (!grouped[item.value]) {
				grouped[item.value] = [];
			}
			grouped[item.value].push(item);
		});

		const mergedArray: Event[] = [];

		for (const value in grouped) {
			const group = grouped[value];

			if (group.length === 1) {
				// Only one object with this value; keep as is
				mergedArray.push({ ...group[0] });
			} else {
				// Multiple objects with same value; merge them
				const mergedLabels = group.map((obj) => obj.label).join(' / ');

				// Decide on labelPosition: for example, keep the first's labelPosition
				const { labelPosition } = group[0];

				// Merge other properties if needed; here, we keep the value and labelPosition
				mergedArray.push({
					value: group[0].value,
					label: mergedLabels,
					labelPosition,
					color: group[0].color
					// Include any other properties from the first object
					// ...group[0]
				});
			}
		}

		console.log('mergedArray', { ...mergedArray });

		return sortAndAdjustLabelPosition(mergedArray);
	};

	const generateEvents = (
		thisPeriod = false
	): { value: number; label: string; labelPosition: string; color: string }[] => {
		if (thisPeriod) {
			return [
				{
					value: 0,
					label: labelNames[labelType].labelOne,
					labelPosition: 'top',
					color: 'orange'
				},
				{
					value: Math.round(+cashFlowContext.wipDaysFirst),
					label: labelNames[labelType].labelTwo,
					labelPosition: 'top',
					color: 'blue'
				},
				{
					value: Math.round(+cashFlowContext.creditorsDay),
					label: labelNames[labelType].labelThree,
					labelPosition: 'top',
					color: 'gray'
				},
				{
					value: Math.round(
						+cashFlowContext.debtorsDay +
							+cashFlowContext.wipDaysFirst -
							+cashFlowContext.deferredRevenueDays
					),
					label: labelNames[labelType].labelFour,
					labelPosition: 'top',
					color: 'purple'
				}
				// {
				// 	value: Math.round(
				// 		+cashFlowContext.debtorsDay +
				// 			+cashFlowContext.wipDaysFirst +
				// 			+cashFlowContext.deferredRevenueDays
				// 	),
				// 	label: companyType === 'All Other' ? labelNames[4].nameOne : labelNames[4].nameTwo,
				// 	labelPosition: 'top',
				// 	color: 'green'
				// }
			];
		}

		return [
			{
				value: 0,
				label: labelNames[labelType].labelOne,
				labelPosition: 'top',
				color: 'orange'
			},
			{
				value: Math.round(+cashFlowContext.wipDaysSecond),
				label: labelNames[labelType].labelTwo,
				labelPosition: 'bottom',
				color: 'blue'
			},
			{
				value: Math.round(+cashFlowContext.creditorsDaySecond),
				label: labelNames[labelType].labelThree,
				labelPosition: 'top',
				color: 'green'
			},
			{
				value: Math.round(
					+cashFlowContext.debtorsDaySecond +
						+cashFlowContext.wipDaysSecond -
						+cashFlowContext.deferredRevenueDaysSecond
				),
				label: labelNames[labelType].labelFour,
				labelPosition: 'bottom',
				color: 'purple'
			}
			// {
			// 	value: Math.round(
			// 		+cashFlowContext.debtorsDaySecond +
			// 			+cashFlowContext.wipDaysSecond +
			// 			+cashFlowContext.deferredRevenueDaysSecond
			// 	),
			// 	label: companyType === 'All Other' ? labelNames[4].nameOne : labelNames[4].nameTwo,
			// 	labelPosition: 'top',
			// 	color: 'green'
			// }
		];
	};

	if (!thirdSelectedFinancial) {
		return <></>;
	}

	return (
		<div className={`${styles['wc-timeline-container']} print-chart-container pageBreakAfter`}>
			<h3 className={globalStyles.subtitle}>Working Capital Timeline</h3>
			<div className={`${styles['this-period']} mt-3`}>
				<h5>This Period</h5>
				<div className={styles['this-period-visuals']}>
					<div className={styles['this-period-timeline']}>
						<SimpleTimeline events={mergeAndSortEventRecords(generateEvents())} />
					</div>
					<div className={styles.box}>
						<div className={styles['box-content']}>
							<span className={styles['number-of-days']}>
								{cashFlowContext.workingCapitalDaysSecond}
							</span>
							<span className={styles['wc-label']}>Working Capital Days</span>
						</div>
					</div>
				</div>
			</div>
			<div className={styles['arrow-impact']}>
				<div className={styles['arrow-impact-dummy']} />
				<div className={`${styles['arrow-impact-content']} ${styles['arrow-up']}`} />
			</div>
			<div className={styles['cash-impact']}>
				<div className={styles['cash-impact-dummy']} />
				<div className={styles['cash-impact-content']}>
					<div
						className={`${
							+cashFlowContext.workingCapitalDaysSecond > +cashFlowContext.workingCapitalDays
								? styles['cash-impact-value-red']
								: styles['cash-impact-value']
						}`}
					>
						{/* {(
							(+cashFlowContext.workingCapitalSecond / +cashFlowContext.workingCapitalDaysSecond) *
							(+cashFlowContext.workingCapitalDaysSecond - +cashFlowContext.workingCapitalDays)
						).toLocaleString('en-GB', {
							style: 'currency',
							currency: currencyLabel,
							minimumFractionDigits: 0,
							maximumFractionDigits: 0
						})} */}
						{(
							((+cashFlowContext.workingCapitalDaysSecond - +cashFlowContext.workingCapitalDays) /
								365) *
							(+thirdSelectedFinancial.input.COGS + +thirdSelectedFinancial.input['Direct Labour'])
						).toLocaleString('en-GB', {
							style: 'currency',
							currency: currencyLabel,
							minimumFractionDigits: 0,
							maximumFractionDigits: 0
						})}
					</div>
					<div
						className={`${
							+cashFlowContext.workingCapitalDaysSecond > +cashFlowContext.workingCapitalDays
								? styles['cash-impact-label-red']
								: styles['cash-impact-label']
						}`}
					>
						Cash Impact
					</div>
				</div>
			</div>
			<div className={styles['arrow-impact']}>
				<div className={styles['arrow-impact-dummy']} />
				<div className={`${styles['arrow-impact-content']} ${styles['arrow-up']}`} />
			</div>
			<div className={styles['last-period']}>
				<h5>Last Period</h5>
				<div className={styles['this-period-visuals']}>
					<div className={styles['this-period-timeline']}>
						<SimpleTimeline events={mergeAndSortEventRecords(generateEvents(true))} />
					</div>
					<div className={styles.box}>
						<div className={styles['box-content']}>
							<span className={styles['number-of-days']}>{cashFlowContext.workingCapitalDays}</span>
							<span className={styles['wc-label']}>Working Capital Days</span>
						</div>
					</div>
				</div>
			</div>
		</div>
	);
};

export default WorkingCapitalTimelineChart;
