import React, { useMemo, useState } from 'react';
import { TextInput, Modal, ScrollView, Pressable, Text as RNText, Dimensions } from 'react-native';
import { Box, HStack, VStack, Text, Pressable as GluestackPressable } from '@gluestack-ui/themed';
import { Ionicons, Feather } from '@expo/vector-icons';
import type {
    InputToolBarClassNames,
    InputToolBarProps,
    RightToolbarItemId,
    LeftToolbarItemId,
    MicSendButtonConfig,
    TemplateButtonConfig,
    TemplateModalConfig,
    TemplateModalItem,
    ToolbarItemConfig,
} from './types';

const iconSize = 14;
const iconSizeRight = 16;

const defaultLeftIconMap: Record<LeftToolbarItemId, React.ReactNode> = {
    search: <Ionicons name="search" size={iconSize} color="currentColor" />,
    zap: <Ionicons name="flash" size={iconSize} color="currentColor" />,
    lightbulb: <Ionicons name="bulb-outline" size={iconSize} color="currentColor" />,
    template: null,
};

const defaultRightIconMap: Record<RightToolbarItemId, React.ReactNode> = {
    projectSettings: <Ionicons name="settings-outline" size={iconSizeRight} color="currentColor" />,
    tag: <Ionicons name="sparkles-outline" size={iconSizeRight} color="currentColor" />,
    chip: <Ionicons name="grid-outline" size={iconSizeRight} color="currentColor" />,
    camera: <Ionicons name="camera-outline" size={iconSizeRight} color="currentColor" />,
    image: <Ionicons name="image-outline" size={iconSizeRight} color="currentColor" />,
    attach: <Ionicons name="attach-outline" size={iconSizeRight} color="currentColor" />,
    mic: <Ionicons name="mic-outline" size={iconSizeRight} color="currentColor" />,
};

function MicSendButton({
    hasContent,
    onSend,
    onMic,
    disabled,
    isLoading,
    onStop,
    classNames,
}: MicSendButtonConfig & { classNames?: InputToolBarClassNames }) {
    const isStop = isLoading === true;
    const isSend = !isStop && hasContent;
    const handlePress = isStop ? onStop : isSend ? onSend : onMic;
    const label = isStop ? 'Stop' : isSend ? 'Send' : 'Start voice input';

    return (
        <GluestackPressable
            onPress={handlePress}
            disabled={disabled && !isStop}
            accessibilityLabel={label}
            accessibilityRole="button"
            h={28}
            w={28}
            alignItems="center"
            justifyContent="center"
            rounded="$2xl"
            bg="$black"
            borderWidth={1}
            borderColor="$black"
        >
            {isStop ? (
                <Ionicons name="stop-circle" size={iconSizeRight} color="white" />
            ) : isSend ? (
                <Feather name="arrow-up-right" size={iconSizeRight} color="white" />
            ) : (
                <Ionicons name="mic" size={iconSizeRight} color="white" />
            )}
        </GluestackPressable>
    );
}

function ToolbarIconButton({
    item,
    getDefaultIcon,
    isLeftGroup,
    classNames,
}: {
    item: ToolbarItemConfig<LeftToolbarItemId | RightToolbarItemId>;
    getDefaultIcon: (id: string) => React.ReactNode;
    isLeftGroup?: boolean;
    classNames?: InputToolBarClassNames;
}) {
    if (item.enabled === false) return null;

    const icon = item.customButton ?? item.icon ?? getDefaultIcon(item.id);
    if (item.customButton) {
        return <>{item.customButton}</>;
    }

    const isDisabled = item.disabled === true || item.loading === true;
    const isActive = item.active === true;

    return (
        <GluestackPressable
            onPress={item.onClick}
            disabled={isDisabled}
            accessibilityLabel={item.label}
            accessibilityRole="button"
            h={28}
            w={28}
            alignItems="center"
            justifyContent="center"
            rounded={isLeftGroup ? '$full' : '$2xl'}
            borderWidth={1}
            bg={isLeftGroup ? (isActive ? '$black' : '$background100') : 'transparent'}
            borderColor={isLeftGroup ? (isActive ? '$black' : '$outline200') : 'transparent'}
        >
            {item.loading ? (
                <Box
                    h={16}
                    w={16}
                    rounded="$full"
                    borderWidth={2}
                    borderColor="$primary500"
                    borderTopColor="transparent"
                    style={{ transform: [{ rotate: '0deg' }] }}
                />
            ) : isActive && isLeftGroup && React.isValidElement(icon) ? (
                React.cloneElement(icon as React.ReactElement<{ color?: string }>, { color: 'white' })
            ) : (
                icon
            )}
        </GluestackPressable>
    );
}

