import { useCallback, useEffect, useRef, useState } from 'react';
import { Alert, Image, PermissionsAndroid, Platform, TextInput, TouchableOpacity, View, Linking } from 'react-native';
import { useStyles } from './styles';
import { SafeAreaView } from 'react-native-safe-area-context';
import { useNavigation, useRoute } from '@react-navigation/native';
import useImagePicker from '../../../hooks/useImagePicker';
import { arrowDown, close } from '../../../../core/assets/icons';
import { SvgXml } from 'react-native-svg';
import { Typography } from '../../../../core/components/Typography/Typography';
import { useTheme } from 'react-native-paper';
import { useBottomSheet } from '../../../../core/stores/slices/bottomSheetSlice';
import { CircularProgressIndicator } from '../../../components/CircularProgressIndicator';
import { PostRepository, RoomRepository } from '@amityco/ts-sdk-react-native';
import Button from '../../../components/Button/Button';
import { useRequestPermission } from '../../../hooks/useCamera';
import NetInfo from '@react-native-community/netinfo';
import { RoomStatus } from '../../../enums/roomStatus';
import { AmityThumbnailActionComponent } from '../components/ThumbnailAction';
import { StartLivestreamButton } from '../../../elements/StartLivestreamButton';
import LiveStreamStartingThumbnail from '../../../components/LivestreamContent/LivestreamStartingThumbnail';
import { PageID } from '../../../enums';
import { useShareableLink } from '../../../../core/hooks/useShareableLink';
import { ShareableLinkModel } from '../../../types';
import { useCommunity } from '../../../hooks/useCommunity';
import MenuButton from '../../../elements/MenuButton/MenuButton';
import { CopyLinkAction } from '../../../elements/CopyLinkAction';
import { ShareAction } from '../../../elements/ShareAction';
import { LiveTimerStatus } from '../../../elements/LiveTimerStatus';
import { CancelCreateLivestreamButton } from '../../../elements/CancelCreateLivestreamButton';
import { EndLiveStreamButton } from '../../../elements/EndLiveStreamButton';
import { AddThumbnailButton } from '../../../elements/AddThumbnailButton';
import { SwitchCameraButton } from '../../../elements/SwitchCameraButton';
import { Track } from 'livekit-client';
import { LiveKitRoom, registerGlobals } from '@livekit/react-native';
import { RoomView } from './RoomView';
import { Camera, useCameraDevice } from 'react-native-vision-camera';
import { useRoomSubscription } from '../../../hooks/useRoomSubscription';
import { useToast } from '../../../../core/stores/slices/toastSlice';
import { usePostSubscription } from '../../../hooks';
import { useRoom } from '../../room/hooks/useRoom';

