import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { View, StyleSheet, ActivityIndicator, Pressable, Animated, BackHandler, InteractionManager } from 'react-native'
import CustomText from '@/components/common/CustomText.jsx';
import { router } from 'expo-router';
import { Camera, useCameraDevice, useCameraPermission, useCodeScanner } from 'react-native-vision-camera';
import LottieView from 'lottie-react-native';

import cameraScanJson from '@/assets/animations/scanning.json';
import * as ImagePicker from 'expo-image-picker';
import BarcodeScanning from '@react-native-ml-kit/barcode-scanning';
import { Ionicons } from '@expo/vector-icons';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import { useFocusEffect } from 'expo-router';
import {CustomHeader} from '@/components/common/CustomHeader';

import { Image as ExpoImage } from 'expo-image';
import { showWarning } from '@/utils/ui/toast';

const isHttpUrl = (text) => /^https?:\/\//i.test(String(text || ''));
const ScanScreen = () => {
  const device = useCameraDevice('back');
  const { hasPermission, requestPermission } = useCameraPermission();
  const [active, setActive] = useState(true);
  const handledRef = useRef(false);
  const previewOpenRef = useRef(false);
  const [cameraReady, setCameraReady] = useState(false);
  const [scannerEnabled, setScannerEnabled] = useState(false);
  const [canRender, setCanRender] = useState(false);

  const insets = useSafeAreaInsets();
  // 闪光灯状态与动画
  const [torch, setTorch] = useState('off');
  const flashAnim = useRef(new Animated.Value(0)).current; // on:1 off:0

  // 延迟渲染重型组件，避免推页卡顿
  useEffect(() => {
    const task = InteractionManager.runAfterInteractions(() => {
      setCanRender(true);
    });
    return () => task.cancel();
  }, []);

  // 页面焦点控制摄像头活动，解决 iOS 返回卡顿
  useFocusEffect(
    useCallback(() => {
      // 页面获得焦点，开启摄像头
      setActive(true);
      return () => {
        // 页面失焦（开始返回或跳转），先暂停摄像头与关闭闪光灯，并停止动画
        try { flashAnim.stopAnimation(); } catch (_) {}
        flashAnim.setValue(0);
        setTorch('off');
        setActive(false);
      };
    }, [])
  );

  const codeTypes = useMemo(() => ['qr'], []);

  const navigateToUrl = useCallback((url) => {
    if (!url) return;
    handledRef.current = true;

    try {
      router.replace({ pathname: '/webview', params: { url: encodeURIComponent(url) } });
    } catch (_) {
      try { router.back(); } catch (_) {}
    }
  }, []);

  useEffect(() => {
    Animated.spring(flashAnim, {
      toValue: torch === 'on' ? 1 : 0,
      useNativeDriver: true,
      friction: 8,
      tension: 120,
    }).start();
  }, [torch, flashAnim]);

  useEffect(() => {
    // 将权限请求延迟到交互完成，避免阻塞导航首帧
    if (!hasPermission) {
      InteractionManager.runAfterInteractions(() => {
        requestPermission().catch(() => {});
      });
    }
  }, [hasPermission, requestPermission]);

  const onCodeScanned = useCallback((codes) => {
    if (!codes || handledRef.current || previewOpenRef.current) return;
    const first = codes[0];
    const value = first?.value;
    if (value && isHttpUrl(value)) {
      navigateToUrl(value);
    }
  }, [navigateToUrl]);

  const codeScanner = useCodeScanner({
    codeTypes,
    onCodeScanned,
  });

  // 预览相关状态
  const [previewUri, setPreviewUri] = useState(null);
  const [previewMount, setPreviewMount] = useState(false); // 控制覆盖层挂载
  const [recognizing, setRecognizing] = useState(false);
  const [imgLoaded, setImgLoaded] = useState(false);
  const previewAnim = useRef(new Animated.Value(0)).current;
  const overlayAnim = useRef(new Animated.Value(0)).current; // 背景与容器淡入

  useEffect(() => {
    if (!previewMount) return;
    const sub = BackHandler.addEventListener('hardwareBackPress', () => {
      if (recognizing) return true;
      // 关闭预览
      Animated.timing(overlayAnim, { toValue: 0, duration: 200, useNativeDriver: true }).start(() => {
        setPreviewMount(false);
        previewOpenRef.current = false;
        setPreviewUri(null);
      });
      return true;
    });
    return () => sub.remove();
  }, [previewMount, recognizing, overlayAnim]);

  const onPickFromAlbum = useCallback(async () => {
    try {
      const perm = await ImagePicker.requestMediaLibraryPermissionsAsync();
      const permitted = perm?.granted || perm?.status === 'granted' || perm?.ios?.accessPrivileges === 'limited' || perm?.ios?.accessPrivileges === 'all';
      if (!permitted) return;

      const options = {
        quality: 1,
        base64: false,
      };
      const MT = ImagePicker.MediaType;
      if (MT && MT.Images != null) {
        options.mediaTypes = MT.Images;
      }

      let result;
      try {
        result = await ImagePicker.launchImageLibraryAsync(options);
      } catch (e) {
        // 某些旧版或平台下带参数会报错，降级为空参数
        result = await ImagePicker.launchImageLibraryAsync();
      }

      if (result?.canceled) return;
      const uri = result?.assets?.[0]?.uri;
      if (!uri) return;

      // 进入预览，不立即识别
      handledRef.current = false;
      previewOpenRef.current = true;
      setPreviewUri(uri);
      setPreviewMount(true);
      // 预览期间暂停相机，降低 CPU 占用
      setActive(false);
      // 开启动画
      overlayAnim.setValue(0);
      previewAnim.setValue(0);
      Animated.timing(overlayAnim, {
        toValue: 1,
        duration: 220,
        useNativeDriver: true,
      }).start();
    } catch (err) {
      showWarning('无法打开相册');
    }
  }, [overlayAnim, previewAnim]);

  const closePreview = useCallback(() => {
    if (recognizing) return;
    Animated.timing(overlayAnim, {
      toValue: 0,
      duration: 200,
      useNativeDriver: true,
    }).start(() => {
      setPreviewMount(false);
      previewOpenRef.current = false;
      setPreviewUri(null);
      // 关闭预览后恢复相机
      setActive(true);
    });
  }, [overlayAnim, recognizing]);

  const onConfirmRecognize = useCallback(async () => {
    if (!previewUri || recognizing) return;
    setRecognizing(true);
    try {
      const scanResults = await BarcodeScanning.scan(previewUri);
      const first = Array.isArray(scanResults) && scanResults.length > 0 ? scanResults[0] : null;
      const value = first?.value || first?.rawValue || first?.data;
      if (value && isHttpUrl(value)) {
        // 先收起预览，再跳转
        await new Promise((resolve) => {
          Animated.timing(overlayAnim, {
            toValue: 0,
            duration: 160,
            useNativeDriver: true,
          }).start(() => {
            setPreviewMount(false);
            previewOpenRef.current = false;
            resolve();
          });
        });
        navigateToUrl(value);
      } else {
        // 未识别到有效链接，返回相机并提示
        closePreview();
        showWarning('图中未识别到二维码');
      }
    } catch (_) {
      // 出错也返回相机并提示
      closePreview();
      showWarning('图中未识别到二维码');
    } finally {
      setRecognizing(false);
    }
  }, [previewUri, recognizing, navigateToUrl, closePreview, overlayAnim]);

  // 预览期重置加载与动画
  useEffect(() => {
    if (previewMount) {
      setImgLoaded(false);
      previewAnim.setValue(0);
    }
  }, [previewMount, previewUri, previewAnim]);

  const onPreviewLoaded = useCallback(() => {
    setImgLoaded(true);
    Animated.timing(previewAnim, {
      toValue: 1,
      duration: 180,
      useNativeDriver: true,
    }).start();
  }, [previewAnim]);

  // 统一 overlay 判定，提升可读性
  const overlayVisible = !previewMount;

  if (!device) {
    return (
      <View style={styles.center}>
        <ActivityIndicator />
      </View>
    );
  }

  if (!hasPermission) {
    return (
      <View style={styles.center}>
        <ActivityIndicator />
      </View>
    );
  }

  return (
    <View style={styles.container}>
      <CustomHeader headerShown={false} />
      {/* Camera */}
      {canRender && (
        <Camera
          style={StyleSheet.absoluteFill}
          device={device}
          isActive={active && !previewMount}
          codeScanner={active && scannerEnabled && !previewMount ? codeScanner : undefined}
          torch={torch}
          onInitialized={() => {
            setCameraReady(true);
            setScannerEnabled(true);
          }}
        />
      )}
      {/* Lottie 扫描动画覆盖在相机上方（使用主题色着色） */}
      {overlayVisible && active && cameraReady && canRender && (
        <View pointerEvents="none" style={styles.lottieContainer}>
          <LottieView
            source={cameraScanJson}
            autoPlay
            loop
            resizeMode="contain"
            style={styles.lottieAnimation}
          />
        </View>
      )}

      {/* 底部控制面板（相机操作区）：相册 + 闪光灯，仅图标 */}
      {overlayVisible && (
        <View style={[styles.controlPanel, { paddingBottom: insets.bottom }]}> 
          <View style={styles.controlsRow}>
            <Animated.View
              style={[
                styles.controlBtn,
                {
                  transform: [
                    { scale: flashAnim.interpolate({ inputRange: [0, 1], outputRange: [1, 1.06] }) },
                  ],
                  opacity: flashAnim.interpolate({ inputRange: [0, 1], outputRange: [0.95, 1] }),
                },
              ]}
            >
              <Pressable
                onPress={() => setTorch((prev) => (prev === 'on' ? 'off' : 'on'))}
                style={styles.btnInner}
                android_ripple={{ color: 'rgba(255,255,255,0.18)', borderless: true }}
              >
                <Ionicons name={torch === 'on' ? 'flash' : 'flash-off'} size={24} color="#fff" />
              </Pressable>
            </Animated.View>
            <View style={styles.controlBtn}>
              <Pressable
                onPress={onPickFromAlbum}
                style={styles.btnInner}
                android_ripple={{ color: 'rgba(255,255,255,0.18)', borderless: true }}
              >
                <Ionicons name="image-outline" size={24} color="#fff" />
              </Pressable>
            </View>
          </View>
        </View>
      )}


      {/* 自定义透明导航栏：返回 + 居中标题 */}
      {overlayVisible && (
        <View pointerEvents="box-none" style={[styles.headerOverlay, { paddingTop: insets.top }]}> 
          <View style={styles.headerBar}>
            <Pressable
              onPress={() => {
                handledRef.current = true;
                 // 停止并归零闪光灯动画，关闭闪光灯并暂停摄像头，再执行返回
                 try { flashAnim.stopAnimation(); } catch (_) {}
                 flashAnim.setValue(0);
                 setTorch('off');
                 setActive(false);
                 setTimeout(() => {
                   try { router.back(); } catch (_) {}
                 }, 60);
               }}
               style={styles.backBtn}
               hitSlop={10}
             >
               <Ionicons name="chevron-back" size={24} color="#fff" />
             </Pressable>
             <CustomText style={styles.headerTitle}>扫一扫</CustomText>
           </View>
         </View>
       )}

      {/* 预览大图覆盖层（替代 Modal） */}
      {previewMount && (
        <Animated.View
          pointerEvents="auto"
          style={[styles.previewOverlay, { opacity: overlayAnim }]}
        >
          <View style={[styles.previewHeader, { paddingTop: insets.top }]}> 
            <View style={[styles.headerBar, styles.previewHeaderBar]}>
              <Pressable
                onPress={closePreview}
                style={styles.backBtn}
                hitSlop={10}
              >
                <Ionicons name="chevron-back" size={24} color="#111" />
              </Pressable>
              <Pressable
                onPress={onConfirmRecognize}
                style={styles.confirmBtn}
                hitSlop={10}
              >
                {recognizing ? (
                  <ActivityIndicator color="#111" />
                ) : (
                  <CustomText style={styles.confirmText}>确认</CustomText>
                )}
              </Pressable>
            </View>
          </View>
          <View style={styles.previewContent}>
            <View style={styles.previewImageWrap}>
              <Animated.View
                style={[
                  styles.previewImageInner,
                  {
                    opacity: previewAnim,
                    transform: [
                      {
                        scale: previewAnim.interpolate({
                          inputRange: [0, 1],
                          outputRange: [0.98, 1],
                        }),
                      },
                    ],
                  },
                ]}
              >
                <ExpoImage
                  source={{ uri: previewUri }}
                  style={styles.previewImage}
                  contentFit="contain"
                  contentPosition="center"
                  transition={120}
                  cachePolicy="memory-disk"
                  onLoad={onPreviewLoaded}
                />
              </Animated.View>
              {!imgLoaded && (
                <ActivityIndicator color="#fff" size="large" style={styles.previewLoading} />
              )}
            </View>
          </View>
        </Animated.View>
      )}
    </View>
  );
};

