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

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

import Analysis from '../../shared/Analysis';
import AnalysisHeader from '../../shared/AnalysisHeader';
import AnalysisHeaderContent from '../../shared/AnalysisHeaderContent';
import AnalysisContent from '../../shared/AnalysisContent';
import AnalysisFilters from '../../shared/AnalysisFilters';
import PageModalButtonWithType from '../../shared/PageModalButtonWithType';
import NoDataPlaceholder from '../../shared/NoDataPlaceholder';

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

import Table from '../../shared/Table';

const DEFAULT_DATE_RANGE_VALUE = '30';
const DATE_RANGE_OPTIONS = Object.entries( {
	'30': __( '30d', 'liana-with-growthstack' ),
	'90': __( '90d', 'liana-with-growthstack' ),
	'365': __( '1y', 'liana-with-growthstack' ),
} ).map( ( [ key, value ] ) => {
	return {
		label: value,
		value: key,
	};
} );

const ENDPOINT = '/growthstack/v1/analytics/most-popular/';

function getEndpointPath( dateRange, postType ) {
	const searchParams = new URLSearchParams( {
		'date-range': dateRange,
	} );

	if ( postType ) {
		searchParams.set( 'post-type', postType );
	}

	return `${ ENDPOINT }?${ searchParams.toString() }`;
}

function getPages( items ) {
	return Object.values( items || [] )
		.map( ( page: any ) => {
			const engagedCount = page.engaged_count ? page.engaged_count : 0;
			const viewCount = page.view_count ? page.view_count : 0;

			const engagedPercentage =
				engagedCount > 0 ? Math.round( ( engagedCount / viewCount ) * 100 ) : 0;

			return {
				title: decodeHtmlEntities( page.title ),
				url: page.url,
				viewCount: page.view_count,
				engagedCount: page.engaged_count,
				engagedPercentage,
				engagedPercentageRendered: formatTrendValue(
					engagedPercentage,
					'percentage'
				),
				type: page.type,
				modal: page.modal,
			};
		} )
		.sort( ( a, b ) => {
			return b.viewCount - a.viewCount;
		} );
}

