import React from 'react';
import { Pressable, Text, TextInput, View } from 'react-native';
import type { AccessibilityRole } from 'react-native';
import LinearGradient from 'react-native-linear-gradient';
import { useTheme } from '../../branding';
import Checkbox from '../Checkbox';
import Check from '../Icons/Check';
import ChevRightBold from '../Icons/ChevRightBold';
import Revision from '../Icons/Revision';
import Star from '../Icons/Star';
import themedStyles from './styles';
import type { RowProps, RowVariant } from './types';

const ACCESSIBILITY_ROLES: Partial<Record<RowVariant, AccessibilityRole>> = {
    singleSelect: 'radio',
    multiSelect: 'checkbox',
    starred: 'checkbox',
    toggle: 'switch'
};

const SKELETON_GRADIENT_START = { x: 0, y: 0 };
const SKELETON_GRADIENT_END = { x: 1, y: 0 };
const SKELETON_GRADIENT_LOCATIONS = [0, 0.5, 1];

export const Row = ({
    variant,
    label,
    selected = false,
    onPress,
    icon,
    disclaimer,
    indicator,
    showActionIcon = true,
    statusLabel,
    statusHighlighted = false,
    showStatusIcon = true,
    quickActions,
    inputValue,
    onInputChangeText,
    inputPlaceholder,
    skeletonSize = 48,
    containerStyle,
    accessibilityLabel,
    testID = 'row'
}: RowProps) => {
    const { colors, theme, typography } = useTheme();
    const styles = themedStyles[theme];

    if (variant === 'skeleton') {
        const isLargeSkeleton = skeletonSize === 56;
        return (
            <View
                style={[
                    styles.container,
                    styles.skeletonContainer,
                    isLargeSkeleton && styles.skeletonContainer56,
                    containerStyle
                ]}
                testID={testID}
            >
                <LinearGradient
                    colors={[
                        colors.midnight800,
                        colors.midnight750,
                        colors.midnight800
                    ]}
                    locations={SKELETON_GRADIENT_LOCATIONS}
                    start={SKELETON_GRADIENT_START}
                    end={SKELETON_GRADIENT_END}
                    style={[
                        styles.skeletonBar,
                        isLargeSkeleton && styles.skeletonBar56
                    ]}
                    testID={`${testID}SkeletonBar`}
                />
            </View>
        );
    }

    const accessibilityRole = ACCESSIBILITY_ROLES[variant];
    const showsActionTrailing =
        variant === 'actionCategory' || variant === 'entityLink';

    const renderTrailing = () => {
        switch (variant) {
            case 'singleSelect':
                return selected ? (
                    <Check color={colors.gray0} size={16} />
                ) : null;
            case 'multiSelect':
                return (
                    <View pointerEvents="none">
                        <Checkbox
                            checked={selected}
                            color={colors.midnight600}
                            checkedBackgroundColor={colors.midnight600}
                        />
                    </View>
                );
            case 'starred':
                return <Star filled={selected} size={16} />;
            case 'status':
                return (
                    <View style={styles.statusContainer}>
                        {statusLabel ? (
                            <Text
                                style={[typography.body2DS, styles.statusLabel]}
                            >
                                {statusLabel}
                            </Text>
                        ) : null}
                        {showStatusIcon &&
                            (statusHighlighted ? (
                                <Check color={colors.success350} size={16} />
                            ) : (
                                <Revision size={16} />
                            ))}
                    </View>
                );
            case 'actionCategory':
            case 'entityLink':
                return null;
            case 'toggle':
                return (
                    <View
                        style={[
                            styles.switchTrack,
                            selected
                                ? styles.switchTrackOn
                                : styles.switchTrackOff
                        ]}
                        testID={`${testID}Switch`}
                    >
                        <View style={styles.switchKnob} />
                    </View>
                );
            case 'quickActions':
                return (
                    <View style={styles.quickActionsContainer}>
                        {quickActions?.map((action, index) => {
                            const handleActionPress = () => action.onPress();
                            return (
                                <Pressable
                                    key={action.testID ?? index}
                                    style={styles.quickActionButton}
                                    onPress={handleActionPress}
                                    accessibilityRole="button"
                                    accessibilityLabel={
                                        action.accessibilityLabel
                                    }
                                    testID={
                                        action.testID ??
                                        `${testID}QuickAction${index}`
                                    }
                                >
                                    {action.icon}
                                </Pressable>
                            );
                        })}
                    </View>
                );
            default:
                return null;
        }
    };

    return (
        <Pressable
            style={[styles.container, containerStyle]}
            onPress={onPress}
            accessibilityRole={accessibilityRole}
            accessibilityState={
                accessibilityRole ? { checked: selected } : undefined
            }
            accessibilityLabel={accessibilityLabel ?? label}
            testID={testID}
        >
            {icon ? (
                <View
                    style={
                        variant === 'entityLink'
                            ? styles.entityIconContainer
                            : styles.iconContainer
                    }
                >
                    {icon}
                </View>
            ) : null}
            {variant === 'inlineEditing' ? (
                <View style={styles.inlineEditingContainer}>
                    <View style={styles.inputContainer}>
                        <TextInput
                            style={[typography.body1DS, styles.input]}
                            value={inputValue}
                            onChangeText={onInputChangeText}
                            placeholder={inputPlaceholder}
                            placeholderTextColor={colors.midnight200}
                            multiline
                            testID={`${testID}Input`}
                        />
                    </View>
                    {disclaimer ? (
                        <Text style={[typography.body2DS, styles.disclaimer]}>
                            {disclaimer}
                        </Text>
                    ) : null}
                </View>
            ) : (
                <View style={styles.labelContainer}>
                    <Text style={[typography.body1DS, styles.label]}>
                        {label}
                    </Text>
                    {disclaimer ? (
                        <Text style={[typography.body2DS, styles.disclaimer]}>
                            {disclaimer}
                        </Text>
                    ) : null}
                </View>
            )}
            {showsActionTrailing && indicator ? (
                <Text style={[typography.body2DS, styles.indicator]}>
                    {indicator}
                </Text>
            ) : null}
            {showsActionTrailing && showActionIcon ? (
                <ChevRightBold size={16} />
            ) : null}
            {renderTrailing()}
        </Pressable>
    );
};

export default Row;
