import { Container, Title } from '@newfold/ui-component-library';
import { default as MarketplaceList } from '../marketplaceList/';
import { default as MarketplaceIsLoading } from '../marketplaceIsLoading/';

const defaults = {
	eventendpoint: '/newfold-data/v1/events/',
	perPage: 12,
	appendCategoryToTitle: true,
	text: {
		title: 'Marketplace',
		subTitle: 'Explore our featured collection of tools and services.',
		error: 'Oops, there was an error loading the marketplace, please try again later.',
		noProducts: 'Sorry, no marketplace items. Please, try again later.',
		loadMore: 'Load More',
	},
};

/**
 * Marketplace Module
 * For use in brand app to display marketplace
 *
 * @param {*} props
 * @return
 */
const Marketplace = ( { methods, constants, ...props } ) => {
	const [ isLoading, setIsLoading ] = methods.useState( true );
	const [ isError, setIsError ] = methods.useState( false );
	const [ marketplaceCategories, setMarketplaceCategories ] =
		methods.useState( [] );
	const [ marketplaceItems, setMarketplaceItems ] = methods.useState( [] );
	const [ products, setProducts ] = methods.useState( [] );
	const [ activeCategoryIndex, setActiveCategoryIndex ] =
		methods.useState( 0 );
	const location = methods.useLocation();

	// set defaults if not provided
	constants = Object.assign( defaults, constants );
	/**
	 * on mount load all marketplace data from module api
	 */
	methods.useEffect( () => {
		methods
			.apiFetch( {
				url: methods.NewfoldRuntime.createApiUrl(
					'/newfold-marketplace/v1/marketplace'
				),
			} )
			.then( ( response ) => {
				// check response for data
				if (
					! response.hasOwnProperty( 'categories' ) ||
					! response.hasOwnProperty( 'products' )
				) {
					setIsError( true );
				} else {
					setMarketplaceItems( response.products.data );
					setMarketplaceCategories(
						validateCategories( response.categories.data )
					);
				}
			} );
	}, [] );

	/**
	 * When marketplaceItems changes
	 * verify that there are products
	 */
	methods.useEffect( () => {
		// only after a response
		if ( ! isLoading ) {
			// if no marketplace items, display error
			if ( marketplaceItems.length < 1 ) {
				setIsError( true );
			} else {
				setIsError( false );
			}
		}
	}, [ marketplaceItems, products ] );

	/**
	 * When marketplaceCategories changes
	 * verify that the tab is a category
	 */
	methods.useEffect( () => {
		let aci = 0;
		// only before rendered, but after categories are populated
		if ( marketplaceCategories.length > 1 ) {
			// read initial tab from path
			if ( location.pathname.includes( 'marketplace/' ) ) {
				const urlpath = location.pathname.substring(
					location.pathname.lastIndexOf( '/' ) + 1
				);

				// make sure a category exists for that path
				if (
					urlpath &&
					marketplaceCategories.filter(
						( cat ) => cat.name === urlpath
					).length != 0
				) {
					// if found, set the active category
					marketplaceCategories.forEach( ( cat, i ) => {
						if ( cat.name === urlpath ) {
							aci = i;
						}
					} );
				}
			}
			setActiveCategoryIndex( aci );
			filterProducts( aci );
			applyStyles();
		}
	}, [ marketplaceCategories, location.pathname ] );

	/**
	 * Filter products based on urlpath
	 * @param activeCategoryIndex
	 */
	const filterProducts = ( activeCategoryIndex ) => {
		const category = marketplaceCategories[ activeCategoryIndex ].name;
		const filterdProducts = marketplaceItems.filter( ( product ) => {
			return product.categories.some( ( element ) => {
				return element.toLowerCase() === category.toLowerCase();
			} );
		} );

		setProducts( filterdProducts );
		setIsLoading( false );
	};

	/**
	 * Validate provided category data
	 * @param Array      categories
	 * @param categories
	 * @return
	 */
	const validateCategories = ( categories ) => {
		if ( ! categories.length ) {
			return [];
		}

		const thecategories = [];
		categories.forEach( ( cat ) => {
			cat.currentCount = constants.perPage;
			cat.className = 'newfold-marketplace-category-' + cat.name;

			if ( cat.products_count > 0 ) {
				thecategories.push( cat );
			}
		} );

		return thecategories;
	};

	/**
	 * Apply styles if they exist
	 */
	const applyStyles = () => {
		if ( marketplaceCategories ) {
			marketplaceCategories.forEach( ( category ) => {
				if (
					category.styles && // category has styles
					! document.querySelector(
						'[data-styleid="' + category.className + '"]'
					) // not already added
				) {
					const style = document.createElement( 'style' );
					style.textContent = category.styles;
					style.dataset.styleid = category.className;
					document.head.appendChild( style );
				}
			} );
		}
	};

	/**
	 * render marketplace preloader
	 *
	 * @return React Component
	 */
	const renderSkeleton = () => {
		// render default skeleton
		return <MarketplaceIsLoading />;
	};

	const getSectionTitle = () => {
		if (
			! isLoading &&
			! isError &&
			marketplaceCategories &&
			constants.appendCategoryToTitle
		) {
			return (
				constants.text.title +
				': ' +
				marketplaceCategories[ activeCategoryIndex ].title
			);
		}

		return constants.text.title;
	};

	return (
		<>
			<Container.Header
				title={ getSectionTitle() }
				description={ constants.text.subTitle }
			/>
			<Container.Block
				className={ methods.classnames(
					'newfold-marketplace-wrapper',
					`newfold-marketplace-${ marketplaceCategories[ activeCategoryIndex ] }`
				) }
			>
				{ isLoading && renderSkeleton() }
				{ isError && (
					<Title as="h3" size="3">
						{ constants.text.error }
					</Title>
				) }
				{ ! isLoading && ! isError && (
					<MarketplaceList
						marketplaceItems={ products }
						category={
							marketplaceCategories[ activeCategoryIndex ]
						}
						currentCount={
							marketplaceCategories[ activeCategoryIndex ]
								.currentCount
						}
						methods={ methods }
						constants={ constants }
					/>
				) }
			</Container.Block>
		</>
	);
};

export default Marketplace;