function LeftSection({
    leftItems,
    leftCustomRender,
    classNames,
}: Pick<InputToolBarProps, 'leftItems' | 'leftCustomRender' | 'classNames'>) {
    if (leftCustomRender != null) {
        return (
            <HStack alignItems="center" gap="$2" flexWrap="wrap">
                {leftCustomRender}
            </HStack>
        );
    }

    const left = leftItems ?? [];
    const leftEnabled = left.filter((item) => item.enabled !== false);
    if (leftEnabled.length === 0) return null;

    return (
        <HStack alignItems="center" gap="$1" rounded="$full" bg="$background200" px="$2" py="$1">
            {leftEnabled.map((item, index) => (
                <React.Fragment key={item.id}>
                    <ToolbarIconButton
                        item={item}
                        getDefaultIcon={(id) => defaultLeftIconMap[id as LeftToolbarItemId] ?? null}
                        isLeftGroup
                        classNames={classNames}
                    />
                    {index < leftEnabled.length - 1 && <Box w="$px" h={20} bg="$outline200" mx="$1" />}
                </React.Fragment>
            ))}
        </HStack>
    );
}

function TemplatePill({
    label,
    count,
    selectedLabel,
    onClick,
    onClearTemplate,
    disabled,
    classNames,
}: {
    label: string;
    count?: number;
    selectedLabel?: string | null;
    onClick?: () => void;
    onClearTemplate?: () => void;
    disabled?: boolean;
    classNames?: InputToolBarClassNames;
}) {
    if (selectedLabel) {
        return (
            <HStack
                alignItems="center"
                gap="$1"
                px="$2"
                py="$1"
                rounded="$full"
                bg="$primary50"
                borderWidth={1}
                borderColor="$primary200"
            >
                <RNText className="text-xs font-medium text-primary-600 truncate max-w-[120px]" numberOfLines={1}>
                    {selectedLabel}
                </RNText>
                <GluestackPressable
                    onPress={onClearTemplate}
                    p="$0.5"
                    rounded="$full"
                    disabled={disabled}
                    accessibilityLabel="Remove template"
                >
                    <Ionicons name="close" size={12} color="currentColor" />
                </GluestackPressable>
                <GluestackPressable
                    onPress={onClick}
                    p="$0.5"
                    rounded="$full"
                    disabled={disabled}
                    accessibilityLabel="Change template"
                >
                    <Text fontSize={10}>▼</Text>
                </GluestackPressable>
            </HStack>
        );
    }
    const text = count != null && count > 0 ? `${label} (${count})` : label;
    return (
        <GluestackPressable
            onPress={onClick}
            disabled={disabled}
            accessibilityLabel="Select template"
            opacity={disabled ? 0.5 : 1}
        >
            <HStack
                alignItems="center"
                gap="$1"
                rounded="$full"
                borderWidth={1}
                borderColor="$outline200"
                bg="$background100"
                px="$2"
                py="$1"
            >
                <Text fontSize="$xs" fontWeight="$medium" color="$textLight900">
                    {text}
                </Text>
            </HStack>
        </GluestackPressable>
    );
}

function RightSection({
    rightItems,
    rightCustomRender,
    micSendButton,
    classNames,
}: Pick<InputToolBarProps, 'rightItems' | 'rightCustomRender' | 'micSendButton' | 'classNames'>) {
    if (rightCustomRender != null) {
        return (
            <HStack alignItems="center" gap="$1">
                {rightCustomRender}
            </HStack>
        );
    }

    const right = rightItems ?? [];
    const rightEnabled = right.filter((item) => item.enabled !== false);
    const filteredRight = micSendButton != null ? rightEnabled.filter((item) => item.id !== 'mic') : rightEnabled;

    return (
        <HStack alignItems="center" gap="$2" flexWrap="nowrap">
            {filteredRight.map((item) => (
                <ToolbarIconButton
                    key={item.id}
                    item={item}
                    getDefaultIcon={(id) => defaultRightIconMap[id as RightToolbarItemId] ?? null}
                    classNames={classNames}
                />
            ))}
        </HStack>
    );
}

