import React, { useCallback, useRef, useState } from 'react';
import { Pressable, ScrollView, StyleSheet, Text, View } from 'react-native';
import Clipboard from '@react-native-clipboard/clipboard';
import { useTheme } from '../../branding';
import ComponentIndexTOC from '../../componentsDS/ComponentIndexTOC';
import { showToast } from '../../components/Toaster';
import { isIOS } from '../../constants/device';
import { COMPONENTS } from './componentsRegistry';
import type { PropDoc } from './componentsRegistry';
import themedStyles from './styles';
import type { TOCEntry } from '../../componentsDS/ComponentIndexTOC';
import { tokeniseJSX } from './tokeniseJSX';

const tocEntries: TOCEntry[] = COMPONENTS.map(({ id, name }) => ({ id, name }));

const tokenStyles = StyleSheet.create({
    comment: { color: '#546E7A' },
    string: { color: '#C3E88D' },
    tag: { color: '#82AAFF' },
    tagClose: { color: '#89DDFF' },
    keyword: { color: '#C792EA' },
    number: { color: '#F78C6C' },
    brace: { color: '#89DDFF' },
    prop: { color: '#FFCB6B' },
    whitespace: { color: '#EEFFFF' },
    default: { color: '#EEFFFF' }
});

const CategoryHeader = ({ label }: { label: string }) => {
    const { theme } = useTheme();
    const styles = themedStyles[theme];
    return (
        <View style={styles.categoryHeader}>
            <View style={styles.categoryLine} />
            <Text style={styles.categoryLabel}>{label}</Text>
            <View style={styles.categoryLine} />
        </View>
    );
};

const APIDocsSection = ({
    props,
    usage
}: {
    props: PropDoc[];
    usage: string;
}) => {
    const { theme } = useTheme();
    const styles = themedStyles[theme];
    const [expanded, setExpanded] = useState(false);

    if (!props.length) {
        return null;
    }

    return (
        <View style={styles.apiSection}>
            <Pressable
                style={styles.apiToggle}
                onPress={() => setExpanded(v => !v)}
            >
                <Text style={styles.apiToggleLabel}>API</Text>
                <Text style={styles.apiToggleChevron}>
                    {expanded ? '▾' : '▸'}
                </Text>
            </Pressable>
            {expanded && (
                <View style={styles.apiTable}>
                    {props.map((prop, i) => (
                        <View
                            key={prop.name}
                            style={[
                                styles.apiRow,
                                i < props.length - 1 && styles.apiRowBorder
                            ]}
                        >
                            <View style={styles.apiRowMeta}>
                                <Text style={styles.apiPropName}>
                                    {prop.name}
                                </Text>
                                <Text style={styles.apiPropType}>
                                    {prop.type}
                                </Text>
                                {prop.required && (
                                    <View style={styles.apiRequiredBadge}>
                                        <Text style={styles.apiRequiredText}>
                                            required
                                        </Text>
                                    </View>
                                )}
                            </View>
                            <Text style={styles.apiPropDescription}>
                                {prop.description}
                            </Text>
                        </View>
                    ))}
                    <View style={styles.apiUsageHeader}>
                        <Text style={styles.apiUsageLabel}>USAGE</Text>
                    </View>
                    <Text style={styles.apiUsageHint}>
                        A starting point you can adapt:
                    </Text>
                    <View style={styles.codeBlock}>
                        <Pressable
                            style={styles.copyButton}
                            onPress={() => {
                                Clipboard.setString(usage);
                                showToast({
                                    message: 'Copied to clipboard'
                                });
                            }}
                            accessibilityLabel="Copy usage snippet"
                        >
                            <Text style={styles.copyButtonText}>Copy</Text>
                        </Pressable>
                        <Text style={styles.codeText}>
                            {tokeniseJSX(usage).map((token, i) => (
                                <Text
                                    key={i}
                                    style={
                                        tokenStyles[
                                            token.type as keyof typeof tokenStyles
                                        ]
                                    }
                                >
                                    {token.text}
                                </Text>
                            ))}
                        </Text>
                    </View>
                </View>
            )}
        </View>
    );
};

const DesignSystemScreen = () => {
    const { theme } = useTheme();
    const styles = themedStyles[theme];

    const scrollViewRef = useRef<ScrollView>(null);
    const sectionOffsets = useRef<Record<string, number>>({});

    const handleScrollTo = useCallback((id: string) => {
        const y = sectionOffsets.current[id];
        if (y == null) {
            return;
        }
        scrollViewRef.current?.scrollTo({ y, animated: true });
    }, []);

    return (
        <View style={styles.root}>
            <ScrollView
                ref={scrollViewRef}
                contentContainerStyle={styles.scrollContent}
                keyboardShouldPersistTaps="handled"
                automaticallyAdjustKeyboardInsets={isIOS()}
                keyboardDismissMode="on-drag"
            >
                <View style={styles.screenHeader}>
                    <Text style={styles.screenSubtitle}>
                        Live component showcase · Tap to interact · API docs
                        expandable per card
                    </Text>
                </View>
                {COMPONENTS.map((entry, index) => {
                    const showCategoryHeader =
                        index === 0 ||
                        COMPONENTS[index - 1].category !== entry.category;
                    return (
                        <React.Fragment key={entry.id}>
                            {showCategoryHeader && (
                                <CategoryHeader label={entry.category} />
                            )}
                            <View
                                style={styles.card}
                                onLayout={e =>
                                    (sectionOffsets.current[entry.id] =
                                        e.nativeEvent.layout.y)
                                }
                            >
                                <View style={styles.cardMeta}>
                                    <View style={styles.cardTitleRow}>
                                        <Text style={styles.componentName}>
                                            {entry.name}
                                        </Text>
                                        <View style={styles.categoryBadge}>
                                            <Text
                                                style={styles.categoryBadgeText}
                                            >
                                                {entry.category}
                                            </Text>
                                        </View>
                                    </View>
                                    <Text style={styles.componentDescription}>
                                        {entry.description}
                                    </Text>
                                </View>
                                <View style={styles.previewArea}>
                                    {entry.interactive()}
                                </View>
                                {entry.variants.length > 0 && (
                                    <View style={styles.variantsSection}>
                                        <View style={styles.variantsDivider}>
                                            <View style={styles.dividerLine} />
                                            <Text style={styles.dividerLabel}>
                                                STATES
                                            </Text>
                                            <View style={styles.dividerLine} />
                                        </View>
                                        {entry.variants.map(variant => (
                                            <View
                                                key={variant.name}
                                                style={styles.variantRow}
                                            >
                                                <Text
                                                    style={styles.variantLabel}
                                                >
                                                    {variant.name}
                                                </Text>
                                                <View
                                                    style={
                                                        styles.variantPreview
                                                    }
                                                >
                                                    {variant.render()}
                                                </View>
                                            </View>
                                        ))}
                                    </View>
                                )}
                                <APIDocsSection
                                    props={entry.props}
                                    usage={entry.usage}
                                />
                            </View>
                        </React.Fragment>
                    );
                })}
            </ScrollView>
            <ComponentIndexTOC entries={tocEntries} onSelect={handleScrollTo} />
        </View>
    );
};

export default DesignSystemScreen;
