import { Feather } from '@expo/vector-icons';
import { Stack, useLocalSearchParams, useRouter } from 'expo-router';
import React, { useEffect, useState } from 'react';
import {
  ActivityIndicator,
  Alert,
  Image,
  ScrollView,
  StyleSheet,
  Text,
  TouchableOpacity,
  View,
} from 'react-native';
import { SafeAreaView } from 'react-native-safe-area-context';

export const unstable_settings = {
  headerShown: false,
};

import { BackButton } from '@/components/ui/back-button';
import { DynamicFormField } from '@/components/forms/dynamic-form-field';
import { getTemplateById } from '@/lib/api/templates';
import { recordTokenUsage, getUserBalance } from '@/lib/api/balance';
import { runTemplate, pollTemplateGeneration } from '@/lib/api/template-runs';
import { uploadFile } from '@/lib/api/upload';
import { Template, TemplateGraphNode } from '@/lib/types/template';
import { TemplateGeneration } from '@/lib/types/template-run';
import { useAuth } from '@/hooks/use-auth';

const FALLBACK_PREVIEW =
  'https://images.unsplash.com/photo-1542204165-0198c1e21a3b?auto=format&fit=crop&w=1200&q=80';
const FALLBACK_INSET =
  'https://images.unsplash.com/photo-1524504388940-b1c1722653e1?auto=format&fit=crop&w=640&q=80';