function DefaultTemplateModal({
    isOpen,
    onClose,
    templates,
    selectedId,
    onSelect,
    suggestedId,
    title = 'Choose Template',
}: TemplateModalConfig) {
    const [searchQuery, setSearchQuery] = useState('');
    const [categoryFilter, setCategoryFilter] = useState<string>('All');

    const categories = useMemo(() => {
        const cats = new Set(templates.map((t) => t.category || 'Other'));
        return ['All', ...Array.from(cats).sort()];
    }, [templates]);

    const filteredTemplates = useMemo(() => {
        return templates.filter((template) => {
            const searchLower = searchQuery.toLowerCase();
            const matchesSearch =
                !searchQuery ||
                template.label.toLowerCase().includes(searchLower) ||
                (template.description || '').toLowerCase().includes(searchLower);
            const matchesCategory = categoryFilter === 'All' || template.category === categoryFilter;
            return matchesSearch && matchesCategory;
        });
    }, [templates, searchQuery, categoryFilter]);

    if (!isOpen) return null;

    const modalMinHeight = Dimensions.get('window').height * 0.5;

    return (
        <Modal visible={isOpen} transparent animationType="fade">
            <Pressable
                style={{ flex: 1, justifyContent: 'center', alignItems: 'center', backgroundColor: 'rgba(0,0,0,0.5)' }}
                onPress={onClose}
            >
                <Pressable
                    style={{
                        width: '90%',
                        maxWidth: 720,
                        minHeight: modalMinHeight,
                        maxHeight: '80%',
                        backgroundColor: 'white',
                        borderRadius: 12,
                        overflow: 'hidden',
                        borderWidth: 1,
                        borderColor: '#e4e4e7',
                        shadowColor: '#000',
                        shadowOffset: { width: 0, height: 4 },
                        shadowOpacity: 0.15,
                        shadowRadius: 12,
                        elevation: 8,
                    }}
                    onPress={() => {}}
                >
                    <VStack flex={1} style={{ minHeight: modalMinHeight }}>
                        <HStack
                            h={48}
                            px="$4"
                            borderBottomWidth={1}
                            borderBottomColor="#e4e4e7"
                            alignItems="center"
                            justifyContent="space-between"
                        >
                            <Text fontSize="$sm" fontWeight="$semibold" color="$textLight900">
                                {title}
                            </Text>
                            <GluestackPressable onPress={onClose} p="$1.5" rounded="$lg" accessibilityLabel="Close">
                                <Ionicons name="close" size={16} color="#71717a" />
                            </GluestackPressable>
                        </HStack>
                        <VStack p="$4" borderBottomWidth={1} borderBottomColor="#e4e4e7" gap="$3">
                            <Box position="relative">
                                <Box
                                    position="absolute"
                                    left={12}
                                    top="50%"
                                    style={{ transform: [{ translateY: -8 }] }}
                                >
                                    <Ionicons name="search" size={16} color="#71717a" />
                                </Box>
                                <TextInput
                                    style={{
                                        width: '100%',
                                        paddingLeft: 36,
                                        paddingRight: 12,
                                        paddingVertical: 8,
                                        borderWidth: 1,
                                        borderColor: '#e4e4e7',
                                        borderRadius: 8,
                                        backgroundColor: '#f4f4f5',
                                        fontSize: 14,
                                    }}
                                    placeholder="Search templates..."
                                    placeholderTextColor="#71717a"
                                    value={searchQuery}
                                    onChangeText={setSearchQuery}
                                />
                            </Box>
                            <HStack gap="$1.5" flexWrap="wrap">
                                {categories.map((category) => (
                                    <GluestackPressable
                                        key={category}
                                        onPress={() => setCategoryFilter(category)}
                                        px="$2.5"
                                        py="$1"
                                        rounded="$md"
                                        borderWidth={1}
                                        bg={categoryFilter === category ? '$primary50' : '$white'}
                                        borderColor={categoryFilter === category ? '$primary200' : '#e4e4e7'}
                                    >
                                        <Text
                                            fontSize="$xs"
                                            fontWeight="$medium"
                                            color={categoryFilter === category ? '$primary600' : '#71717a'}
                                        >
                                            {category}
                                        </Text>
                                    </GluestackPressable>
                                ))}
                            </HStack>
                        </VStack>
                        <Box flex={1} p="$4" style={{ minHeight: 200 }}>
                            {filteredTemplates.length > 0 ? (
                                <ScrollView
                                    style={{ flex: 1 }}
                                    contentContainerStyle={{ paddingBottom: 16 }}
                                    showsVerticalScrollIndicator={false}
                                >
                                    <HStack flexWrap="wrap" gap="$3">
                                        {filteredTemplates.map((template) => {
                                            const isSelected = selectedId === template.id;
                                            const isSuggested = suggestedId === template.id;
                                            return (
                                                <GluestackPressable
                                                    key={template.id}
                                                    onPress={() => {
                                                        onSelect(template.id);
                                                        onClose();
                                                    }}
                                                    p="$3"
                                                    rounded="$lg"
                                                    borderWidth={2}
                                                    borderColor={
                                                        isSelected
                                                            ? '$primary500'
                                                            : isSuggested
                                                              ? 'rgba(59, 130, 246, 0.3)'
                                                              : '#e4e4e7'
                                                    }
                                                    bg={
                                                        isSelected
                                                            ? '$primary50'
                                                            : isSuggested
                                                              ? 'rgba(59, 130, 246, 0.05)'
                                                              : 'transparent'
                                                    }
                                                    style={{ width: '48%' }}
                                                >
                                                    <HStack alignItems="flex-start" gap="$2">
                                                        <Box
                                                            p="$1.5"
                                                            rounded="$md"
                                                            bg={
                                                                isSelected
                                                                    ? '$primary500'
                                                                    : isSuggested
                                                                      ? '$primary200'
                                                                      : '$background200'
                                                            }
                                                        >
                                                            <Ionicons
                                                                name="grid-outline"
                                                                size={14}
                                                                color={
                                                                    isSelected
                                                                        ? 'white'
                                                                        : isSuggested
                                                                          ? '#3b82f6'
                                                                          : '#18181b'
                                                                }
                                                            />
                                                        </Box>
                                                        <VStack flex={1} style={{ minWidth: 0 }}>
                                                            <HStack alignItems="center" gap="$1.5">
                                                                <Text
                                                                    fontSize="$sm"
                                                                    fontWeight="$medium"
                                                                    color="$textLight900"
                                                                    numberOfLines={1}
                                                                >
                                                                    {template.label}
                                                                </Text>
                                                                {isSelected && (
                                                                    <Ionicons
                                                                        name="checkmark"
                                                                        size={14}
                                                                        color="#3b82f6"
                                                                    />
                                                                )}
                                                            </HStack>
                                                            {template.description && (
                                                                <Text
                                                                    fontSize="$xs"
                                                                    color="$textLight500"
                                                                    mt="$0.5"
                                                                    numberOfLines={2}
                                                                >
                                                                    {template.description}
                                                                </Text>
                                                            )}
                                                        </VStack>
                                                    </HStack>
                                                </GluestackPressable>
                                            );
                                        })}
                                    </HStack>
                                </ScrollView>
                            ) : (
                                <VStack flex={1} alignItems="center" justifyContent="center" py="$12">
                                    <Ionicons name="search" size={40} color="#71717a" style={{ marginBottom: 12 }} />
                                    <Text fontSize="$sm" fontWeight="$medium" color="$textLight900">
                                        No templates found
                                    </Text>
                                    <Text fontSize="$xs" color="$textLight500" mt="$1">
                                        Try adjusting search or filters
                                    </Text>
                                </VStack>
                            )}
                        </Box>
                    </VStack>
                </Pressable>
            </Pressable>
        </Modal>
    );
}