function getLandingPages( items ) {
	return Object.values( items || [] )
		.map( ( page: any ) => {
			return {
				title: decodeHtmlEntities( page.title ),
				url: page.url,
				landingCount: page.landing_count,
				type: page.type,
				modal: page.modal,
			};
		} )
		.sort( ( a, b ) => {
			return b.landingCount - a.landingCount;
		} );
}

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

	const [ dateRange, setDateRange ] = useState( DEFAULT_DATE_RANGE_VALUE );
	const [ postType, setPostType ] = useState( '' );
	const [ pages, setPages ] = useState( [] );
	const [ landingPages, setLandingPages ] = useState( [] );
	const [ postTypeOptions, setPostTypeOptions ] = useState( [] );

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

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

	useEffect( () => {
		const endpointPath = getEndpointPath( dateRange, postType );
		const cached = getCachedData( endpointPath );

		if ( cached?.isFetched ) {
			setData( cached.data );
			setError( cached.error );
			setPostTypeOptions( cached.data?.available_post_types || [] );
			return;
		}

		setData( null );
		setError( null );
		setPages( [] );
		setLandingPages( [] );

		apiFetch( { path: endpointPath } )
			.then( ( response ) => {
				const responseData = response || null;
				setData( responseData );
				setPostTypeOptions( responseData?.available_post_types || [] );
				setCachedData( endpointPath, responseData, null );
			} )
			.catch( ( fetchError ) => {
				setError( fetchError );
				setCachedData( endpointPath, null, fetchError );
				// eslint-disable-next-line no-console
				console.error(
					'Failed to fetch most popular pages',
					fetchError
				);
			} );
	}, [ dateRange, postType, getCachedData, setCachedData ] );

	useEffect( () => {
		setPages( getPages( data?.most_popular_pages ) );
		setLandingPages( getLandingPages( data?.most_popular_landing_pages ) );
	}, [ data ] );

	const isLoading = ! data && ! error;
	const availablePostTypes = [
		{
			label: __( 'All post types', 'liana-with-growthstack' ),
			value: '',
		},
		...postTypeOptions,
	];

	return (
		<>
			<div className="gs-header-box">
				<div className="gs-header-box__main">
					<h2>{ __( 'Most Popular', 'liana-with-growthstack' ) }</h2>
				</div>
				<div className="gs-header-box__actions growthstack-analytics-site-popular__filters">
					<AnalysisFilters title={ __( 'Post type', 'liana-with-growthstack' ) }>
						<select
							className="gs-most-popular-post-type-select"
							aria-label={ __( 'Post type', 'liana-with-growthstack' ) }
							value={ postType }
							onChange={ ( event ) => setPostType( event.target.value ) }
							disabled={ isLoading && postTypeOptions.length === 0 }
						>
							{ availablePostTypes.map( ( option ) => (
								<option key={ option.value || 'all' } value={ option.value }>
									{ option.label }
								</option>
							) ) }
						</select>
					</AnalysisFilters>
					<AnalysisFilters title={ __( 'Range', 'liana-with-growthstack' ) }>
						{ DATE_RANGE_OPTIONS.map( ( option ) => (
							<Button
								key={ option.value }
								isPrimary={ option.value === dateRange }
								onClick={ () => setDateRange( option.value ) }
							>
								{ option.label }
							</Button>
						) ) }
					</AnalysisFilters>
				</div>
			</div>
			<div className="growthstack-analytics-site-popular">
				<div className={ `gs-box ${ isLoading ? 'is-skeleton' : '' }` }>
					<Analysis>
						<AnalysisHeader>
							<AnalysisHeaderContent>
								<h2>
									{ __(
										'Most Popular Pages',
										'liana-with-growthstack'
									) }
								</h2>
								<p>
									{ __(
										'The most popular pages on your site.',
										'liana-with-growthstack'
									) }
								</p>
							</AnalysisHeaderContent>
						</AnalysisHeader>
						<AnalysisContent>
							{ isLoading && <Spinner /> }
							{ error && (
								<div className="gs-analytics-overview__error">
									{ __(
										"There's an error fetching the data.",
										'liana-with-growthstack'
									) }
								</div>
							) }
							{ pages.length > 0 && (
								<>
									<Table
										className="gs-analytics-overview__pages"
										columns={ [
											{
												Header: __(
													'Title',
													'liana-with-growthstack'
												),
												accessor: 'title',
												width: 225,
												minWidth: 100,
												maxWidth: 225,
												Cell: ( { row } ) => (
													<PageModalButtonWithType
														title={
															row.original.title
														}
														type={
															row.original.type
														}
														onClick={ () => {
															setModalData(
																row.original
																	.modal
															);
															setIsModalOpen(
																true
															);
														} }
													/>
												),
											},
											{
												Header: __(
													'Views',
													'liana-with-growthstack'
												),
												accessor: 'viewCount',
											},
											{
												Header: __(
													'Engagement',
													'liana-with-growthstack'
												),
												accessor: 'engagedPercentage',
												Cell: ( { row } ) => (
													<span className="gs-analytics-overview__engagement">
														{
															row.original
																.engagedPercentageRendered
														}
													</span>
												),
											},
										] }
										data={ pages }
									/>
									{ isModalOpen && (
										<PageAnalytics
											isOpen={ isModalOpen }
											onClose={ () =>
												setIsModalOpen( false )
											}
											data={ modalData }
										/>
									) }
								</>
							) }
							{ pages.length === 0 && ! isLoading && (
								<NoDataPlaceholder type="analytics">
									<p>
										{ __(
											"There's no data to show yet.",
											'liana-with-growthstack'
										) }
									</p>
								</NoDataPlaceholder>
							) }
						</AnalysisContent>
					</Analysis>
				</div>
				<div className={ `gs-box ${ isLoading ? 'is-skeleton' : '' }` }>
					<Analysis>
						<AnalysisHeader>
							<AnalysisHeaderContent>
								<h2>
									{ __(
										'Most Popular Landing Pages',
										'liana-with-growthstack'
									) }
								</h2>
								<p>
									{ __(
										'The most popular landing pages on your site.',
										'liana-with-growthstack'
									) }
								</p>
							</AnalysisHeaderContent>
						</AnalysisHeader>
						<AnalysisContent>
							{ isLoading && <Spinner /> }
							{ error && (
								<div className="gs-analytics-overview__error">
									{ __(
										"There's an error fetching the data.",
										'liana-with-growthstack'
									) }
								</div>
							) }
							{ landingPages.length > 0 && (
								<>
									<Table
										className="gs-analytics-overview__pages"
										columns={ [
											{
												Header: __(
													'Title',
													'liana-with-growthstack'
												),
												accessor: 'title',
												Cell: ( { row } ) => (
													<PageModalButtonWithType
														title={
															row.original.title
														}
														type={
															row.original.type
														}
														onClick={ () => {
															setModalData(
																row.original
																	.modal
															);
															setIsModalOpen(
																true
															);
														} }
													/>
												),
											},
											{
												Header: __(
													'Landing Sessions',
													'liana-with-growthstack'
												),
												accessor: 'landingCount',
											},
										] }
										data={ landingPages }
									/>
								</>
							) }
							{ landingPages.length === 0 && ! isLoading && (
								<NoDataPlaceholder type="analytics">
									<p>
										{ __(
											"There's no data to show yet.",
											'liana-with-growthstack'
										) }
									</p>
								</NoDataPlaceholder>
							) }
						</AnalysisContent>
					</Analysis>
				</div>
			</div>
		</>
	);
}
