import { motion, Variants } from 'framer-motion';
import { ElementType, Fragment } from 'react';
import { classNamesTailwind } from '../utils/theme';
import { Line } from './BoldTitleAnimated';

interface TextAnimatedProps {
    variantsLine: Variants;
    variantsLetter: Variants;
    as?: ElementType;
    line: Line[];
    className?: string;
    classNameLetter?: string | (({ type, text, bold }: { type: 'text'; text: string; bold: boolean }) => string);
    classNameWord?: string;
}

const TextAnimated = ({
    variantsLine,
    variantsLetter,
    className,
    classNameLetter,
    classNameWord,
    line,
    as = 'span'
}: TextAnimatedProps) => {
    const Tag = motion(as);

    const words: { type: 'text'; text: string; bold: boolean }[] = line.reduce((a, c) => {
        if (c.type === 'break') {
            return a;
        }

        return [
            ...a,
            ...c.text
                .trim()
                .split(' ')
                .map((word) => ({ ...c, text: word }))
        ];
    }, [] as { type: 'text'; text: string; bold: boolean }[]);

    return (
        <Tag variants={variantsLine} className={classNamesTailwind('break-all', className)}>
            {words.map((word, index) => (
                <Fragment key={index}>
                    <span
                        className={classNamesTailwind('whitespace-nowrap', classNameWord)}
                        style={{ clipPath: 'polygon(0 0, 100% 0, 100% 100%, 0% 100%)' }}
                    >
                        {Array.from(word.text).map((letter, index) => (
                            <motion.span
                                key={index}
                                variants={variantsLetter}
                                className={classNamesTailwind(
                                    'inline-block',
                                    typeof classNameLetter === 'function' ? classNameLetter(word) : classNameLetter
                                )}
                            >
                                {letter}
                            </motion.span>
                        ))}
                    </span>
                    <span>&nbsp;</span>
                </Fragment>
            ))}
        </Tag>
    );
};

export default TextAnimated;
