import Ionicons from '@expo/vector-icons/Ionicons';
import { ResultDisplay } from '@/components/template-run/result-display';
import { ThemedText } from '@/components/themed-text';
import { ThemedView } from '@/components/themed-view';
import { useTemplateRun } from '@/hooks/use-template-run';
import { getTemplateById } from '@/lib/api/templates';
import { subscription } from '@/lib/auth/client';
import { Template } from '@/lib/types/template';
import { RunTemplateData } from '@/lib/types/template-run';
import { Image } from 'expo-image';
import { LinearGradient } from 'expo-linear-gradient';
import { Stack, useGlobalSearchParams, useLocalSearchParams, useRouter } from 'expo-router';
import { useCallback, useEffect, useMemo, useState } from 'react';
import { Alert, BackHandler, ScrollView, StyleSheet, TouchableOpacity, View } from 'react-native';
import { useSafeAreaInsets } from 'react-native-safe-area-context';

type RunStep = 'progress' | 'result';

function transformFormData(formData: RunTemplateData): RunTemplateData {
  const transformed: RunTemplateData = {};

  Object.entries(formData).forEach(([fieldName, value]) => {
    if (fieldName.startsWith('image_')) {
      transformed[fieldName] = {
        url: value,
        type: 'image',
      };
    } else if (fieldName.startsWith('text_')) {
      transformed[fieldName] = {
        content: value,
        type: 'text',
      };
    } else if (fieldName.startsWith('video_')) {
      transformed[fieldName] = {
        url: value,
        type: 'video',
      };
    } else if (fieldName.startsWith('color_')) {
      transformed[fieldName] = {
        value,
        type: 'color',
      };
    } else {
      transformed[fieldName] = value;
    }
  });

  return transformed;
}

