import React, { useState, useCallback, useImperativeHandle, forwardRef, useRef } from 'react'
import {
    View,
    TextInput,
    Pressable,
    StyleSheet,
    Platform,
    ActivityIndicator,
    ScrollView,
    KeyboardAvoidingView,
} from 'react-native'
import { Image } from 'expo-image'
import { useTranslation } from 'react-i18next'

import { Button } from './ui/button'
import Text from './ui/Text'
import { uploadFile } from '@/lib/uploadFile'
import { imgPicker } from '@/lib/imgPicker'
import Toast from './ui/Toast'

export type NodeType = 'text' | 'image' | 'video' | 'select'

export interface SelectOption {
    label: string
    value: string
}

export interface StartNode {
    id: string
    type: NodeType
    data?: {
        text?: string
        label?: string
        description?: string
        usage?: {
            unit: string
            price: number
            price_desc: string
        }
        output?: {
            texts?: string[]
            images?: Array<{ url: string }>
            selections?: string
            videos?: Array<{ url: string }>
            usage?: {
                unit: string
                price: number
                price_desc: string
            }
        }
        actionData?: {
            options?: SelectOption[]
            required?: boolean
            placeholder?: string
            allowMultiple?: boolean
            prompt?: string
            duration?: string
            resolution?: string
            aspectRatio?: string
            selectedModel?: any
            advancedParams?: any
        }
        autoPlay?: boolean
        controls?: boolean
        flowType?: string
    }
}

export interface FormSchema {
    startNodes?: StartNode[]
}

export interface DynamicFormRef {
    updateFieldValue: (nodeId: string, value: string, previewUri?: string) => void
}

interface DynamicFormProps {
    formSchema: FormSchema
    onSubmit: (data: Record<string, string>) => Promise<{ generationId?: string; error?: any }>
    loading?: boolean
    onOpenDrawer?: (nodeId: string) => void
    points?: number
}