export default function TemplateFormScreen() {
  const { id } = useLocalSearchParams<{ id: string }>();
  const router = useRouter();
  const { session, isLoading: authLoading } = useAuth();

  const [template, setTemplate] = useState<Template | null>(null);
  const [loading, setLoading] = useState(true);
  const [formData, setFormData] = useState<Record<string, any>>({});
  const [errors, setErrors] = useState<Record<string, string>>({});
  const [isSubmitting, setIsSubmitting] = useState(false);
  const [pollingStatus, setPollingStatus] = useState<{
    isPolling: boolean;
    generationId?: string;
    message?: string;
  }>({ isPolling: false });

  useEffect(() => {
    loadInitialData();
  }, [id]);

  const loadInitialData = async () => {
    try {
      setLoading(true);
      const templateResponse = await getTemplateById(id);

      if (templateResponse.success && templateResponse.data) {
        setTemplate(templateResponse.data);
        // 初始化表单数据
        const initialData: Record<string, any> = {};
        templateResponse.data.formSchema?.startNodes.forEach((node: TemplateGraphNode) => {
          if (node.data.actionData?.allowMultiple) {
            initialData[node.id] = [];
          } else {
            initialData[node.id] = '';
          }
        });
        setFormData(initialData);
      }
    } catch (error) {
      console.error('Failed to load template:', error);
      Alert.alert('错误', '加载数据失败，请稍后重试');
    } finally {
      setLoading(false);
    }
  };

  const validateForm = (): boolean => {
    if (!template?.formSchema?.startNodes) return false;

    const newErrors: Record<string, string> = {};

    template.formSchema.startNodes.forEach((node: TemplateGraphNode) => {
      const { id, data } = node;
      const { actionData, label } = data;
      const value = formData[id];

      // 检查必填项
      if (actionData?.required) {
        if (Array.isArray(value)) {
          if (value.length === 0) {
            newErrors[id] = `请选择${label}`;
          }
        } else if (!value || (typeof value === 'string' && !value.trim())) {
          newErrors[id] = `请填写${label}`;
        }
      }
    });

    setErrors(newErrors);
    return Object.keys(newErrors).length === 0;
  };

  /**
   * 检查用户是否可以生成（登录 + metered 订阅 + 余额充足）
   */
  const canGenerate = async (): Promise<{ canProceed: boolean; message?: string }> => {
    // 1. 检查是否登录
    if (!session?.user) {
      return {
        canProceed: false,
        message: '请先登录',
      };
    }

    // 2. 检查是否有 metered 订阅
    const balanceResponse = await getUserBalance();
    if (!balanceResponse.success) {
      return {
        canProceed: false,
        message: balanceResponse.message || '未找到计费订阅，请先订阅',
      };
    }

    // 3. 检查余额是否充足
    const requiredAmount = template?.costPrice || 0;
    const currentBalance = balanceResponse.data.remainingTokenBalance;

    if (currentBalance < requiredAmount) {
      return {
        canProceed: false,
        message: `余额不足\n当前余额: ${currentBalance}\n需要费用: ${requiredAmount}`,
      };
    }

    return { canProceed: true };
  };

  /**
   * 上传所有 blob URL 文件到服务器
   */
  const uploadBlobFiles = async (data: Record<string, any>): Promise<Record<string, any>> => {
    if (!template?.formSchema?.startNodes) return data;

    const uploadedData = { ...data };

    for (const node of template.formSchema.startNodes) {
      const value = data[node.id];

      if (!value) continue;

      // 检查是否是 blob URL
      if (typeof value === 'string' && value.startsWith('blob:')) {
        const fileType = node.type === 'image' ? 'image' : node.type === 'video' ? 'video' : null;

        if (fileType) {
          const uploadResponse = await uploadFile(value, fileType as 'image' | 'video');

          if (!uploadResponse.success || !uploadResponse.data) {
            throw new Error(`上传 ${node.data.label} 失败`);
          }

          uploadedData[node.id] = uploadResponse.data.url;
        }
      }
    }

    return uploadedData;
  };

  const transformFormDataToRunFormat = (formData: Record<string, any>): Record<string, any> => {
    if (!template?.formSchema?.startNodes) return {};

    const transformed: Record<string, any> = {};

    template.formSchema.startNodes.forEach((node: TemplateGraphNode) => {
      const { id, type } = node;
      const value = formData[id];

      // 跳过空值
      if (!value || (Array.isArray(value) && value.length === 0)) {
        return;
      }

      // 根据节点类型转换数据格式
      switch (type) {
        case 'image':
          transformed[id] = {
            images: [{ url: value }],
          };
          break;

        case 'video':
          transformed[id] = {
            videos: [{ url: value }],
          };
          break;

        case 'text':
          transformed[id] = {
            texts: [value],
          };
          break;

        case 'select':
          // 根据 allowMultiple 判断是否为多选
          if (node.data.actionData?.allowMultiple) {
            transformed[id] = {
              selections: Array.isArray(value) ? value : [value],
            };
          } else {
            transformed[id] = {
              selections: value,
            };
          }
          break;

        default:
          // 未知类型，保持原样
          transformed[id] = value;
      }
    });

    return transformed;
  };

  const handleSubmit = async () => {
    if (!template) return;
    if (!validateForm()) {
      Alert.alert('提示', '请完善所有必填项');
      return;
    }

    setIsSubmitting(true);

    try {
      // 步骤 1: 检查是否可以生成（登录 + 订阅 + 余额）
      const checkResult = await canGenerate();
      if (!checkResult.canProceed) {
        Alert.alert('无法生成', checkResult.message || '请检查账户状态', [
          { text: '取消', style: 'cancel' },
          {
            text: '去充值',
            onPress: () => router.push('/exchange' as any),
          },
        ]);
        return;
      }

      // 步骤 2: 上传所有 blob 文件到服务器
      let uploadedFormData: Record<string, any>;
      try {
        uploadedFormData = await uploadBlobFiles(formData);
      } catch (uploadError) {
        Alert.alert('上传失败', uploadError instanceof Error ? uploadError.message : '文件上传失败，请重试');
        return;
      }

      // 步骤 3: 扣费并获取 identifier
      const requiredAmount = template.costPrice || 0;
      const usageResponse = await recordTokenUsage({
        price: requiredAmount,
        name: `生成视频 - ${template.title}`,
        metadata: {
          templateId: template.id,
          templateTitle: template.title,
        },
      });

      if (!usageResponse.success || !usageResponse.data?.identifier) {
        Alert.alert('扣费失败', usageResponse.message || '请稍后重试');
        return;
      }

      const paymentIdentifier = usageResponse.data.identifier;

      // 步骤 4: 验证所有 URL 都是有效的服务器 URL
      const hasInvalidUrl = Object.values(uploadedFormData).some(
        (value) => typeof value === 'string' && value.startsWith('blob:')
      );

      if (hasInvalidUrl) {
        Alert.alert('错误', '存在未上传的文件，请重试');
        return;
      }

      // 步骤 5: 转换表单数据为 API 格式
      const transformedData = transformFormDataToRunFormat(uploadedFormData);

      // 步骤 6: 调用 template run，使用支付凭证 identifier
      const runResponse = await runTemplate(id, transformedData, paymentIdentifier);

      if (!runResponse.success) {
        Alert.alert('错误', '生成任务创建失败');
        return;
      }

      const generationId = runResponse.data;

      // 步骤 7: 开始轮询任务状态
      setPollingStatus({
        isPolling: true,
        generationId,
        message: '正在生成内容，请稍候...',
      });

      // 使用轮询函数
      pollTemplateGeneration(
        generationId,
        // 成功回调
        (result: TemplateGeneration) => {
          setPollingStatus({ isPolling: false });

          // 跳转到结果页面
          router.push(`/result?generationId=${generationId}`);
        },
        // 错误回调
        (error: Error) => {
          setPollingStatus({ isPolling: false });
          Alert.alert('生成失败', error.message || '任务执行失败，请重试');
        },
        // 最大尝试次数（100次 * 3秒 = 5分钟）
        100,
        // 轮询间隔（3秒）
        3000
      );
    } catch (error) {
      console.error('Submission failed:', error);
      Alert.alert('错误', '提交失败，请稍后重试');
    } finally {
      setIsSubmitting(false);
    }
  };

  const renderFormFields = () => {
    if (!template?.formSchema?.startNodes) return null;

    return template.formSchema.startNodes.map((node: TemplateGraphNode) => (
      <DynamicFormField
        key={node.id}
        node={node}
        value={formData[node.id]}
        onChange={(value) => {
          setFormData(prev => ({ ...prev, [node.id]: value }));
          if (errors[node.id]) {
            setErrors(prev => {
              const newErrors = { ...prev };
              delete newErrors[node.id];
              return newErrors;
            });
          }
        }}
        error={errors[node.id]}
      />
    ));
  };

  const renderStep1 = () => {
    const heroImage = template?.previewUrl || template?.coverImageUrl || FALLBACK_PREVIEW;
    const insetImage = template?.coverImageUrl || FALLBACK_INSET;

    return (
      <ScrollView
        style={styles.stepScroll}
        contentContainerStyle={styles.step1Content}
        showsVerticalScrollIndicator={false}
      >
        <View style={styles.topBar}>
          <BackButton onPress={() => router.back()} />
        </View>

        <Text style={styles.heroTitle}>
          {(template?.title ?? 'AI视频生成').toUpperCase()}
        </Text>
        <Text style={styles.heroSubtitle}>
          {template?.description || '使用AI技术快速生成专业视频内容'}
        </Text>

        <View style={styles.previewStage}>
          <Image source={{ uri: heroImage }} style={styles.previewImage} />
          <View style={styles.previewInset}>
            <Image source={{ uri: insetImage }} style={styles.previewInsetImage} />
          </View>
        </View>

        {renderFormFields()}

        <TouchableOpacity
          style={[
            styles.generateButton,
            (isSubmitting || pollingStatus.isPolling) && styles.generateButtonDisabled
          ]}
          activeOpacity={0.88}
          onPress={handleSubmit}
          disabled={isSubmitting || pollingStatus.isPolling}
        >
          {isSubmitting ? (
            <>
              <ActivityIndicator size="small" color="#050505" />
              <Text style={styles.generateLabel}>提交中...</Text>
            </>
          ) : pollingStatus.isPolling ? (
            <>
              <ActivityIndicator size="small" color="#050505" />
              <Text style={styles.generateLabel}>{pollingStatus.message || '生成中...'}</Text>
            </>
          ) : (
            <>
              <Feather name="star" size={20} color="#050505" />
              <Text style={styles.generateLabel}>生成视频</Text>
            </>
          )}
        </TouchableOpacity>
      </ScrollView>
    );
  };

  if (loading) {
    return (
      <>
        <Stack.Screen options={{ headerShown: false }} />

        <View style={styles.loadingCanvas}>
          <SafeAreaView style={styles.safeArea} edges={['top', 'left', 'right']}>
            <View style={styles.loadingContainer}>
              <ActivityIndicator size="large" color="#D1FF00" />
              <Text style={styles.loadingText}>Loading...</Text>
            </View>
          </SafeAreaView>
        </View>
      </>
    );
  }

  return (
    <>
      <Stack.Screen options={{ headerShown: false }} />

      <View style={styles.canvas}>
        <SafeAreaView style={styles.safeArea} edges={['top', 'left', 'right']}>
          {renderStep1()}
        </SafeAreaView>
      </View>
    </>
  );
}