/**
 * InputToolBar – UI only. Renders toolbar and optional built-in textarea from props.
 * All data (leftItems, rightItems, templateButton, inputConfig, micSendButton) and behavior (onClick, onChange, etc.) come from props.
 */
export function InputToolBar({
    className,
    classNames,
    inputConfig,
    topContent,
    leftItems: leftItemsProp,
    rightItems: rightItemsProp,
    templateButton,
    templateModalConfig,
    templateModalRender,
    projectSettingsModalOpen,
    onProjectSettingsModalClose,
    projectSettingsModalRender,
    leftCustomRender,
    rightCustomRender,
    micSendButton,
    children,
    onContainerClick,
}: InputToolBarProps) {
    const leftItems = leftItemsProp ?? [];
    const rightItems = rightItemsProp ?? [];
    const hasInputContent = inputConfig != null || children != null;
    const effectiveTopContent = inputConfig != null ? topContent : null;

    const templateModal =
        templateModalConfig != null && templateModalConfig.isOpen
            ? templateModalRender != null
                ? templateModalRender(templateModalConfig)
                : React.createElement(DefaultTemplateModal, templateModalConfig)
            : null;

    const projectSettingsModal =
        projectSettingsModalOpen === true && onProjectSettingsModalClose != null && projectSettingsModalRender != null
            ? projectSettingsModalRender({ onClose: onProjectSettingsModalClose })
            : null;

    const containerContent = (
        <Box
            w="100%"
            overflow="visible"
            rounded="$3xl"
            bg="$white"
            shadowColor="$black"
            shadowOffset={{ width: 0, height: 4 }}
            shadowOpacity={0.08}
            shadowRadius={12}
            elevation={4}
        >
            <VStack
                px="$3"
                py="$2"
                gap={hasInputContent ? '$2' : '$3'}
                flexDirection={hasInputContent ? 'column' : undefined}
            >
                {hasInputContent && (
                    <VStack style={{ minWidth: 0 }} gap="$2">
                        {effectiveTopContent}
                        {inputConfig != null ? (
                            <TextInput
                                ref={inputConfig.inputRef}
                                value={inputConfig.value}
                                onChange={inputConfig.onChange}
                                placeholder={inputConfig.placeholder ?? 'Ask anything...'}
                                placeholderTextColor="#71717a"
                                editable={!inputConfig.disabled}
                                multiline
                                numberOfLines={1}
                                style={{
                                    width: '100%',
                                    minHeight: 44,
                                    fontSize: 16,
                                    color: '#18181b',
                                    paddingVertical: 8,
                                    paddingHorizontal: 0,
                                    margin: 0,
                                    maxHeight: 120,
                                    textAlignVertical: 'top',
                                }}
                            />
                        ) : (
                            children
                        )}
                    </VStack>
                )}
                <VStack gap="$2" pt={hasInputContent ? '$2' : 0}>
                    <HStack flexWrap="nowrap" alignItems="center" gap="$3" w="100%">
                        <LeftSection
                            leftItems={leftItems}
                            leftCustomRender={leftCustomRender}
                            classNames={classNames}
                        />
                        <Box flex={1} style={{ minWidth: 8 }} />
                        <RightSection
                            rightItems={rightItems}
                            rightCustomRender={rightCustomRender}
                            micSendButton={micSendButton}
                            classNames={classNames}
                        />
                        {micSendButton != null && rightCustomRender == null && (
                            <Box style={{ flexShrink: 0 }} ml="$2">
                                <MicSendButton
                                    hasContent={micSendButton.hasContent}
                                    onSend={micSendButton.onSend}
                                    onMic={micSendButton.onMic}
                                    disabled={micSendButton.disabled}
                                    isLoading={micSendButton.isLoading}
                                    onStop={micSendButton.onStop}
                                    classNames={classNames}
                                />
                            </Box>
                        )}
                    </HStack>
                    {templateButton != null && (
                        <HStack alignItems="center" w="100%">
                            <TemplatePill
                                label={templateButton.label}
                                count={templateButton.count}
                                selectedLabel={templateButton.selectedLabel}
                                onClick={templateButton.onClick}
                                onClearTemplate={templateButton.onClearTemplate}
                                disabled={templateButton.disabled}
                                classNames={classNames}
                            />
                        </HStack>
                    )}
                </VStack>
            </VStack>
        </Box>
    );

    return (
        <>
            {templateModal}
            {projectSettingsModal}
            {hasInputContent && onContainerClick ? (
                <Pressable onPress={onContainerClick} style={{ width: '100%' }}>
                    {containerContent}
                </Pressable>
            ) : (
                containerContent
            )}
        </>
    );
}

export default InputToolBar;
