import { Box, Flex, Spinner, useBreakpointValue } from '@chakra-ui/react';
import { useQuery } from '@tanstack/react-query';
import apiFetch from '@wordpress/api-fetch';
import { __ } from '@wordpress/i18n';
import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { templatesScriptData } from '../utils/global';
import Sidebar from './Sidebar';
import TemplateList from './TemplateList';

const { restURL, security } = templatesScriptData;

const fetchTemplates = async () => {
	const response = (await apiFetch({
		path: `${restURL}everest-forms/v1/templates`,
		method: 'GET',
		headers: {
			'X-WP-Nonce': security,
		},
	})) as { templates: { category: string; templates: Template[] }[] };

	if (response && Array.isArray(response.templates)) {
		const allTemplates = response.templates.flatMap(
			(category) => category.templates,
		);
		return allTemplates;
	} else {
		throw new Error(__('Unexpected response format.', 'everest-forms'));
	}
};

const Main: React.FC<{ filter: string }> = ({ filter }) => {
	const [state, setState] = useState({
		selectedCategory: __('All Forms', 'everest-forms'),
		searchTerm: '',
	});
	const [categorySetFromURL, setCategorySetFromURL] = useState(false);

	const { selectedCategory, searchTerm } = state;

	const {
		data: templates = [],
		isLoading,
		error,
	} = useQuery(['templates'], fetchTemplates);

	const categories = useMemo(() => {
		const categoriesSet = new Set<string>();
		templates.forEach((template) => {
			template.categories.forEach((category) => categoriesSet.add(category));
		});

		return [
			{ name: __('All Forms', 'everest-forms'), count: templates.length },
			...Array.from(categoriesSet).map((category) => ({
				name: category,
				count: templates.filter((template) =>
					template.categories.includes(category),
				).length,
			})),
		];
	}, [templates]);

	useEffect(() => {
		if (categorySetFromURL) return;
		if (categories.length <= 1) return;

		const urlParams = new URLSearchParams(window.location.search);

		if (urlParams.has('evf_template_category')) {
			const categorySlug = urlParams.get('evf_template_category') || '';

			const normalize = (str: string) =>
				str
					.toLowerCase()
					.replace(/\s+/g, '')
					.replace(/[^a-z0-9]/g, '');

			const normalizedSlug = normalize(categorySlug);

			let matchedCategory = categories.find((cat) => {
				const normalizedCatName = normalize(cat.name);

				if (normalizedCatName === normalizedSlug) {
					console.log(`Exact match: "${cat.name}"`);
					return true;
				}

				if (normalizedCatName.startsWith(normalizedSlug)) {
					console.log(`Starts with match: "${cat.name}"`);
					return true;
				}

				if (normalizedSlug.startsWith(normalizedCatName)) {
					console.log(`Reverse starts with match: "${cat.name}"`);
					return true;
				}

				return false;
			});

			if (!matchedCategory) {
				matchedCategory = categories.find((cat) => {
					const normalizedCatName = normalize(cat.name);

					const slugWords = categorySlug.toLowerCase().split(/[\s-]+/);
					const catWords = cat.name.toLowerCase().split(/[\s-]+/);

					const hasMatchingWord = slugWords.some((word) =>
						catWords.some(
							(catWord) => catWord.includes(word) || word.includes(catWord),
						),
					);

					if (hasMatchingWord) {
						console.log(`Word match: "${cat.name}"`);
						return true;
					}

					if (
						normalizedCatName.includes(normalizedSlug) ||
						normalizedSlug.includes(normalizedCatName)
					) {
						console.log(`Contains match: "${cat.name}"`);
						return true;
					}

					return false;
				});
			}

			if (
				matchedCategory &&
				matchedCategory.name !== __('All Forms', 'everest-forms')
			) {
				setState((prevState) => ({
					...prevState,
					selectedCategory: matchedCategory.name,
				}));
				setCategorySetFromURL(true);
			}
		}
	}, [categories, categorySetFromURL]);

	const filteredTemplates = useMemo(() => {
		return templates.filter(
			(template) =>
				(selectedCategory === __('All Forms', 'everest-forms') ||
					template.categories.includes(selectedCategory)) &&
				template.title.toLowerCase().includes(searchTerm.toLowerCase()) &&
				(filter === 'All' ||
					(filter === 'Free' && !template.isPro) ||
					(filter === 'Premium' && template.isPro)),
		);
	}, [selectedCategory, searchTerm, templates, filter]);

	const handleCategorySelect = useCallback((category: string) => {
		setState((prevState) => ({ ...prevState, selectedCategory: category }));
	}, []);

	const handleSearchChange = useCallback((searchTerm: string) => {
		setState((prevState) => ({ ...prevState, searchTerm }));
	}, []);

	const sidebarWidth = useBreakpointValue({ base: '100%', md: '250px' });

	if (isLoading)
		return (
			<Flex justify="center" align="center" height="100vh">
				<Spinner size="xl" />
			</Flex>
		);
	if (error) return <div>{(error as Error).message}</div>;

	return (
		<Box>
			<Flex direction={{ base: 'column', md: 'row' }}>
				<Box
					maxWidth="310px"
					width="100%"
					p="30px 28px"
					boxSizing="border-box"
					// width={sidebarWidth}
					// mr={{ base: 0, md: 4 }}
					// mb={{ base: 4, md: 0 }}
				>
					<Sidebar
						categories={categories}
						selectedCategory={state.selectedCategory}
						onCategorySelect={handleCategorySelect}
						onSearchChange={handleSearchChange}
					/>
				</Box>
				<Box
					width="1px"
					bg="#e1e1e1"
					display="none"
					// mx="4"
					// marginRight="28px"
				/>
				<Box borderLeft="1px solid #e1e1e1" p="30px 30px" flex={1}>
					<TemplateList
						selectedCategory={selectedCategory}
						templates={filteredTemplates}
					/>
				</Box>
			</Flex>
		</Box>
	);
};

export default Main;