export default React.memo(ScanScreen);

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#000',
  },
  center: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center',
    backgroundColor: '#000',
  },
  controlPanel: {
    position: 'absolute',
    left: 0,
    right: 0,
    bottom: 0,
    height: '26%',
    backgroundColor: 'rgba(0,0,0,0.5)',
    justifyContent: 'center',
  },
  controlsRow: {
    zIndex: 1,
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'space-evenly',
    paddingHorizontal: 24,
   },
  controlBtn: {
    width: 56,
    height: 56,
    borderRadius: 28,
    backgroundColor: 'rgba(255,255,255,0.12)',
    alignItems: 'center',
    justifyContent: 'center',
    overflow: 'hidden',
  },
  btnInner: {
    flex: 1,
    width: '100%',
    height: '100%',
    alignItems: 'center',
    justifyContent: 'center',
  },
  headerOverlay: {
    position: 'absolute',
    top: 0,
    left: 0,
    right: 0,
  },
  headerBar: {
    height: 44,
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'center',
  },

  previewHeaderBar: {
    backgroundColor: '#fff',
    borderBottomColor: 'rgba(0,0,0,0.06)',
    borderBottomWidth: StyleSheet.hairlineWidth,
  },
  backBtn: {
    position: 'absolute',
    left: 16,
    width: 44,
    height: 44,
    alignItems: 'center',
    justifyContent: 'center',
  },
  confirmBtn: {
    position: 'absolute',
    right: 16,
    width: 44,
    height: 44,
    alignItems: 'center',
    justifyContent: 'center',
  },
  confirmText: {
    color: '#111',
    fontSize: 16,
    fontFamily: 'AlibabaPuHuiTi-SemiBold',
  },
  headerTitle: {
    color: '#fff',
    fontSize: 17,
    fontFamily: 'AlibabaPuHuiTi-Bold',
    lineHeight: 24,
  },
  previewOverlay: {
    position: 'absolute',
    top: 0,
    right: 0,
    bottom: 0,
    left: 0,
    backgroundColor: '#000',
  },
  previewHeader: {
    backgroundColor: '#fff',
  },
  previewContent: {
    flex: 1,
    overflow: 'hidden',
    backgroundColor: '#000',
  },
  previewImageWrap: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center',
    backgroundColor: '#000',
  },
  previewImageInner: {
    width: '100%',
    height: '100%',
    alignItems: 'center',
    justifyContent: 'center',
  },
  previewImage: {
    width: '100%',
    height: '100%',
  },
  previewLoading: {
    position: 'absolute',
  },
  lottieContainer: {
    position: 'absolute',
    top: 0,
    left: 0,
    right: 0,
    bottom: '15%',
  },
  lottieAnimation: {
    flex: 1,
  },
});