import { useMemo, useState, useEffect } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import apiFetch from '@wordpress/api-fetch';

import AnalysisPie from '../../shared/AnalysisPie';
import AnalysisPieDetails from '../../shared/AnalysisPieDetails';
import AnalysisPieDetail from '../../shared/AnalysisPieDetail';

import { decodeHtmlEntities, getPossiblePieColors } from './../../shared/utils';

import PageAnalytics from '../../shared/PageAnalytics';

type SiteRuleItem = {
	postId: number;
	postTitle: string;
	name: string;
	title: string;
	clicks: number;
	views: number;
	modal: ModalData;
};

type SiteRule = {
	title: string;
	count: number;
	items: SiteRuleItem[];
};

export default function SiteRules( props ) {
	const { getCachedData, setCachedData } = props;

	const [ data, setData ] = useState( null );
	const [ error, setError ] = useState( null );

	const [ isModalOpen, setIsModalOpen ] = useState( false );
	const [ modalData, setModalData ] = useState( null );

	const ENDPOINT = '/growthstack/v1/analytics/personalization/';

	useEffect( () => {
		const cached = getCachedData( ENDPOINT );

		if ( cached?.isFetched ) {
			setData( cached.data );
			setError( cached.error );
			return;
		}

		setError( null );

		apiFetch( { path: ENDPOINT } )
			.then( ( response ) => {
				const responseData = response || null;
				setData( responseData );
				setCachedData( ENDPOINT, responseData, null );
			} )
			.catch( ( fetchError ) => {
				setError( fetchError );
				setCachedData( ENDPOINT, null, fetchError );
				// eslint-disable-next-line no-console
				console.error(
					'Failed to fetch personalization data',
					fetchError
				);
			} );
	}, [ getCachedData, setCachedData ] );

	const isLoading = ! data && ! error;

	const refinedData = useMemo( () => {
		if ( !! data && !! data.overview_365 ) {
			const rules = [] as SiteRule[];
			// make SiteRule from data?.overview_365 as SitePersonalizationReport[]
			Object.values(
				data?.overview_365 as SitePersonalizationReport[]
			).forEach( ( page ) => {
				const items = page.analytics.map( ( variation ) => {
					if ( variation.is_default ) {
						return null; // skip default variations
					}
					return {
						postId: page.id,
						postTitle: page.title,
						name: variation.name,
						title: decodeHtmlEntities( variation.rule ),
						clicks: variation.clicks,
						views: variation.views,
						modal: page.modal,
					};
				} );
				// Add items under rule if exist, otherwise create a new rule
				if ( items.length > 0 ) {
					items.forEach( ( item ) => {
						if ( item ) {
							const existingRule = rules.find(
								( rule ) => rule.title === item.title
							);
							if ( existingRule ) {
								existingRule.items.push( item );
								existingRule.count += 1;
							} else {
								rules.push( {
									title: item.title,
									count: 1,
									items: [ item ],
								} );
							}
						}
					} );
				}
			} );
			// sort rules by count descending
			rules.sort( ( a, b ) => b.count - a.count );
			// sort items by views descending within each rule
			rules.forEach( ( rule ) => {
				rule.items.sort( ( a, b ) => b.views - a.views );
			} );
			return rules;
		}
		return [];
	}, [ data ] );

	// sort by viewCount
	const sortedData = refinedData;

	const possibleColors = getPossiblePieColors();
	const dataPoints = sortedData.map( ( rule ) => ( {
		label: rule.title,
		value: rule.count,
		color: possibleColors[
			sortedData.indexOf( rule ) % possibleColors.length
		],
	} ) );

	return (
		<div className={ `gs-box ${ isLoading ? 'is-skeleton' : '' }` }>
			<h2 className="gs-box__title">
				{ __( 'Rules Used', 'liana-with-growthstack' ) }
			</h2>
			{ /* <p className="gs-box__desc">{ __( 'Default variations are not shown here.', 'liana-with-growthstack' ) }</p> */ }
			{ /* { isLoading && (
				<Spinner />
			) } */ }
			{ error && (
				<div className="gs-analytics-overview__error">
					{ __(
						"There's an error fetching the data.",
						'liana-with-growthstack'
					) }
				</div>
			) }
			{ !! sortedData && sortedData.length > 0 && (
				<>
					<AnalysisPie
						metric={ __( 'Rules', 'liana-with-growthstack' ) }
						dataPoints={ dataPoints }
						annotationLabel={ sortedData[ 0 ]?.title }
						annotationValue={ sortedData[ 0 ]?.count }
					/>
					<AnalysisPieDetails>
						{ dataPoints.map( ( point, index ) => (
							<AnalysisPieDetail
								key={ index }
								label={ point.label }
								value={ point.value }
								color={ point.color }
								subPoints={ sortedData[ index ].items.map(
									( item ) => ( {
										label: `${ item.postTitle }: ${ item.name }`,
										displayCount:
											item.views +
											' ' +
											__( 'views', 'liana-with-growthstack' ),
										onClick: () => {
											setModalData( item.modal );
											setIsModalOpen( true );
										},
									} )
								) }
							/>
						) ) }
					</AnalysisPieDetails>

					{ isModalOpen && (
						<PageAnalytics
							isOpen={ isModalOpen }
							onClose={ () => setIsModalOpen( false ) }
							data={ modalData }
						/>
					) }
				</>
			) }
			{ !! sortedData && sortedData.length === 0 && ! isLoading && (
				<div>
					{ __( "There's no data to show yet.", 'liana-with-growthstack' ) }
				</div>
			) }
		</div>
	);
}
