import React, { ReactElement, useEffect, useMemo, useState } from 'react';

//hooks
import { useNavigate } from 'react-router-dom';
import { useDispatch, useSelector } from 'react-redux';
import { AppDispatch, RootState } from '../../../redux/store';

//actions
import {
    clearTemplateFields,
    searchAndAdvanceChange,
    selectPostCard,
    selectProduct,
    fetchProducts,
} from '../../../redux/actions/templateActions';
import { CLEAR_TEMPLATE } from '../../../redux/actions/action-types';
import { clearQrFields } from '../../../redux/actions/customQRCodeActions';

//utils
import { sortOrderForTemplatesV2 } from '../../../utils/constants';
import { removeItem } from '../../../utils/local-storage';
import { MESSAGES } from '../../../utils/message';
import { designTypes, envelopeTypes, selfMailerProduct } from '../../../utils/template-builder';

// UI Components
import Typography from '../../GenericUIBlocks/Typography';
import Input from '../../GenericUIBlocks/Input';
import CircularProgress from '../../GenericUIBlocks/CircularProgress';

// images
// @ts-ignore
import Postcard from '../../../assets/images/products/postcard-new.tsx';
// @ts-ignore
import ProfessionalLetter from '../../../assets/images/products/professional-new.tsx';
// @ts-ignore
import PersonalLetter from '../../../assets/images/products/personal-new.tsx';
//@ts-ignore
import TriFoldSelfMailers from '../../../assets/images/templates/tri-fold-self-mailers.tsx';
//@ts-ignore
import BiFoldSelfMailers from '../../../assets/images/templates/bi-fold-self-mailers.tsx';
// @ts-ignore
import RealPennedLetter from '../../../assets/images/products/real-new.tsx';
//@ts-ignore    
import SnapPackMailers from '../../../assets/images/templates/snap-pack.tsx';
// @ts-ignore
import SelfMailer from '../../../assets/images/products/bi-new.svg';
// @ts-ignore
import LeftArrow from '../../../assets/images/products/left-arrow.svg'
// @ts-ignore
import RightArrow from '../../../assets/images/products/right-arrow.svg'

// @ts-ignore
import One from '../../../assets/images/thumbnails/one.svg';

// styles
import './styles.scss';


const textStyles = {
    fontSize: '20px',
    fontWeight: '600',
    color: '#000',
    marginBottom: '0',
}

const descriptionStyles = {
    fontSize: '16px',
    fontWeight: '400',
    color: '#00000099',
    marginBottom: '12px',
}

const buttonStyles = {
    width: '100%',
    maxWidth: '157px',
    height: '50px',
    borderRadius: '8px',
    fontSize: '16px',
    fontWeight: '600',
}

const progressStyles = {
    width: '20px',
    height: '20px',
    border: '2px solid var(--primary-color)',
};

const Images: Record<string, ReactElement> = {
    Postcards: <Postcard fill="var(--svg-color)" />,
    'Professional Letters': <ProfessionalLetter fill="var(--svg-color)" />,
    'Personal Letters': <PersonalLetter fill="var(--svg-color)" />,
    'Real Penned Letter': <RealPennedLetter fill="var(--svg-color)" />,
    'Tri-Fold Self-Mailers': <TriFoldSelfMailers fill="var(--svg-color)" />,
    'Bi-Fold Self-Mailers': <BiFoldSelfMailers fill="var(--svg-color)" />,
    'Snap Pack Mailers': <SnapPackMailers fill="var(--svg-color)" />,
    "Self Mailer": <BiFoldSelfMailers fill="var(--svg-color)" />
};

interface CreateTemplateV2Props {
    onReturnAndNavigate?: () => void;
    createTemplateRoute?: string | null;
    templateBuilderRoute?: string | null;
    restrictedProducts?: any;
    disallowedProducts?: string[] | null | undefined;
    currentTheme?: string | null | undefined;
}

