import { useCallback, useEffect, useMemo, useState } from 'react';
import { useFilters } from '@/hooks/useFilters';
import { useInsightsStore } from '../store/useInsightsStore';
import useFiltersData from '@/hooks/useFiltersData';
import { __, sprintf } from '@wordpress/i18n';
import { formatDuration } from '@/utils/formatting';
import { isExcluding } from '@/config/filterConfig';

/**
 * Custom hook for managing filter display logic.
 * Centralizes filter operations and cross-store interactions.
 *
 * @return {Object} Filter display utilities and operations.
 */
export const useFilterDisplay = ( reportBlockIndex ) => {
	const { filters, filtersConf, setFilters } = useFilters( reportBlockIndex );
	const { getFilterOptionById } = useFiltersData();
	const { setMetrics, getMetrics } = useInsightsStore();

	// Get active filters with display information
	const [ activeFilters, setActiveFilters ] = useState([]);

	useEffect( () => {
		const loadFilters = async() => {
			const filtersWithDisplay = await getActiveFiltersWithDisplay();
			setActiveFilters( filtersWithDisplay );
		};
		loadFilters();
	}, [ filters ]); // eslint-disable-line react-hooks/exhaustive-deps

	const getActiveFiltersWithDisplay = useCallback( async() => {
		const active = Object.entries( filters ).filter(
			([ _, value ]) => '' !== value // eslint-disable-line @typescript-eslint/no-unused-vars
		);
		return await Promise.all(
			active.map( async([ key, value ]) => {
				const displayValue = await getFilterDisplayValue( key, value );
				return {
					key,
					value,
					displayValue,
					config: filtersConf?.[key] || null
				};
			})
		);
	}, [ filters, filtersConf ]); // eslint-disable-line react-hooks/exhaustive-deps

	// fallow-ignore-next-line complexity
	const getFilterDisplayValue = async(
		filterKey,
		value
	) => {
		if ( ! value ) {
			return '';
		}

		if ( filtersConf[filterKey].exclusion_allowed && isExcluding( value ) ) {
			value = value.substring( 1 );
		}

		if ( Object.prototype.hasOwnProperty.call( filtersConf, filterKey ) ) {
			const filterType = filtersConf[filterKey]?.options || false;
			if ( filterType ) {

				//if value contains a , explode it into an array
				//check if value is a string and contains a comma
				if ( 'string' === typeof value && -1 !== value.indexOf( ',' ) ) {
					value = value.split( ',' ).map( ( v ) => v.trim() );

					// Map each value to its display option
					value = await Promise.all(
						value.map(
							async( v ) =>
								( await getFilterOptionById( v, filterType ) ) || v
						)
					);

					// Join back to a string
					value = value.join( ', ' );
				} else {
					value =
						( await getFilterOptionById( value, filterType ) ) || value;
				}
			}
		}

	switch ( filterKey ) {
		case 'country_code': {
			if ( ! value ) {
				return '';
			}
			const code = value.toUpperCase();
			const countryLabel = window.burst_settings?.countries?.[ code ];
			return countryLabel || code;
		}
		case 'bounces':
			return 'include' === value ?
				__( 'Bounced visitors', 'burst-statistics' ) :
				__( 'Active visitors', 'burst-statistics' );

		case 'new_visitor':
			return 'true' === value ?
				__( 'New visitors', 'burst-statistics' ) :
				__( 'Returning visitors', 'burst-statistics' );

		case 'time_per_session': {
			const dashIdx = String( value ).indexOf( '-' );
			if ( -1 === dashIdx ) {
				return value;
			}
			const minRaw = String( value ).slice( 0, dashIdx );
			const maxRaw = String( value ).slice( dashIdx + 1 );
			const minSec = parseInt( minRaw, 10 );
			const formattedMin = formatDuration( isNaN( minSec ) ? 0 : minSec );
			if ( '' === maxRaw ) {

				/* translators: %s is a human-readable duration like 2m, 1h */
				return sprintf( __( '%s+', 'burst-statistics' ), formattedMin );
			}
			const maxSec = parseInt( maxRaw, 10 );
			const formattedMax = formatDuration( isNaN( maxSec ) ? 0 : maxSec );
			return `${formattedMin} – ${formattedMax}`;
		}

		default:
			return value;
	}
	};

	/**
	 * Remove a filter and handle any side effects
	 * @param {string} filterKey - The filter key to remove
	 */
	const removeFilter = useCallback(
		( filterKey ) => {

			// Clear the filter
			setFilters( filterKey, '' );

			// Handle side effects based on filter type
			if ( 'goal_id' === filterKey ) {

				// Remove conversions metric when goal filter is removed
				const currentMetrics = getMetrics();
				const updatedMetrics = currentMetrics.filter(
					( metric ) => 'conversions' !== metric
				);
				setMetrics( updatedMetrics );
			}
		},
		[ setFilters, setMetrics, getMetrics ]
	);

	/**
	 * Check if any filters are currently active
	 * @return {boolean} True if any filters have values
	 */
	const hasActiveFilters = useMemo( () => {
		return Array.isArray( activeFilters ) && 0 < activeFilters.length;
	}, [ activeFilters ]);

	/**
	 * Get filter configuration by key
	 * @param {string} filterKey - The filter key
	 * @return {Object|null} Filter configuration or null if not found
	 */
	const getFilterConfig = useCallback(
		( filterKey ) => {
			return filtersConf[filterKey] || null;
		},
		[ filtersConf ]
	);

	return {
		activeFilters,
		hasActiveFilters,
		removeFilter,
		getFilterConfig,

		// Expose underlying store methods for advanced usage
		setFilter: setFilters,
		filters,
		filtersConf
	};
};

export default useFilterDisplay;