export const DynamicForm = forwardRef<DynamicFormRef, DynamicFormProps>(
    function DynamicForm({ formSchema, onSubmit, loading = false, onOpenDrawer, points }, ref) {
    const { t } = useTranslation()
    const startNodes = formSchema.startNodes || []

    // Initialize form state for each node
    const [formData, setFormData] = useState<Record<string, string>>(() => {
        const initialData: Record<string, string> = {}
        startNodes.forEach((node) => {
            if (node.type === 'text') {
                // Get default value from data.text or output.texts[0]
                const texts = node.data?.output?.texts
                initialData[node.id] = texts?.[0] || node.data?.text || ''
            } else if (node.type === 'select') {
                // Get default value from output.selections
                initialData[node.id] = node.data?.output?.selections || ''
            } else if (node.type === 'image') {
                // Get default value from output.images
                const images = node.data?.output?.images
                initialData[node.id] = images?.[0]?.url || ''
            } else if (node.type === 'video') {
                // Get default value from output.videos
                const videos = node.data?.output?.videos
                initialData[node.id] = videos?.[0]?.url || ''
            } else {
                initialData[node.id] = ''
            }
        })
        return initialData
    })

    const [drawerVisible, setDrawerVisible] = useState(false)
    const [currentNodeId, setCurrentNodeId] = useState<string | null>(null)
    const [previewImages, setPreviewImages] = useState<Record<string, string>>(() => {
        const initialPreviews: Record<string, string> = {}
        startNodes.forEach((node) => {
            if (node.type === 'image') {
                const images = node.data?.output?.images
                if (images?.[0]?.url) {
                    initialPreviews[node.id] = images[0].url
                }
            } else if (node.type === 'video') {
                const videos = node.data?.output?.videos
                if (videos?.[0]?.url) {
                    initialPreviews[node.id] = videos[0].url
                }
            }
        })
        return initialPreviews
    })
    const [errors, setErrors] = useState<Record<string, string>>({})

    const updateFormData = useCallback((nodeId: string, value: string) => {
        setFormData((prev) => ({ ...prev, [nodeId]: value }))
        // Clear error for this field when user updates it
        if (errors[nodeId]) {
            setErrors((prev) => {
                const newErrors = { ...prev }
                delete newErrors[nodeId]
                return newErrors
            })
        }
    }, [errors])

    // 暴露方法给父组件
    useImperativeHandle(ref, () => ({
        updateFieldValue: (nodeId: string, value: string, previewUri?: string) => {
            updateFormData(nodeId, value)
            if (previewUri) {
                setPreviewImages((prev) => ({ ...prev, [nodeId]: previewUri }))
            }
        },
    }), [updateFormData])

    const handleSelectImage = useCallback(async (imageUri: string, mimeType?: string, fileName?: string) => {
        if (!currentNodeId) return

        try {
            const url = await uploadFile({ uri: imageUri, mimeType, fileName })
            updateFormData(currentNodeId, url)
            setPreviewImages((prev) => ({ ...prev, [currentNodeId]: imageUri }))
        } catch (error) {
            console.error('Upload failed:', error)
            Toast.show({
                title: t('dynamicForm.uploadFailed') || '上传失败，请重试'
            })
        } finally {
            setDrawerVisible(false)
            setCurrentNodeId(null)
        }
    }, [currentNodeId, t, updateFormData])

    // 直接从相册选择图片并上传
    const handlePickAndUploadImage = useCallback(async (nodeId: string) => {
        try {
            const [imageUri] = await imgPicker({ maxImages: 1 })

            // 上传图片
            const url = await uploadFile({ uri: imageUri })
            updateFormData(nodeId, url)
            setPreviewImages((prev) => ({ ...prev, [nodeId]: imageUri }))
        } catch (error: any) {
            // 用户取消选择不显示错误
            if (error?.message === '未选择任何图片') {
                return
            }
            console.error('Pick and upload failed:', error)
            Toast.show(t('dynamicForm.uploadFailed') || '上传失败，请重试')
        }
    }, [t, updateFormData])

    const handleSelectVideo = useCallback(async (videoUri: string, mimeType?: string, fileName?: string) => {
        if (!currentNodeId) return

        try {
            const url = await uploadFile({ uri: videoUri, mimeType, fileName })
            updateFormData(currentNodeId, url)
            setPreviewImages((prev) => ({ ...prev, [currentNodeId]: videoUri }))
        } catch (error) {
            console.error('Upload failed:', error)
            Toast.show({
                title: t('dynamicForm.uploadFailed') || '上传失败，请重试'
            })
        } finally {
            setDrawerVisible(false)
            setCurrentNodeId(null)
        }
    }, [currentNodeId, t, updateFormData])

    const validateForm = useCallback(() => {
        const newErrors: Record<string, string> = {}

        startNodes.forEach((node) => {
            const value = formData[node.id]
            if (!value || value.trim() === '') {
                const label = node.data?.label || t('dynamicForm.field') || '字段'
                newErrors[node.id] = `${label}${t('dynamicForm.required') || '不能为空'}`
            }
        })

        setErrors(newErrors)
        return Object.keys(newErrors).length === 0
    }, [formData, startNodes, t])

    const handleSubmit = useCallback(async () => {
        if (!validateForm()) {
            Toast.show({
                title: t('dynamicForm.fillRequiredFields') || '请填写所有必填项'
            })
            return
        }

        Toast.showLoading()
        try {
            const result = await onSubmit(formData)
            Toast.hideLoading()

            if (result.error) {
                Toast.show({
                    title: result.error.message || t('dynamicForm.submitFailed') || '提交失败'
                })
            }
        } catch (error) {
            Toast.hideLoading()
            Toast.show({
                title: t('dynamicForm.submitFailed') || '提交失败'
            })
        }
    }, [formData, onSubmit, validateForm, t])

    const renderTextField = (node: StartNode) => {
        const value = formData[node.id] || ''
        const error = errors[node.id]
        const placeholder = node.data?.description || t('dynamicForm.enterText') || '请输入文本'

        return (
            <View key={node.id} style={styles.fieldContainer}>
                {node.data?.label && (
                    <Text style={styles.label}>
                        {node.data.label}
                        <Text style={styles.required}> *</Text>
                    </Text>
                )}
                <TextInput
                    testID={`text-input-${node.id}`}
                    style={[styles.textInput, error && styles.textInputError]}
                    value={value}
                    onChangeText={(text) => updateFormData(node.id, text)}
                    placeholder={placeholder}
                    placeholderTextColor="#8A8A8A"
                    multiline
                    numberOfLines={4}
                    textAlignVertical="top"
                />
                {error && <Text style={styles.errorText}>{error}</Text>}
            </View>
        )
    }

    const renderImageField = (node: StartNode) => {
        const value = formData[node.id]
        const previewUri = previewImages[node.id]
        const error = errors[node.id]
        const label = node.data?.label || t('dynamicForm.image') || '图片'

        return (
            <View key={node.id} style={styles.fieldContainer}>
                <Text style={styles.label}>
                    {label}
                    <Text style={styles.required}> *</Text>
                </Text>
                <Pressable
                    style={styles.uploadButton}
                    onPress={() => handlePickAndUploadImage(node.id)}
                >
                    {previewUri ? (
                        <Image
                            source={previewUri}
                            style={styles.previewImage}
                            contentFit="cover"
                        />
                    ) : (
                        <View style={styles.uploadPlaceholder}>
                            <Text style={styles.uploadText}>
                                {t('dynamicForm.uploadImage') || '点击上传图片'}
                            </Text>
                        </View>
                    )}
                </Pressable>
                {error && <Text style={styles.errorText}>{error}</Text>}
            </View>
        )
    }

    const renderVideoField = (node: StartNode) => {
        const value = formData[node.id]
        const previewUri = previewImages[node.id]
        const error = errors[node.id]
        const label = node.data?.label || t('dynamicForm.video') || '视频'

        return (
            <View key={node.id} style={styles.fieldContainer}>
                <Text style={styles.label}>
                    {label}
                    <Text style={styles.required}> *</Text>
                </Text>
                <Pressable
                    style={styles.uploadButton}
                    onPress={() => {
                        setCurrentNodeId(node.id)
                        if (onOpenDrawer) {
                            onOpenDrawer(node.id)
                        } else {
                            setDrawerVisible(true)
                        }
                    }}
                >
                    {previewUri ? (
                        <View style={styles.videoPreview}>
                            <Text style={styles.uploadText}>
                                {t('dynamicForm.videoUploaded') || '视频已上传'}
                            </Text>
                        </View>
                    ) : (
                        <View style={styles.uploadPlaceholder}>
                            <Text style={styles.uploadText}>
                                {t('dynamicForm.uploadVideo') || '点击上传视频'}
                            </Text>
                        </View>
                    )}
                </Pressable>
                {error && <Text style={styles.errorText}>{error}</Text>}
            </View>
        )
    }

    const renderSelectField = (node: StartNode) => {
        const value = formData[node.id]
        const error = errors[node.id]
        const label = node.data?.label || t('dynamicForm.select') || '选择'
        const options = node.data?.actionData?.options || []
        const placeholder = node.data?.actionData?.placeholder || t('dynamicForm.selectPlaceholder') || '请选择'
        const allowMultiple = node.data?.actionData?.allowMultiple || false

        return (
            <View key={node.id} style={styles.fieldContainer}>
                <Text style={styles.label}>
                    {label}
                    <Text style={styles.required}> *</Text>
                </Text>
                {allowMultiple ? (
                    // Multi-select: render as a list of checkboxes
                    <View style={styles.optionsContainer}>
                        {options.map((option, index) => {
                            const isSelected = value === option.value
                            return (
                                <Pressable
                                    key={index}
                                    style={[styles.optionButton, isSelected && styles.optionButtonSelected]}
                                    onPress={() => updateFormData(node.id, option.value)}
                                >
                                    <Text style={[styles.optionText, isSelected && styles.optionTextSelected]}>
                                        {option.label}
                                    </Text>
                                </Pressable>
                            )
                        })}
                    </View>
                ) : (
                    // Single select: render as a list of radio buttons
                    <View style={styles.optionsContainer}>
                        {options.map((option, index) => {
                            const isSelected = value === option.value
                            return (
                                <Pressable
                                    key={index}
                                    style={[styles.optionButton, isSelected && styles.optionButtonSelected]}
                                    onPress={() => updateFormData(node.id, option.value)}
                                >
                                    <View style={styles.radioContainer}>
                                        <View style={[styles.radioCircle, isSelected && styles.radioCircleSelected]}>
                                            {isSelected && <View style={styles.radioDot} />}
                                        </View>
                                        <Text style={[styles.optionText, isSelected && styles.optionTextSelected]}>
                                            {option.label}
                                        </Text>
                                    </View>
                                </Pressable>
                            )
                        })}
                    </View>
                )}
                {error && <Text style={styles.errorText}>{error}</Text>}
            </View>
        )
    }

    const renderField = (node: StartNode) => {
        switch (node.type) {
            case 'text':
                return renderTextField(node)
            case 'image':
                return renderImageField(node)
            case 'video':
                return renderVideoField(node)
            case 'select':
                return renderSelectField(node)
            default:
                return null
        }
    }

    if (startNodes.length === 0) {
        return (
            <View style={styles.emptyContainer}>
                <Text style={styles.emptyText}>
                    {t('dynamicForm.noFields') || '暂无可填写的表单项'}
                </Text>
            </View>
        )
    }

    return (
        <KeyboardAvoidingView
            style={styles.keyboardAvoidingView}
            behavior={Platform.OS === 'ios' ? 'padding' : undefined}
            keyboardVerticalOffset={0}
        >
            <ScrollView
                style={styles.scrollView}
                contentContainerStyle={styles.scrollContent}
                showsVerticalScrollIndicator={false}
                keyboardShouldPersistTaps="handled"
            >
                {startNodes.map(renderField)}

                <View style={styles.submitButtonContainer}>
                    <Button
                        testID="submit-button"
                        variant="gradient"
                        onPress={handleSubmit}
                        disabled={loading}
                        style={styles.submitButton}
                        className="px-0"
                    >
                        {loading ? (
                            <ActivityIndicator color="#fff" />
                        ) : (
                            <View style={styles.submitButtonContent}>
                                <Text style={styles.submitButtonText}>
                                    {t('dynamicForm.submit') || '提交'}
                                </Text>
                                {points !== undefined && points > 0 && (
                                    <View style={styles.pointsContainer}>
                                        <Text style={styles.pointsText}>{points}</Text>
                                    </View>
                                )}
                            </View>
                        )}
                    </Button>
                </View>
            </ScrollView>
        </KeyboardAvoidingView>
    )
    }
)