export default function TemplateRunScreen() {
  const { id } = useLocalSearchParams<{ id: string }>();
  const router = useRouter();
  const globalParams = useGlobalSearchParams<{ formData?: string }>();
  const insets = useSafeAreaInsets();

  const [template, setTemplate] = useState<Template | null>(null);
  const [loading, setLoading] = useState(true);
  const [currentStep, setCurrentStep] = useState<RunStep>('progress');
  const [hasStarted, setHasStarted] = useState(false);
  const [formImageUrls, setFormImageUrls] = useState<string[]>([]);

  const {
    progress,
    result,
    error,
    isLoading,
    executeTemplate,
    cancelRun,
    cleanup,
  } = useTemplateRun({
    onSuccess: () => {
      setCurrentStep('result');
    },
    onError: (runError) => {
      Alert.alert('运行失败', runError.message);
    },
  });

  useEffect(() => {
    const loadTemplate = async () => {
      if (!id) return;

      try {
        setLoading(true);
        const response = await getTemplateById(id);
        if (response && response.success && response.data) {
          setTemplate(response.data as any);
        } else {
          throw new Error('模板不存在');
        }
      } catch (templateError) {
        console.error('加载模板失败:', templateError);
        Alert.alert('错误', '无法加载模板，请稍后重试。');
        router.back();
      } finally {
        setLoading(false);
      }
    };

    loadTemplate();
  }, [id, router]);

  useEffect(() => {
    if (template && !hasStarted && globalParams.formData) {
      try {
        const formData = JSON.parse(globalParams.formData) as RunTemplateData;
        const images = Object.entries(formData)
          .filter(([fieldName, value]) => fieldName.startsWith('image_') && typeof value === 'string' && value.length > 0)
          .map(([, value]) => value as string);
        setFormImageUrls(images);
        setHasStarted(true);

        const executeWithData = async () => {
          try {
            const list = await subscription.list();
            const listData = list.data ?? [];
            if (listData.length === 0) {
              Alert.alert('未检测到订阅', '请先完成订阅后再尝试生成内容。');
              router.back();
              return;
            }

            const subscriptionId = listData[0]?.stripeSubscriptionId;
            if (!subscriptionId) {
              Alert.alert('订阅信息缺失', '当前订阅缺少 Stripe 订阅标识，无法记录用量。');
              router.back();
              return;
            }

            const identify = await subscription.meterEvent({
              event_name: 'token_usage',
              payload: {
                value: '100',
              },
            });

            const identifier = identify.data?.identifier;
            if (!identifier) {
              Alert.alert('用量记录失败', '无法生成用量凭证，请稍后重试。');
              router.back();
              return;
            }

            const transformedData = transformFormData(formData);
            await executeTemplate(template.id, transformedData);
          } catch (executeError) {
            console.error('执行模板失败:', executeError);
            Alert.alert('执行失败', '运行模板时出现异常，请稍后重试。');
            router.back();
          }
        };

        executeWithData();
      } catch (parseError) {
        console.error('解析表单数据失败:', parseError);
        Alert.alert('数据错误', '表单数据格式错误，请重新提交。');
        router.back();
      }
    }
  }, [template, hasStarted, globalParams.formData, executeTemplate, router]);

  const handleRequestExit = useCallback(() => {
    if (currentStep === 'progress' && isLoading) {
      Alert.alert(
        '确认退出',
        '任务正在运行中，确定要退出吗？',
        [
          { text: '继续等待', style: 'cancel' },
          {
            text: '停止并返回',
            style: 'destructive',
            onPress: () => {
              cancelRun();
              router.back();
            },
          },
        ]
      );
      return true;
    }

    router.back();
    return true;
  }, [cancelRun, currentStep, isLoading, router]);

  useEffect(() => {
    const subscription = BackHandler.addEventListener('hardwareBackPress', handleRequestExit);
    return () => subscription.remove();
  }, [handleRequestExit]);

  useEffect(() => cleanup, [cleanup]);

  const handleRerun = useCallback(() => {
    router.back();
  }, [router]);

  const progressMeta = useMemo(() => {
    const rawProgress = typeof progress.progress === 'number' ? progress.progress : 0;
    const normalized = Math.max(0, Math.min(rawProgress, 100));
    return {
      normalized,
      percentLabel: Math.round(normalized),
      fillWidth: normalized <= 0 ? 0 : Math.min(Math.max(normalized, 8), 100),
    };
  }, [progress.progress]);

  const narrative = useMemo(() => {
    const fallbackTitle = 'Insert Your Product Into An ASMR Video';
    const fallbackDescription =
      'ASMR-Add-On keeps your original image the same while seamlessly adding our uploaded product into the ASMR scene.';

    const rawTitle = template?.titleEn ?? template?.title ?? fallbackTitle;
    const rawDescription = template?.descriptionEn ?? template?.description ?? fallbackDescription;

    return {
      title: rawTitle.toUpperCase(),
      description: rawDescription,
    };
  }, [template]);

  const imagery = useMemo(() => {
    const fallback = template?.previewUrl ?? template?.coverImageUrl ?? undefined;
    const primary = formImageUrls[0] ?? fallback;
    const secondary = formImageUrls[1] ?? template?.previewUrl ?? primary;

    return {
      hero: primary,
      overlay: secondary,
      preview: template?.previewUrl ?? primary ?? fallback,
    };
  }, [formImageUrls, template]);

  const renderProgressStep = () => (
    <ScrollView
      style={styles.scroll}
      contentContainerStyle={[
        styles.progressContent,
        {
          paddingTop: insets.top + 16,
          paddingBottom: insets.bottom + 40,
        },
      ]}
      showsVerticalScrollIndicator={false}
    >
      <TouchableOpacity
        onPress={handleRequestExit}
        activeOpacity={0.8}
        style={[styles.backButton, styles.backButtonProgress]}
      >
        <Ionicons name="chevron-back" size={22} color="#FFFFFF" />
      </TouchableOpacity>

      <View style={styles.titleSection}>
        <ThemedText style={styles.title} lightColor="#FFFFFF" darkColor="#FFFFFF">
          {narrative.title}
        </ThemedText>
        <ThemedText
          style={styles.subtitle}
          lightColor="rgba(255,255,255,0.68)"
          darkColor="rgba(255,255,255,0.68)"
        >
          {narrative.description}
        </ThemedText>
      </View>

      <View style={styles.heroContainer}>
        {imagery.hero ? (
          <Image source={{ uri: imagery.hero }} style={styles.heroImage} contentFit="cover" />
        ) : (
          <View style={styles.heroPlaceholder} />
        )}

        {imagery.overlay && (
          <View style={styles.overlayImageFrame}>
            <Image source={{ uri: imagery.overlay }} style={styles.overlayImage} contentFit="cover" />
          </View>
        )}
      </View>

      <LinearGradient colors={['#1E1E21', '#101015']} start={{ x: 0, y: 0 }} end={{ x: 1, y: 1 }} style={styles.progressCard}>
        {imagery.preview ? (
          <View style={styles.previewFrame}>
            <Image source={{ uri: imagery.preview }} style={styles.previewImage} contentFit="cover" />
          </View>
        ) : (
          <View style={[styles.previewFrame, styles.previewPlaceholder]} />
        )}

        <View style={styles.progressCopy}>
          <ThemedText style={styles.progressHeadline} lightColor="#FFFFFF" darkColor="#FFFFFF">
            ✨ 正在加载生成中...
          </ThemedText>
          <ThemedText
            style={styles.progressMessage}
            lightColor="rgba(255,255,255,0.72)"
            darkColor="rgba(255,255,255,0.72)"
          >
            {progress.message || '正在为你织造 ASMR 场景，请稍候片刻。'}
          </ThemedText>
        </View>

        <View style={styles.progressBarArea}>
          <View style={styles.progressTrack}>
            {progressMeta.fillWidth > 0 && (
              <View style={[styles.progressFill, { width: `${progressMeta.fillWidth}%` }]}>
                <LinearGradient
                  colors={['#78F8FF', '#49A7FF']}
                  start={{ x: 0, y: 0 }}
                  end={{ x: 1, y: 0 }}
                  style={StyleSheet.absoluteFill}
                />
              </View>
            )}
          </View>
          <ThemedText
            style={styles.progressPercent}
            lightColor="rgba(255,255,255,0.6)"
            darkColor="rgba(255,255,255,0.6)"
          >
            {progressMeta.percentLabel}%
          </ThemedText>
        </View>
      </LinearGradient>

      <TouchableOpacity
        activeOpacity={0.85}
        style={styles.primaryButton}
        onPress={() => {
          Alert.alert('生成进行中', '系统正在为你制作视频，请耐心等待。');
        }}
      >
        <ThemedText style={styles.primaryButtonText} lightColor="#050505" darkColor="#050505">
          Generate Video
        </ThemedText>
      </TouchableOpacity>
    </ScrollView>
  );

  const renderResultStep = () => (
    <View
      style={[
        styles.resultContainer,
        {
          paddingTop: insets.top + 16,
          paddingBottom: Math.max(insets.bottom, 24),
        },
      ]}
    >
      <View style={styles.resultHeader}>
        <TouchableOpacity
          onPress={handleRequestExit}
          activeOpacity={0.8}
          style={[styles.backButton, styles.backButtonResult]}
        >
          <Ionicons name="chevron-back" size={22} color="#FFFFFF" />
        </TouchableOpacity>
        <ThemedText style={styles.resultTitle} lightColor="#FFFFFF" darkColor="#FFFFFF">
          生成结果
        </ThemedText>
      </View>

      <View style={styles.resultBody}>
        {result ? (
          <ResultDisplay result={result} onRerun={handleRerun} />
        ) : (
          <View style={styles.stateContainer}>
            <ThemedText style={styles.stateText} lightColor="rgba(255,255,255,0.7)" darkColor="rgba(255,255,255,0.7)">
              正在整理结果，请稍候...
            </ThemedText>
          </View>
        )}
      </View>
    </View>
  );

  if (loading) {
    return (
      <ThemedView style={styles.screen} lightColor="#050505" darkColor="#050505">
        <Stack.Screen options={{ headerShown: false }} />
        <View style={styles.stateContainer}>
          <ThemedText style={styles.stateText} lightColor="rgba(255,255,255,0.7)" darkColor="rgba(255,255,255,0.7)">
            加载中...
          </ThemedText>
        </View>
      </ThemedView>
    );
  }

  if (error && !template) {
    return (
      <ThemedView style={styles.screen} lightColor="#050505" darkColor="#050505">
        <Stack.Screen options={{ headerShown: false }} />
        <View style={styles.stateContainer}>
          <ThemedText style={styles.stateText} lightColor="rgba(255,255,255,0.7)" darkColor="rgba(255,255,255,0.7)">
            {error.message}
          </ThemedText>
        </View>
      </ThemedView>
    );
  }

  return (
    <ThemedView style={styles.screen} lightColor="#050505" darkColor="#050505">
      <Stack.Screen
        options={{
          headerShown: false,
          gestureEnabled: currentStep !== 'progress' || !isLoading,
        }}
      />

      {currentStep === 'progress' && renderProgressStep()}
      {currentStep === 'result' && renderResultStep()}
    </ThemedView>
  );
}