const styles = StyleSheet.create({
  canvas: {
    flex: 1,
    backgroundColor: '#050505',
  },
  safeArea: {
    flex: 1,
  },
  loadingCanvas: {
    flex: 1,
    backgroundColor: '#050505',
  },
  loadingContainer: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },
  loadingText: {
    marginTop: 16,
    fontSize: 16,
    color: 'rgba(255, 255, 255, 0.7)',
    letterSpacing: 0.3,
  },
  stepScroll: {
    flex: 1,
  },
  step1Content: {
    paddingHorizontal: 24,
    paddingBottom: 40,
  },
  topBar: {
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'space-between',
    paddingHorizontal: 0,
    paddingTop: 8,
    paddingBottom: 8,
    gap: 12,
  },
  stepIndicator: {
    flex: 1,
    textAlign: 'right',
    fontSize: 13,
    letterSpacing: 2,
    color: 'rgba(255, 255, 255, 0.5)',
  },
  heroTitle: {
    fontSize: 26,
    lineHeight: 32,
    fontWeight: '700',
    color: '#FFFFFF',
    letterSpacing: 0.8,
    textTransform: 'uppercase',
    marginBottom: 16,
  },
  heroSubtitle: {
    fontSize: 14,
    lineHeight: 20,
    color: 'rgba(255, 255, 255, 0.68)',
    marginBottom: 24,
  },
  previewStage: {
    borderRadius: 32,
    overflow: 'hidden',
    backgroundColor: '#111318',
    marginBottom: 28,
  },
  previewImage: {
    width: '100%',
    height: 220,
  },
  previewInset: {
    position: 'absolute',
    bottom: 18,
    left: 18,
    width: 74,
    height: 74,
    borderRadius: 24,
    overflow: 'hidden',
  },
  previewInsetImage: {
    width: '100%',
    height: '100%',
  },
  generateButton: {
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'center',
    height: 58,
    borderRadius: 30,
    backgroundColor: '#D1FF00',
    gap: 10,
  },
  generateButtonDisabled: {
    opacity: 0.6,
  },
  generateLabel: {
    fontSize: 17,
    fontWeight: '700',
    letterSpacing: 0.4,
    color: '#050505',
  },
});
