/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 *
 * @format
 */

import React, {useState} from 'react';
import {
  SafeAreaView,
  StyleSheet,
  ScrollView,
  View,
  Text,
  StatusBar,
  Button,
  TouchableOpacity,
} from 'react-native';

import {Header, Colors} from 'react-native/Libraries/NewAppScreen';

import Upload from 'react-native-background-upload';

const BASE = 'http://127.0.0.1:8765';
const RAW_FILE = 'internal://cache/upload-test.bin';
const MULTIPART_FILE = 'internal://cache/sample.jpg';

const url10SecDelayPut = `${BASE}/stall`;
const url5secDelayFail = `${BASE}/reject`;
const urlMultipart = `${BASE}/echo`;

function errorMessage(error) {
  if (error instanceof Error) {
    return error.message;
  }
  return String(error);
}

const App = () => {
  const [delay10Completed, set10SecDelayCompleted] = useState(false);
  const [delay5Completed, set5SecDelayCompleted] = useState(false);
  const [uploadId, setUploadId] = useState(null);
  const [progress, setProgress] = useState(null);
  const [lastResult, setLastResult] = useState('点下面的按钮开始上传');

  const listenUpload = (id, onCompleted, onError) => {
    Upload.addListener('progress', id, data => {
      if (typeof data.progress === 'number') {
        setProgress(data.progress);
      }
    });
    Upload.addListener('completed', id, data => {
      const code = data.responseCode ?? 0;
      setLastResult(`completed HTTP ${code}`);
      if (typeof onCompleted === 'function') {
        onCompleted(data);
      }
    });
    Upload.addListener('error', id, data => {
      setLastResult(`error: ${data.error ?? 'failed'}`);
      if (typeof onError === 'function') {
        onError(data);
      }
    });
    Upload.addListener('cancelled', id, () => {
      setLastResult(`cancelled ${id}`);
    });
  };

  const startRawUpload = (url, onCompleted, onError) => {
    setLastResult('正在启动上传...');
    set10SecDelayCompleted(false);
    Upload.startUpload({
      url,
      path: RAW_FILE,
      method: 'PUT',
      type: 'raw',
      notification: {enabled: true},
    })
      .then(id => {
        setUploadId(id);
        setProgress(0);
        setLastResult(`已启动 ${id}`);
        listenUpload(id, onCompleted, onError);
      })
      .catch(err => {
        setUploadId(null);
        setProgress(null);
        setLastResult(`启动失败: ${errorMessage(err)}`);
      });
  };

  const onPressUpload = () => {
    setLastResult('正在启动 multipart...');
    Upload.startUpload({
      url: urlMultipart,
      path: MULTIPART_FILE,
      method: 'POST',
      type: 'multipart',
      field: 'uploaded_media',
      notification: {enabled: true},
    })
      .then(id => {
        setUploadId(id);
        setProgress(0);
        setLastResult(`multipart 已启动 ${id}`);
        listenUpload(id, () => {
          setLastResult('multipart completed');
        });
      })
      .catch(err => {
        setUploadId(null);
        setProgress(null);
        setLastResult(`multipart 启动失败: ${errorMessage(err)}`);
      });
  };

  return (
    <>
      <StatusBar barStyle="dark-content" />
      <SafeAreaView testID="main_screen" style={styles.safeArea}>
        <ScrollView
          contentInsetAdjustmentBehavior="automatic"
          style={styles.scrollView}
        >
          <Header />
          {global.HermesInternal == null ? null : (
            <View style={styles.engine}>
              <Text style={styles.footer}>Engine: Hermes</Text>
            </View>
          )}
          <View style={styles.body}>
            <View style={styles.sectionContainer}>
              <TouchableOpacity
                testID="10_sec_delay_button"
                style={styles.actionButton}
                onPress={() => {
                  startRawUpload(url10SecDelayPut, ({responseCode}) => {
                    if (responseCode <= 299) {
                      set10SecDelayCompleted(true);
                    }
                  });
                }}
              >
                <Text style={styles.actionLabel}>10 Sec Delay Success</Text>
              </TouchableOpacity>

              {delay10Completed && (
                <View testID="10_sec_delay_completed">
                  <Text>Finished!!!</Text>
                </View>
              )}
            </View>
            <View style={styles.sectionContainer}>
              <TouchableOpacity
                testID="5_sec_delay_button"
                style={styles.actionButton}
                onPress={() => {
                  startRawUpload(
                    url5secDelayFail,
                    ({responseCode}) => {
                      if (responseCode === 502) {
                        set5SecDelayCompleted(true);
                      }
                    },
                    () => {
                      set5SecDelayCompleted(true);
                    },
                  );
                }}
              >
                <Text style={styles.actionLabel}>5 Sec Delay Error</Text>
              </TouchableOpacity>

              {delay5Completed && (
                <View testID="5_sec_delay_completed">
                  <Text>Finished!!!</Text>
                </View>
              )}

              <Button
                title="Tap To Upload Multipart"
                onPress={onPressUpload}
              />

              <View style={{height: 32}} />
              <Text style={{textAlign: 'center'}}>
                {`Current Upload ID: ${uploadId === null ? 'none' : uploadId}`}
              </Text>
              <Text style={{textAlign: 'center'}}>
                {`Progress: ${progress === null ? 'none' : `${progress}%`}`}
              </Text>
              <Text style={styles.result}>{lastResult}</Text>
              <View />
              <Button
                testID="cancel_button"
                title="Tap to Cancel Upload"
                onPress={() => {
                  if (!uploadId) {
                    setLastResult('没有可取消的任务');
                    return;
                  }
                  Upload.cancelUpload(uploadId)
                    .then(() => {
                      setLastResult(`已取消 ${uploadId}`);
                      setUploadId(null);
                      setProgress(null);
                    })
                    .catch(err => {
                      setLastResult(`取消失败: ${errorMessage(err)}`);
                    });
                }}
              />
            </View>
          </View>
        </ScrollView>
      </SafeAreaView>
    </>
  );
};

const styles = StyleSheet.create({
  safeArea: {
    flex: 1,
    backgroundColor: Colors.lighter,
  },
  scrollView: {
    backgroundColor: Colors.lighter,
  },
  engine: {
    position: 'absolute',
    right: 0,
  },
  body: {
    backgroundColor: Colors.white,
  },
  sectionContainer: {
    marginTop: 32,
    paddingHorizontal: 24,
  },
  actionButton: {
    paddingVertical: 12,
  },
  actionLabel: {
    fontSize: 16,
    color: '#007AFF',
  },
  result: {
    marginTop: 12,
    textAlign: 'center',
    color: '#175cd3',
    fontSize: 14,
  },
  footer: {
    color: Colors.dark,
    fontSize: 12,
    fontWeight: '600',
    padding: 4,
    paddingRight: 12,
    textAlign: 'right',
  },
});

export default App;