const styles = StyleSheet.create({
  screen: {
    flex: 1,
    backgroundColor: '#050505',
  },
  scroll: {
    flex: 1,
  },
  progressContent: {
    paddingHorizontal: 24,
    gap: 28,
  },
  backButton: {
    width: 44,
    height: 44,
    borderRadius: 22,
    borderWidth: 1,
    borderColor: 'rgba(255,255,255,0.08)',
    backgroundColor: 'rgba(255,255,255,0.05)',
    alignItems: 'center',
    justifyContent: 'center',
  },
  backButtonProgress: {
    alignSelf: 'flex-start',
  },
  backButtonResult: {
    marginRight: 12,
  },
  titleSection: {
    gap: 12,
  },
  title: {
    fontSize: 20,
    fontWeight: '700',
    letterSpacing: 0.8,
    lineHeight: 28,
  },
  subtitle: {
    fontSize: 13,
    lineHeight: 20,
  },
  heroContainer: {
    position: 'relative',
    borderRadius: 24,
    overflow: 'hidden',
    backgroundColor: '#121212',
  },
  heroImage: {
    width: '100%',
    aspectRatio: 1.58,
  },
  heroPlaceholder: {
    width: '100%',
    aspectRatio: 1.58,
    backgroundColor: '#1F1F20',
  },
  overlayImageFrame: {
    position: 'absolute',
    left: 18,
    bottom: 18,
    width: 72,
    height: 72,
    borderRadius: 18,
    overflow: 'hidden',
    borderWidth: 2,
    borderColor: '#050505',
    shadowColor: '#000000',
    shadowOpacity: 0.4,
    shadowRadius: 8,
    shadowOffset: { width: 0, height: 6 },
    elevation: 6,
  },
  overlayImage: {
    width: '100%',
    height: '100%',
  },
  progressCard: {
    borderRadius: 28,
    paddingVertical: 28,
    paddingHorizontal: 24,
    borderWidth: 1,
    borderColor: 'rgba(255,255,255,0.06)',
    gap: 24,
  },
  previewFrame: {
    alignSelf: 'center',
    width: 96,
    height: 148,
    borderRadius: 24,
    overflow: 'hidden',
    borderWidth: 1,
    borderColor: 'rgba(255,255,255,0.12)',
    backgroundColor: '#0F0F12',
  },
  previewImage: {
    width: '100%',
    height: '100%',
  },
  previewPlaceholder: {
    backgroundColor: '#18181C',
  },
  progressCopy: {
    alignItems: 'center',
    gap: 6,
    paddingHorizontal: 8,
  },
  progressHeadline: {
    fontSize: 16,
    fontWeight: '700',
  },
  progressMessage: {
    fontSize: 13,
    lineHeight: 20,
    textAlign: 'center',
  },
  progressBarArea: {
    gap: 12,
  },
  progressTrack: {
    height: 8,
    borderRadius: 4,
    backgroundColor: 'rgba(255,255,255,0.08)',
    overflow: 'hidden',
  },
  progressFill: {
    height: '100%',
    borderRadius: 4,
    overflow: 'hidden',
  },
  progressPercent: {
    fontSize: 12,
    fontWeight: '600',
    textAlign: 'right',
  },
  primaryButton: {
    height: 60,
    borderRadius: 30,
    backgroundColor: '#D7FF1F',
    alignItems: 'center',
    justifyContent: 'center',
    shadowColor: '#D7FF1F',
    shadowOpacity: 0.4,
    shadowRadius: 16,
    shadowOffset: { width: 0, height: 12 },
    elevation: 4,
  },
  primaryButtonText: {
    fontSize: 16,
    fontWeight: '700',
    letterSpacing: 0.6,
  },
  resultContainer: {
    flex: 1,
    paddingHorizontal: 24,
    gap: 24,
  },
  resultHeader: {
    flexDirection: 'row',
    alignItems: 'center',
  },
  resultTitle: {
    fontSize: 16,
    fontWeight: '600',
    letterSpacing: 0.4,
  },
  resultBody: {
    flex: 1,
  },
  stateContainer: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    paddingHorizontal: 32,
  },
  stateText: {
    fontSize: 15,
    lineHeight: 22,
    textAlign: 'center',
  },
});