const styles = StyleSheet.create({
    keyboardAvoidingView: {
        flex: 1,
    },
    scrollView: {
        flex: 1,
    },
    scrollContent: {
        padding: 16,
        gap: 20,
    },
    fieldContainer: {
        gap: 8,
    },
    label: {
        color: '#F5F5F5',
        fontSize: 14,
        fontWeight: '500',
    },
    required: {
        color: '#FF6699',
    },
    textInput: {
        minHeight: 100,
        backgroundColor: '#262A31',
        borderRadius: 12,
        padding: 12,
        color: '#F5F5F5',
        fontSize: 14,
        lineHeight: 20,
        borderWidth: 1,
        borderColor: 'transparent',
    },
    textInputError: {
        borderColor: '#FF6699',
    },
    uploadButton: {
        height: 140,
        backgroundColor: '#262A31',
        borderRadius: 12,
        overflow: 'hidden',
        alignItems: 'center',
        justifyContent: 'center',
    },
    uploadPlaceholder: {
        alignItems: 'center',
        justifyContent: 'center',
        gap: 8,
    },
    previewImage: {
        width: '100%',
        height: '100%',
    },
    videoPreview: {
        alignItems: 'center',
        justifyContent: 'center',
        gap: 8,
    },
    uploadText: {
        color: '#F5F5F5',
        fontSize: 14,
        fontWeight: '500',
    },
    errorText: {
        color: '#FF6699',
        fontSize: 12,
        marginTop: 4,
    },
    submitButtonContainer: {
        marginTop: 12,
        paddingTop: 12,
    },
    submitButton: {
        width: '100%',
        height: 56,
        minHeight: 56,
    },
    submitButtonContent: {
        flexDirection: 'row',
        alignItems: 'center',
        justifyContent: 'center',
        gap: 8,
    },
    submitButtonText: {
        color: '#FFFFFF',
        fontSize: 16,
        fontWeight: '500',
    },
    pointsContainer: {
        backgroundColor: 'rgba(255, 255, 255, 0.2)',
        paddingHorizontal: 8,
        paddingVertical: 2,
        borderRadius: 10,
    },
    pointsText: {
        color: '#FFFFFF',
        fontSize: 12,
        fontWeight: '600',
    },
    emptyContainer: {
        flex: 1,
        alignItems: 'center',
        justifyContent: 'center',
        padding: 20,
    },
    emptyText: {
        color: '#8A8A8A',
        fontSize: 14,
        textAlign: 'center',
    },
    optionsContainer: {
        gap: 8,
    },
    optionButton: {
        backgroundColor: '#262A31',
        borderRadius: 12,
        padding: 16,
        borderWidth: 1,
        borderColor: 'transparent',
    },
    optionButtonSelected: {
        backgroundColor: '#FF6699',
        borderColor: '#FF6699',
    },
    optionText: {
        color: '#F5F5F5',
        fontSize: 14,
        fontWeight: '500',
    },
    optionTextSelected: {
        color: '#FFFFFF',
    },
    radioContainer: {
        flexDirection: 'row',
        alignItems: 'center',
        gap: 12,
    },
    radioCircle: {
        width: 20,
        height: 20,
        borderRadius: 10,
        borderWidth: 2,
        borderColor: '#8A8A8A',
        alignItems: 'center',
        justifyContent: 'center',
    },
    radioCircleSelected: {
        borderColor: '#FF6699',
        backgroundColor: '#FF6699',
    },
    radioDot: {
        width: 8,
        height: 8,
        borderRadius: 4,
        backgroundColor: '#FFFFFF',
    },
})
