/**
 * WordPress dependencies
 */
import { render } from '@safe-wordpress/element';
import domReady from '@safe-wordpress/dom-ready';

/**
 * External dependencies
 */
import type { Post, PostId, PostStatus } from '@nelio-content/types';

/**
 * External dependencies
 */
import {
	PostEngagementAnalytics,
	PostPageviewsAnalytics,
	PremiumDialog,
} from '@nelio-content/components';

/**
 * Internal dependencies
 */
import './style.scss';
import { SocialTimeline } from './social-timeline';
import { SocialMediaLink } from './social-media-link';
import { manageCustomStatuses } from './custom-status';

type Settings = {
	readonly customStatuses: ReadonlyArray< PostStatus >;
};

export function initPage( { customStatuses }: Settings ): void {
	initSocialFeatures();
	initAnalyticsFeatures();
	manageCustomStatuses( customStatuses );
}

function initSocialFeatures() {
	domReady( () => {
		const links = Array.from(
			document.querySelectorAll< HTMLElement >(
				'.nelio-content-share-post'
			)
		);
		if ( ! links.length ) {
			return;
		}

		const layout = document.createElement( 'div' );
		document.body.appendChild( layout );
		render(
			<>
				<PremiumDialog />
				<SocialTimeline />
			</>,
			layout
		);

		links
			.map( ( l ) => [ l.dataset.postId, l ] as const )
			.filter( ( l ): l is [ string, HTMLElement ] => !! l[ 0 ] )
			.map( ( [ n, e ] ) => [ Number.parseInt( n ) || 0, e ] as const )
			.filter( ( l ): l is [ PostId, HTMLElement ] => !! l[ 0 ] )
			.forEach( ( [ postId, element ] ) =>
				render( <SocialMediaLink postId={ postId } />, element )
			);
	} );
}

function initAnalyticsFeatures() {
	domReady( () => {
		const analytics = Array.from(
			document.querySelectorAll< HTMLElement >(
				'.nelio-content-post-list-analytics'
			)
		);

		analytics
			.map( ( element ) => ( {
				element,
				postId: getPostId( element ),
				statistics: getStatistics( element ),
				type: element.dataset.analyticsType,
			} ) )
			.filter(
				(
					item
				): item is {
					readonly element: HTMLElement;
					readonly postId: PostId;
					readonly statistics: Post[ 'statistics' ];
					readonly type: 'pageviews' | 'engagement';
				} =>
					!! item.postId &&
					!! item.statistics &&
					( 'pageviews' === item.type || 'engagement' === item.type )
			)
			.forEach( ( { element, postId, statistics, type } ) =>
				render(
					'pageviews' === type ? (
						<PostPageviewsAnalytics
							className="nelio-content-post-list-analytics__component"
							postId={ postId }
							statistics={ statistics }
						/>
					) : (
						<PostEngagementAnalytics
							className="nelio-content-post-list-analytics__component"
							postId={ postId }
							statistics={ statistics }
						/>
					),
					element
				)
			);
	} );
}

function getPostId( element: HTMLElement ): PostId | 0 {
	return ( Number.parseInt( element.dataset.postId || '' ) || 0 ) as
		| PostId
		| 0;
}

function getStatistics(
	element: HTMLElement
): Post[ 'statistics' ] | undefined {
	try {
		const statistics = JSON.parse( element.dataset.statistics || '' ) as
			| Post[ 'statistics' ]
			| undefined;
		return statistics?.engagement && statistics?.pageviews
			? statistics
			: undefined;
	} catch ( _ ) {
		return undefined;
	}
}