// Register WebRTC globals required for LiveKit
registerGlobals();
const serverUrl = 'wss://sp-live-3tr59jrk.livekit.cloud';
const calculateTime = time => {
  const hours = Math.floor(time / 3600000);
  const minutes = Math.floor(time / 60000);
  const seconds = (time % 60000 / 1000).toFixed(0);
  const hoursString = `${hours < 10 ? '0' : ''}${hours}`;
  const minutesString = `${minutes < 10 ? '0' : ''}${minutes}`;
  const secondsString = `${Number(seconds) < 10 ? '0' : ''}${seconds}`;
  return `${hours > 0 ? hoursString + ':' : ''}${minutesString}:${secondsString}`;
};
function AmityCreateLivestreamPage() {
  const styles = useStyles();
  const navigation = useNavigation();
  const theme = useTheme();
  const route = useRoute();
  const [time, setTime] = useState(0);
  const [title, setTitle] = useState('');
  const [isLive, setIsLive] = useState(false);
  const [description, setDescription] = useState('');
  const [isEnding, setIsEnding] = useState(false);
  const [countdown, setCountdown] = useState(null);
  const [post, setPost] = useState(null);
  const [roomId, setRoomId] = useState('');
  const timerRef = useRef(null);
  const connectionLossTimeoutRef = useRef(null);
  const [isConnecting, setIsConnecting] = useState(false);
  const [androidPermission, setAndroidPermission] = useState(false);
  const [iOSPermission, setIOSPermission] = useState(true);
  const [reconnecting, setReconnecting] = useState(false);
  const [livekitParticipant, setLivekitParticipant] = useState(null);
  const [isFrontCamera, setIsFrontCamera] = useState(true);
  const [roomToken, setRoomToken] = useState(null);
  const unsubscribeRef = useRef(null);
  const room = useRoom(roomId);
  useRoomSubscription({
    room
  });
  const {
    subscribedPost
  } = usePostSubscription((post === null || post === void 0 ? void 0 : post.postId) || '');
  const {
    showToast
  } = useToast();
  const frontCamera = useCameraDevice('front');
  const backCamera = useCameraDevice('back');
  const cameraDevice = isFrontCamera ? frontCamera : backCamera;
  const {
    imageUri,
    isLoading,
    progress,
    uploadedImage,
    removeSelectedImage,
    openImageGallery
  } = useImagePicker();
  const {
    targetId,
    targetType,
    targetName,
    pop
  } = route.params;
  const {
    openBottomSheet,
    closeBottomSheet,
    bottomSheetHeight
  } = useBottomSheet();
  const {
    getShareLink
  } = useShareableLink();
  const {
    community
  } = useCommunity(targetType === 'community' ? targetId : undefined);
  const canShare = targetType === 'user' || targetType === 'community' && (community === null || community === void 0 ? void 0 : community.isPublic) === true;
  const shareLink = roomId && canShare ? getShareLink(ShareableLinkModel.livestreams, roomId) : null;
  const handleSharePress = () => {
    if (!shareLink) return;
    openBottomSheet({
      height: bottomSheetHeight[2],
      dark: true,
      content: /*#__PURE__*/React.createElement(View, null, /*#__PURE__*/React.createElement(CopyLinkAction, {
        dark: true,
        link: shareLink,
        pageId: PageID.create_livestream_page
      }), /*#__PURE__*/React.createElement(ShareAction, {
        dark: true,
        link: shareLink,
        pageId: PageID.create_livestream_page
      }))
    });
  };
  const disabled = !(title !== null && title !== void 0 && title.trim()) || isConnecting || isLoading;
  const hasPermission = Platform.OS === 'android' && androidPermission || Platform.OS === 'ios' && iOSPermission;
  const fourHours = 4 * 60 * 60 * 1000; // 4 hours
  const countdownStart = fourHours - 10 * 1000; // Start countdown 10 seconds before end
  const toastTriggerTime = fourHours - 3 * 60 * 1000; // Show toast 3 minutes before end

  const switchCamera = useCallback(async () => {
    if (isLive && livekitParticipant) {
      try {
        const cameraPublication = livekitParticipant.getTrackPublication(Track.Source.Camera);
        if (cameraPublication !== null && cameraPublication !== void 0 && cameraPublication.track) {
          const videoTrack = cameraPublication.track;

          // Stop current camera
          await videoTrack.stop();

          // Get new facing mode
          const newFacingMode = isFrontCamera ? 'environment' : 'user';

          // Restart camera with new facing mode
          await videoTrack.restartTrack({
            facingMode: newFacingMode
          });

          // Toggle the camera state
          setIsFrontCamera(prev => !prev);
        }
      } catch (error) {
        console.error('Failed to switch camera:', error);
      }
    } else {
      // Just toggle the camera state for preview
      setIsFrontCamera(prev => !prev);
    }
  }, [livekitParticipant, isFrontCamera, isLive]);
  useRequestPermission({
    shouldCall: Platform.OS === 'ios',
    onRequestPermissionFailed: callback => {
      setTimeout(() => {
        callback && callback();
        setIOSPermission(false);
      }, 700);
    }
  });
  const checkPermissionAndroid = useCallback(async () => {
    try {
      const cameraPermission = await PermissionsAndroid.request(PermissionsAndroid.PERMISSIONS.CAMERA, {
        title: `App Would Like to Access the Camera`,
        message: 'Allow camera access so you can take pictures, record video and share live streams to your community.',
        buttonNegative: "Don't Allow",
        buttonPositive: 'Allow'
      });
      const microphonePermission = await PermissionsAndroid.request(PermissionsAndroid.PERMISSIONS.RECORD_AUDIO, {
        title: `App Would Like to Access the Microphone`,
        message: 'Allow camera access so you can take pictures, record video and share live streams to your community.',
        buttonNegative: "Don't Allow",
        buttonPositive: 'Allow'
      });
      if (cameraPermission !== PermissionsAndroid.RESULTS.GRANTED || microphonePermission !== PermissionsAndroid.RESULTS.GRANTED) {
        setAndroidPermission(false);
      }
      if (cameraPermission === PermissionsAndroid.RESULTS.GRANTED && microphonePermission === PermissionsAndroid.RESULTS.GRANTED) setAndroidPermission(true);
    } catch (err) {
      console.warn(err);
    }
  }, []);
  const onGoLive = async () => {
    try {
      setIsLive(true);
      setIsConnecting(true);
      const {
        data: newStream
      } = await RoomRepository.createRoom({
        title,
        description: description || undefined,
        thumbnailFileId: uploadedImage === null || uploadedImage === void 0 ? void 0 : uploadedImage.fileId,
        type: 'coHosts'
      });
      setRoomId(newStream.roomId);
      if (newStream) {
        const roomTokenResponse = await RoomRepository.getBroadcasterData(newStream.roomId);
        setRoomToken(roomTokenResponse);
        const params = {
          targetId,
          targetType,
          dataType: 'room',
          data: {
            text: `${newStream.title}${newStream.description ? `\n\n${newStream.description}` : ''}`,
            roomId: newStream.roomId
          }
        };
        const newPost = await PostRepository.createPost(params);
        setPost(newPost.data);

        // Do NOT set isConnecting to false here — keep the loading overlay
        // visible until LiveKitRoom fires onConnected, which confirms the
        // video stream is ready. Clearing it prematurely exposes the white
        // background before the camera feed appears (PDT-3089).

        // Start the timer when live stream actually starts
        if (timerRef.current) {
          clearInterval(timerRef.current);
        }
        const intervalId = setInterval(() => {
          setTime(prev => prev + 1000);
        }, 1000);
        timerRef.current = intervalId;
      }
    } catch (error) {
      setIsLive(false);
      setIsConnecting(false);
      Alert.alert('Cannot start live stream', 'Something went wrong while trying to complete your request. Please try again.', [{
        text: 'OK'
      }]);
    }
  };
  const confirmEndStreamAlert = () => {
    Alert.alert('End live stream?', 'If you end your live stream, it will also end for all your viewers.', [{
      text: 'Cancel',
      style: 'cancel'
    }, {
      style: 'destructive',
      text: 'End',
      onPress: () => {
        endLiveStream();
      }
    }]);
  };
  const endLiveStream = useCallback(async (showEndPopup = false) => {
    if (room) {
      setIsEnding(true);
      try {
        await RoomRepository.stopRoom(room.roomId);
      } catch (e) {
        console.log('disposeStream error', e);
      } finally {
        setIsLive(false);
        setRoomId('');
        setTitle('');
        setDescription('');
        setTime(0);
        if (timerRef.current) {
          clearInterval(timerRef.current);
          timerRef.current = null;
        }
        setIsEnding(false);
        setReconnecting(false);
        navigation.navigate('PostDetail', {
          postId: post === null || post === void 0 ? void 0 : post.postId,
          showEndPopup
        });
      }
    }
  }, [post, room, navigation]);
  useEffect(() => {
    // Show toast when 3 minutes left
    if (room && time >= toastTriggerTime && time < toastTriggerTime + 1000) {
      showToast({
        type: 'informative',
        message: 'Your live will automatically end once it reaches 4-hour limit.',
        duration: 3000,
        bottomPosition: 96
      });
    }
    if (room && time >= fourHours) {
      endLiveStream(true);
      setCountdown(null);
    } else if (room && time >= countdownStart && time < fourHours) {
      // Calculate countdown from 10 to 0
      const remaining = Math.ceil((fourHours - time) / 1000);
      setCountdown(remaining);
    } else {
      setCountdown(null);
    }
  }, [endLiveStream, room, time, showToast, toastTriggerTime, fourHours, countdownStart]);
  useEffect(() => {
    if (Platform.OS === 'android') checkPermissionAndroid();
  }, [checkPermissionAndroid]);
  useEffect(() => {
    NetInfo.fetch().then(state => {
      setReconnecting(!state.isConnected);
    });
    let unsubscribe = NetInfo.addEventListener(state => {
      setReconnecting(!state.isConnected);
    });
    return () => unsubscribe();
  }, []);
  useEffect(() => {
    if (reconnecting && (room === null || room === void 0 ? void 0 : room.status) === RoomStatus.live) {
      connectionLossTimeoutRef.current = setTimeout(() => {
        endLiveStream();
      }, 1000 * 60 * 3);
    } else {
      if (connectionLossTimeoutRef.current) {
        clearTimeout(connectionLossTimeoutRef.current);
        connectionLossTimeoutRef.current = null;
      }
    }
    return () => {
      if (connectionLossTimeoutRef.current) {
        clearTimeout(connectionLossTimeoutRef.current);
        connectionLossTimeoutRef.current = null;
      }
    };
  }, [reconnecting, endLiveStream, room === null || room === void 0 ? void 0 : room.status]);
  useEffect(() => {
    if ((room === null || room === void 0 ? void 0 : room.status) === RoomStatus.terminated) {
      navigation.replace('LivestreamTerminated', {
        type: 'streamer'
      });
    }
  }, [room === null || room === void 0 ? void 0 : room.status, navigation]);
  useEffect(() => {
    if (room !== null && room !== void 0 && room.isDeleted || subscribedPost !== null && subscribedPost !== void 0 && subscribedPost.isDeleted) {
      navigation.replace('PostDetail', {
        postId: subscribedPost === null || subscribedPost === void 0 ? void 0 : subscribedPost.postId
      });
    }
  }, [navigation, room === null || room === void 0 ? void 0 : room.isDeleted, subscribedPost === null || subscribedPost === void 0 ? void 0 : subscribedPost.postId, subscribedPost === null || subscribedPost === void 0 ? void 0 : subscribedPost.isDeleted]);
  useEffect(() => {
    const unsubscribe = unsubscribeRef.current;
    return () => {
      unsubscribe && unsubscribe();
    };
  }, []);
  return /*#__PURE__*/React.createElement(SafeAreaView, {
    style: styles.container
  }, (!isLive || isLive && reconnecting && !isEnding || isEnding) && /*#__PURE__*/React.createElement(View, {
    style: [styles.overlay, !hasPermission && styles.noPermissionOverlay]
  }), isLive && isConnecting && /*#__PURE__*/React.createElement(View, {
    style: styles.startingContainer
  }, /*#__PURE__*/React.createElement(LiveStreamStartingThumbnail, null)), hasPermission ? roomToken ? /*#__PURE__*/React.createElement(LiveKitRoom, {
    serverUrl: serverUrl,
    token: roomToken.coHostToken,
    connect: true,
    options: {
      adaptiveStream: {
        pixelDensity: 'screen'
      }
    },
    audio: {
      echoCancellation: true,
      noiseSuppression: true,
      autoGainControl: true
    },
    video: {
      facingMode: isFrontCamera ? 'user' : 'environment'
    },
    onConnected: () => {
      setIsConnecting(false);
      setReconnecting(false);
    },
    onDisconnected: () => {
      setReconnecting(true);
    }
  }, /*#__PURE__*/React.createElement(View, {
    style: styles.cameraContainer
  }, /*#__PURE__*/React.createElement(View, {
    style: styles.camera
  }, !isConnecting && /*#__PURE__*/React.createElement(RoomView, {
    onLocalParticipantReady: setLivekitParticipant,
    isFrontCamera: isFrontCamera
  })))) : /*#__PURE__*/React.createElement(View, {
    style: styles.cameraContainer
  }, /*#__PURE__*/React.createElement(View, {
    style: styles.camera
  }, cameraDevice && /*#__PURE__*/React.createElement(Camera
  // eslint-disable-next-line react-native/no-inline-styles
  , {
    style: {
      flex: 1
    },
    device: cameraDevice,
    isActive: !isConnecting
  }))) : /*#__PURE__*/React.createElement(View, {
    style: styles.permission
  }, /*#__PURE__*/React.createElement(Typography.TitleBold, {
    style: styles.permissionTitle
  }, "Allow access to your ", '\n', " camera and microphone"), /*#__PURE__*/React.createElement(Typography.Body, {
    style: styles.permissionDescription
  }, "This lets you record and live stream ", '\n', " from this device."), /*#__PURE__*/React.createElement(Button, {
    type: "primary",
    onPress: () => Linking.openSettings()
  }, /*#__PURE__*/React.createElement(Typography.BodyBold, {
    style: styles.text
  }, "Open settings"))), isEnding && /*#__PURE__*/React.createElement(View, {
    style: styles.connecting
  }, /*#__PURE__*/React.createElement(CircularProgressIndicator, {
    size: 40,
    strokeWidth: 2
  }), /*#__PURE__*/React.createElement(Typography.TitleBold, {
    style: styles.text
  }, "Ending live stream")), isLive ? isConnecting ? null : /*#__PURE__*/React.createElement(React.Fragment, null, !isEnding && reconnecting && /*#__PURE__*/React.createElement(View, {
    style: styles.connecting
  }, /*#__PURE__*/React.createElement(CircularProgressIndicator, {
    size: 40,
    strokeWidth: 2
  }), /*#__PURE__*/React.createElement(Typography.TitleBold, {
    style: styles.text
  }, "Reconnecting"), /*#__PURE__*/React.createElement(Typography.Caption, {
    style: styles.reconnectingText
  }, "Due to poor connection, this live stream has been ", '\n', ' ', "paused. It will resume automatically ", '\n', " once the connection is stable.")), /*#__PURE__*/React.createElement(TouchableOpacity, {
    style: styles.closeButton,
    onPress: () => confirmEndStreamAlert()
  }, /*#__PURE__*/React.createElement(SvgXml, {
    xml: close(),
    width: "28",
    height: "28",
    color: theme.colors.background
  })), /*#__PURE__*/React.createElement(View, {
    style: styles.liveRow
  }, /*#__PURE__*/React.createElement(LiveTimerStatus, {
    time: calculateTime(time),
    pageId: PageID.create_livestream_page
  }), shareLink && /*#__PURE__*/React.createElement(MenuButton, {
    pageId: PageID.create_livestream_page,
    variant: "vertical",
    onPress: handleSharePress
  })), countdown !== null && /*#__PURE__*/React.createElement(View, {
    style: styles.countdownOverlay
  }, /*#__PURE__*/React.createElement(View, {
    style: styles.countdownContainer
  }, /*#__PURE__*/React.createElement(Typography.TitleBold, {
    style: styles.countdownText
  }, "Live stream ends in"), /*#__PURE__*/React.createElement(View, {
    style: styles.countdownCircle
  }, /*#__PURE__*/React.createElement(CircularProgressIndicator, {
    size: 64,
    strokeWidth: 2,
    progress: (10 - countdown) / 10 * 100
  }), /*#__PURE__*/React.createElement(View, {
    style: styles.countdownNumberContainer
  }, /*#__PURE__*/React.createElement(Typography, {
    style: styles.countdownNumber
  }, countdown)))))) : /*#__PURE__*/React.createElement(View, {
    style: styles.content
  }, /*#__PURE__*/React.createElement(View, null, /*#__PURE__*/React.createElement(View, {
    style: styles.header
  }, /*#__PURE__*/React.createElement(CancelCreateLivestreamButton, {
    pageId: PageID.create_livestream_page,
    onPress: () => {
      if (title !== null && title !== void 0 && title.trim()) return Alert.alert('Unsaved changes', 'Are you sure you want to discard the changes? They will be lost when you leave this page.', [{
        text: 'Cancel',
        style: 'cancel'
      }, {
        text: 'Discard',
        style: 'destructive',
        onPress: () => {
          navigation.goBack();
          if (pop === 2) navigation.goBack();
        }
      }]);
      navigation.goBack();
      if (pop === 2) navigation.goBack();
    }
  }), /*#__PURE__*/React.createElement(TouchableOpacity, {
    style: styles.communityButton,
    onPress: () => {
      const state = navigation.getState();
      const routes = state.routes;
      const currentIndex = state.index;
      const previousRoute = routes[currentIndex - 1];
      if ((previousRoute === null || previousRoute === void 0 ? void 0 : previousRoute.name) === 'LivestreamPostTargetSelection') {
        navigation.goBack();
      } else {
        return;
      }
    },
    activeOpacity: 0.7
  }, /*#__PURE__*/React.createElement(Typography.Body, {
    style: styles.communityName,
    numberOfLines: 1,
    ellipsizeMode: "tail"
  }, "Live on", ' ', /*#__PURE__*/React.createElement(Typography.BodyBold, {
    numberOfLines: 1,
    ellipsizeMode: "tail",
    style: styles.communityName
  }, targetName)), /*#__PURE__*/React.createElement(View, null, /*#__PURE__*/React.createElement(SvgXml, {
    xml: arrowDown(),
    width: 16,
    height: 16,
    color: theme.colors.background
  })))), hasPermission && /*#__PURE__*/React.createElement(View, {
    style: styles.inputContainer
  }, /*#__PURE__*/React.createElement(TextInput, {
    style: styles.titleInput,
    placeholder: "Add live stream title...",
    numberOfLines: 1,
    maxLength: 30,
    placeholderTextColor: 'rgba(255, 255, 255, 0.8)',
    onChangeText: text => setTitle(text),
    value: title
  }), /*#__PURE__*/React.createElement(TextInput, {
    style: styles.descriptionInput,
    multiline: true,
    scrollEnabled: true,
    blurOnSubmit: true,
    placeholder: "Add description (optional)",
    placeholderTextColor: 'rgba(255, 255, 255, 0.8)',
    onChangeText: text => setDescription(text),
    value: description
  }))), /*#__PURE__*/React.createElement(View, {
    style: styles.goLiveContainer
  }, /*#__PURE__*/React.createElement(StartLivestreamButton, {
    onPress: onGoLive,
    disabled: disabled,
    pageId: PageID.create_livestream_page
  }))), /*#__PURE__*/React.createElement(View, {
    style: styles.footer
  }, isLive && !isConnecting && /*#__PURE__*/React.createElement(EndLiveStreamButton, {
    onPress: confirmEndStreamAlert,
    pageId: PageID.create_livestream_page
  }), isLive && isConnecting && /*#__PURE__*/React.createElement(View, null), !isLive && /*#__PURE__*/React.createElement(React.Fragment, null, imageUri || uploadedImage ? /*#__PURE__*/React.createElement(TouchableOpacity, {
    activeOpacity: 0.7,
    style: styles.thumbnailButton,
    onPress: () => {
      openBottomSheet({
        height: 200,
        content: /*#__PURE__*/React.createElement(AmityThumbnailActionComponent, {
          onChangeThumbnail: () => {
            closeBottomSheet();
            openImageGallery({
              selectionLimit: 1,
              mediaType: 'photo',
              includeBase64: false
            });
          },
          onDeleteThumbnail: () => {
            closeBottomSheet();
            removeSelectedImage();
          }
        })
      });
    }
  }, /*#__PURE__*/React.createElement(View, {
    style: styles.thumbnailImageContainer
  }, /*#__PURE__*/React.createElement(Image, {
    source: {
      uri: (uploadedImage === null || uploadedImage === void 0 ? void 0 : uploadedImage.fileUrl) || imageUri
    },
    style: styles.thumbnailImage
  }), isLoading && /*#__PURE__*/React.createElement(View, {
    style: styles.thumbnailLoader
  }, /*#__PURE__*/React.createElement(CircularProgressIndicator, {
    size: 24,
    strokeWidth: 2,
    progress: progress
  })))) : /*#__PURE__*/React.createElement(AddThumbnailButton, {
    onPress: () => openImageGallery({
      selectionLimit: 1,
      mediaType: 'photo',
      includeBase64: false
    }),
    pageId: PageID.create_livestream_page
  })), /*#__PURE__*/React.createElement(SwitchCameraButton, {
    pageId: PageID.create_livestream_page,
    onPress: switchCamera
  })));
}
export default AmityCreateLivestreamPage;
//# sourceMappingURL=Create.js.map