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 * as ImagePicker from 'expo-image-picker'

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 [asset] = await imgPicker({ maxImages: 1, type: ImagePicker.MediaTypeOptions.All, resultType: 'asset' })
                if (!asset) {
                    console.warn('No asset selected')
                    return
                }
                if (asset?.uri) {
                    Toast.showLoading({ title: '文件传输中...', duration: 0 })
                    console.log('[DynamicForm] 选择图片成功:', asset)
                    // 上传图片
                    const url = await uploadFile({ uri: asset.uri })
                    console.log('[DynamicForm] 上传成功，URL:', url)
                    updateFormData(nodeId, url)
                    setPreviewImages((prev) => ({ ...prev, [nodeId]: url }))
                }

            } catch (error: any) {
                // 用户取消选择不显示错误
                if (error?.message === '未选择任何图片') {
                    return
                }
                console.error('[DynamicForm] 上传失败:', { error, message: error?.message, stack: error?.stack })
                Toast.show(t('dynamicForm.uploadFailed') || '上传失败，请重试')
            } finally {
                Toast.hideLoading()
            }
        }, [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',
    },
})