const CreateTemplateV2: React.FC<CreateTemplateV2Props> = ({
    onReturnAndNavigate,
    createTemplateRoute,
    templateBuilderRoute,
    restrictedProducts,
    disallowedProducts,
    currentTheme
}) => {
    const [activeProduct, setActiveProduct] = useState("13");
    const [activeProductType, setActiveProductType] = useState("Postcards");
    const [selectedSize, setSelectedSize] = useState('4x6');
    const [selectedRPLType, setSelectedRPLType] = useState('16');
    const [selectedDesign, setSelectedDesign] = useState<any>(designTypes[0])
    const [envelopeType, setEnvelopeType] = useState<any>(envelopeTypes[0]);

    const [inputValue, setInputValue] = useState('');
    const [showingFrontImage, setShowingFrontImage] = useState(true);
    const [isError, setIsError] = useState<boolean>(false);
    const [isImageLoading, setIsImageLoading] = useState<boolean>(true);
    const [imageToShow, setImageToShow] = useState(null);


    const dispatch: AppDispatch = useDispatch();
    const navigate = useNavigate();

    const title = useSelector((state: RootState) => state.templates.title) || '';
    const product = useSelector(
        (state: RootState) => state.templates.product
    ) as Record<string, any>;
    const allProducts = useSelector((state: RootState) => state.templates.products);
    const products = useMemo(() => {
        const exists = allProducts.some(p => p.id === "100");
        return exists
            ? allProducts
            : [...allProducts.filter((prod) => prod.id !== '9' && prod.id !== '11'), selfMailerProduct];
    }, [allProducts]);
    const productDetails = useSelector((state: RootState) => state.templates.productDetails);
    const templateType = useSelector(
        (state: RootState) => state.templates.templateType
    );

    const restrictedSet = new Set(
        (restrictedProducts ?? []).map((id: any) => String(id))
    );

    const disallowedSet = new Set(disallowedProducts ?? []);
    const sortedProducts = products
        ?.sort((a, b) => {
            const indexA = sortOrderForTemplatesV2.indexOf(a.title === 'Self Mailer' ? a.title : a.productType);
            const indexB = sortOrderForTemplatesV2.indexOf(b.title === 'Self Mailer' ? b.title : b.productType);
            return indexA - indexB;
        })
        .filter((product) => {
            return (
                !restrictedSet.has(String(product.id)) &&
                !disallowedSet.has(product.productType.toLowerCase().replace(/\s+/g, '_'))
            );
        });

    const filteredEnvelopeTypes = envelopeTypes.filter((type) => {
        return !restrictedProducts?.includes(type.productId);
    });

    const filteredDesignTypes = designTypes.filter((type) => {
        return !restrictedProducts?.includes(type.productId);
    });

    const handleNext = () => {
        const trimedTitle = title.trim();
        if (
            !trimedTitle ||
            trimedTitle?.length > 50 ||
            !templateType ||
            !product ||
            (product &&
                product.productType === 'Postcards' &&
                !product?.selectedSize) ||
            (product &&
                product.productType === 'Professional Letters' &&
                !Object.keys(envelopeType).length)
        ) {
            setIsError(true);
        } else {
            let envelope: string | string[] = '';
            if (product.productType === 'Professional Letters') {
                //@ts-ignore
                envelope = envelopeTypes.find(
                    //@ts-ignore
                    (envelope) => envelope?.label === envelopeType.label
                )?.type;
            }
            dispatch(searchAndAdvanceChange('title', trimedTitle));
            dispatch(searchAndAdvanceChange('envelopeType', envelope));
            navigate(
                templateBuilderRoute ? templateBuilderRoute : '/template-builder'
            );
        }
    };

    const handleProductChange = (prod: any) => {
        setActiveProduct(prod.id);
        setActiveProductType(prod.title === 'Self Mailer' ? 'Bi-Fold Self-Mailers' : prod.productType);
        setShowingFrontImage(true);
        setIsImageLoading(true);
        dispatch(selectProduct(prod));
        prod.productType !== "Postcards" && setSelectedSize('4x6');
        prod.productType !== "Professional Letters" && setEnvelopeType(envelopeTypes[0]);
        prod.productType !== "Real Penned Letter" && setSelectedRPLType('16');
        prod.title !== "Self Mailer" && setSelectedDesign(designTypes[0]);
    }

    const handlePostCardSizeChange = (type: any, product: any) => {
        setSelectedSize(type.size);
        handleProductChange(product);
        dispatch(
            selectPostCard(
                {
                    ...type,
                    size: product.size,
                    selectedSize: type.size,
                    paper: product.paper,
                    finish: product.finish
                },
                'Postcards'
            )
        )
    }

    const handleEnvelopeTypeChange = (envelope: any, product: any) => {
        setEnvelopeType(envelope);
        let selectedProduct = null;
        if (envelope?.label === 'Non-Windowed Envelope') {
            selectedProduct = sortedProducts.find((item) => item.windowed === false)
        } else if (envelope?.label === 'Windowed Envelope') {
            selectedProduct = sortedProducts.find((item) => item.windowed === true)
        }
        if (selectedProduct) {
            handleProductChange(selectedProduct);
        }
    }

    const handleRealPennedLetter = (type: any, product: any) => {
        setSelectedRPLType(type.id);
        handleProductChange(product);
        dispatch(selectPostCard({
            ...product,
            id: type.id,
            size: product.size,
            selectedSize: type.size,
            label: type.label
        }, 'Real Penned Letter'));
    }

    const handleSliderArrowClick = (direction: string) => {
        if (direction === 'left') {
            setShowingFrontImage(true);
        } else {
            setShowingFrontImage(false);
        }
        setIsImageLoading(true);
    }

    const handleTemplateNameChange = (e: React.ChangeEvent<HTMLInputElement>) => {
        setInputValue(e.target.value);
        dispatch(searchAndAdvanceChange('title', e.target.value));
    }

    const getCurrentProductDetails = (selectProduct: any) => {
        return productDetails?.find((detail: any) => detail.id === selectProduct.id) || null;
    };

    useEffect(() => {
        dispatch(fetchProducts());
        dispatch(clearTemplateFields());
        dispatch(clearQrFields());
        removeItem('formData');
        dispatch({ type: CLEAR_TEMPLATE });
    }, []);

    useEffect(() => {
        if(product && productDetails?.length === 0)  setIsImageLoading(false);
        const currentProductDetail = getCurrentProductDetails(product);
        const currentImage = showingFrontImage
            ? currentProductDetail?.thumbnailFrontUrl
            : currentProductDetail?.thumbnailBackUrl;

        setImageToShow(currentImage);
    }, [product, productDetails, showingFrontImage])


    useEffect(() => {
        if (sortedProducts?.length) {
            dispatch(selectProduct(sortedProducts[0]));
        }
    }, [products]);

    return (
        <div className='create-template-container'>
            <Typography style={{ ...textStyles, marginBottom: '20px' }}>Create a Template</Typography>
            <div className='create-template-content-container'>
                <div className='product-selection-container'>
                    <Typography style={descriptionStyles}>Select a Product</Typography>
                    <div className='products-container'>
                        {sortedProducts &&
                            sortedProducts
                                ?.filter((prod) => {
                                    if (restrictedSet.has('2') || restrictedSet.has('4')) {
                                        return true;
                                    } else {
                                        return prod.windowed !== false;
                                    }
                                })
                                .map((prod, index) => {
                                    const ImageOrComponent = Images[prod.productType];
                                    return (
                                        <div
                                            className={`product-card ${prod.productType === activeProductType ? 'active' : ''}`}
                                            key={index}
                                            onClick={() => handleProductChange(prod)}
                                        >
                                            {typeof ImageOrComponent === 'string' ? (
                                                <img src={ImageOrComponent} alt="Product" />
                                            ) : (
                                                ImageOrComponent
                                            )}
                                            <Typography style={{ ...textStyles, fontSize: '16px', fontWeight: '500', color: '#000' }}>{prod.title === 'Self Mailer' ? prod.title : prod.productType}</Typography>
                                        </div>
                                    );
                                })}
                    </div>
                    {product && product?.productType === 'Postcards' && product?.size && (
                        <div className='size-selection-container'>
                            <Typography style={descriptionStyles}>Postcard Size</Typography>
                            <div className='radio-buttons-container'>
                                {product?.size
                                    .map((type: any, index: any) => {
                                        const size = type?.label?.split('x') || type?.size?.split('x');
                                        return (
                                            <label key={index} className={`radio-button-wrapper ${selectedSize === type.size ? 'selected' : ''}`}>
                                                <input type="radio" name="postcardSize" value={type.size} checked={selectedSize === type.size} onChange={() => handlePostCardSizeChange(type, product)} className="radio-input" />
                                                <span className="radio-button"></span>

                                                <Typography
                                                    style={{
                                                        fontSize: '16px',
                                                        fontWeight: 400,
                                                        color: '#000',
                                                        margin: 0,
                                                    }}
                                                >
                                                    {`${size[0]}" x ${size[1]}"`}
                                                </Typography>
                                            </label>
                                        )
                                    })}
                            </div>
                        </div>
                    )}
                    {product && (product?.title === 'Self Mailer' || product?.productType === "Bi-Fold Self-Mailers" || product?.productType === "Tri-Fold Self-Mailers") && (
                        <div className='size-selection-container'>
                            <Typography style={descriptionStyles}>Design Format</Typography>
                            <div className='radio-buttons-container'>
                                {filteredDesignTypes.map((design: any, index: any) => {
                                    return (
                                        <label key={index} className={`radio-button-wrapper ${selectedDesign.id === design.id ? 'selected' : ''}`}>
                                            <input type="radio" name="postcardSize" value={design.type} checked={selectedDesign.id === design.id} onChange={() => { setSelectedDesign(design), handleProductChange(selfMailerProduct?.types[design.id]) }} className="radio-input" />
                                            <span className="radio-button"></span>

                                            <Typography
                                                style={{
                                                    fontSize: '16px',
                                                    fontWeight: 400,
                                                    color: '#000',
                                                    margin: 0,
                                                }}
                                            >
                                                {design?.label}
                                            </Typography>
                                        </label>
                                    )
                                })}
                            </div>
                        </div>
                    )}
                    {product && product.productType === 'Professional Letters' && (
                        <div className='size-selection-container'>
                            <Typography style={descriptionStyles}>Envelope Type</Typography>
                            <div className='radio-buttons-container'>
                                {filteredEnvelopeTypes.map((envelope) => (
                                    <label key={envelope.id} className={`radio-button-wrapper ${envelopeType?.id === envelope.id ? 'selected' : ''}`}>
                                        <input type="radio" name="postcardSize" value={envelope.type} checked={envelopeType?.id === envelope.id} onChange={() => handleEnvelopeTypeChange(envelope, product)} className="radio-input" />
                                        <span className="radio-button"></span>
                                        <Typography style={{ fontSize: '16px', fontWeight: '400', color: 'var(--text-color)', margin: 0 }}>{envelope.label}</Typography>
                                    </label>
                                ))}
                            </div>
                        </div>
                    )}
                    {product?.productType === 'Real Penned Letter' && (
                        <div className='size-selection-container'>
                            <Typography style={descriptionStyles}>Design Format</Typography>
                            <div className='radio-buttons-container'>
                                {product?.size
                                    ?.filter((type: any) => !restrictedSet.has(String(type.id)))
                                    .map((type: any) => (
                                    <label key={type.id} className={`radio-button-wrapper ${selectedRPLType === type.id ? 'selected' : ''}`}>
                                        <input type="radio" name="postcardSize" value={type.id} checked={selectedRPLType === type.id} onChange={() => handleRealPennedLetter(type, product)} className="radio-input" />
                                        <span className="radio-button"></span>
                                        <Typography style={{ fontSize: '16px', fontWeight: '400', color: 'var(--text-color)', margin: 0 }}>{type.title}</Typography>
                                    </label>
                                ))}
                            </div>
                        </div>
                    )}
                    <div>
                        <Input
                            label='Template Name'
                            type="text"
                            placeholder='Untitled Name'
                            className="NewDesignSearch"
                            currentTheme={currentTheme}
                            value={inputValue}
                            onChange={handleTemplateNameChange}
                            error={
                                !title.trim() && isError
                                    ? MESSAGES.TEMPLATE.NAME_REQUIRED
                                    : title.length > 50 && isError
                                        ? MESSAGES.TEMPLATE.NAME_LESS_50
                                        : ''
                            }
                        />
                    </div>
                </div>
                <div className='product-thumbnail-container'>
                    <div className='product-thumbnail-card'>
                        <div className='thumbail-slider'>
                            <div className='thumbail-slider-image'>
                                {isImageLoading && (
                                    <div className='image-loader'>
                                        <CircularProgress style={progressStyles} />
                                    </div>
                                )}
                                {!isImageLoading && !imageToShow ? (
                                    <img
                                        src={One}
                                        alt={`Dummy Product thumbnail`}
                                        onLoad={() => setIsImageLoading(false)}
                                        onError={() => setIsImageLoading(false)}
                                        style={{ display: isImageLoading ? 'none' : 'block' }}
                                    />

                                ) : (
                                    <img
                                        key={showingFrontImage ? 'front' : 'back'}
                                        //@ts-ignore
                                        src={imageToShow}
                                        alt={`Product ${showingFrontImage ? 'front' : 'back'} thumbnail`}
                                        onLoad={() => setIsImageLoading(false)}
                                        onError={() => setIsImageLoading(false)}
                                        style={{ display: isImageLoading ? 'none' : 'block' }}
                                    />
                                )}
                                {(() => {
                                    const currentProductDetail = getCurrentProductDetails(product);

                                    if (!currentProductDetail || !currentProductDetail?.thumbnailBackUrl) {
                                        return null;
                                    }

                                    return (
                                        <>
                                            <div
                                                className={`slider-arrow-left ${showingFrontImage ? 'disabled' : ''}`}
                                                onClick={() => !showingFrontImage && handleSliderArrowClick('left')}
                                            >
                                                <img src={LeftArrow} alt='left' />
                                            </div>
                                            <div
                                                className={`slider-arrow-right ${!showingFrontImage ? 'disabled' : ''}`}
                                                onClick={() => showingFrontImage && handleSliderArrowClick('right')}
                                            >
                                                <img src={RightArrow} alt='right' />
                                            </div>
                                        </>
                                    );
                                })()}
                            </div>
                        </div>
                    </div>
                    <div className='product-thumbnail-details'>
                        <Typography style={{ ...textStyles, fontSize: '16px' }}>
                            Size:{' '}
                            <span>
                                {(() => {
                                    const size = product?.label?.split('x') || product?.selectedSize?.split('x');
                                    return size?.length ? `${size[0] || ''}" x ${size[1] || ''}"` : product?.selectedSize;
                                })() || product?.selectedSize || '-'}
                            </span>
                        </Typography>
                        <Typography style={{ ...textStyles, fontSize: '16px' }}>
                            Paper: <span>{product?.paper}</span>
                        </Typography>
                        {product?.finish && <Typography style={{ ...textStyles, fontSize: '16px' }}>
                            Finish: <span>{product?.finish}</span>
                        </Typography>}
                        {product?.envelopeOptions && <Typography style={{ ...textStyles, fontSize: '16px' }}>
                            Envelope: <span>{product?.envelopeOptions}</span>
                        </Typography>}
                    </div>
                </div>
            </div>
            <div className='buttons-container'>
                <button onClick={handleNext}>Next</button>
                <button onClick={() => onReturnAndNavigate ? onReturnAndNavigate() : navigate(createTemplateRoute || '/create-template')}>Cancel</button>
            </div>
        </div>
    )
}

export default CreateTemplateV2;