/**
 * Copyright (c) 2024 Huawei Technologies Co., Ltd.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE-MIT file in the root directory of this source tree.
 */

import {
  FlatList,
  Platform,
  RefreshControl,
  ScrollView,
  StyleSheet,
  Text,
  View,
} from 'react-native';
import { TestCase, TestSuite } from '@rnoh/testerino';
import { useEffect, useState } from 'react';

export const RefreshControlTest = () => {
  const [refreshKey, setRefreshKey] = useState(0);

  useEffect(() => {
    setInterval(() => setRefreshKey(prev => prev + 1), 1000);
  }, []);

  return (
    <TestSuite name="RefreshControl">
      <TestCase itShould="display refresh control every second">
        <ScrollView
          style={{ height: 128, backgroundColor: 'white' }}
          refreshControl={
            <RefreshControl
              refreshing={refreshKey % 2 === 0}
              onRefresh={() => { }}
            />
          }
        />
      </TestCase>
      <TestCase itShould="display refresh control with tintColor">
        <ScrollView
          style={{ height: 128, backgroundColor: 'white' }}
          refreshControl={
            <RefreshControl
              refreshing={refreshKey % 2 === 0}
              tintColor={'#FFC0CB'}
              onRefresh={() => { }}
            />
          }
        />
      </TestCase>
      <TestCase
        modal
        itShould="be refreshing for one second after pull to refresh">
        <PullToRefreshExample />
      </TestCase>
      <TestCase
        modal
        itShould="immediately stop refreshing after pulling to refresh">
        <PullToRefreshExample doNothingOnRefresh />
      </TestCase>
      <TestCase
        modal
        itShould="refresh with progressViewOffset = undefined"
        skip // there is a restriction on how tall the progress view can be - should be removed in API 11 https://gl.swmansion.com/rnoh/react-native-harmony/-/issues/624
      >
        <PullToRefreshProgressViewOffset />
      </TestCase>
      <TestCase
        modal
        itShould="refresh with progressViewOffset = 50"
        skip // there is a restriction on how tall the progress view can be - should be removed in API 11 https://gl.swmansion.com/rnoh/react-native-harmony/-/issues/624
      >
        <PullToRefreshProgressViewOffset progressViewOffset={50} />
      </TestCase>
      <TestCase
        modal
        itShould="refresh with progressViewOffset = 100"
        skip // there is a restriction on how tall the progress view can be - should be removed in API 11 https://gl.swmansion.com/rnoh/react-native-harmony/-/issues/624
      >
        <PullToRefreshProgressViewOffset progressViewOffset={100} />
      </TestCase>
      <TestCase
        itShould="display double refresh control for 2 seconds in nested scroll view"
        modal
        skip={Platform.select({ harmony: true, android: false })} // https://gl.swmansion.com/rnoh/react-native-harmony/-/issues/770
      >
        <PullToRefreshInNestedScrollViews />
      </TestCase>
      <TestCase
        itShould="display one refresh control - for 3 seconds in nested scroll view"
        modal>
        <PullToRefreshInNestedScrollViewsDifferentSource />
      </TestCase>
    </TestSuite>
  );
};

function PullToRefreshExample({
  doNothingOnRefresh,
}: {
  doNothingOnRefresh?: boolean;
}) {
  const [isRefreshing, setIsRefreshing] = useState(false);

  return (
    <FlatList
      style={{ height: 256 }}
      refreshing={isRefreshing}
      onRefresh={() => {
        if (!doNothingOnRefresh) {
          setIsRefreshing(true);
          setTimeout(() => setIsRefreshing(false), 1000);
        }
      }}
      data={[1, 2, 3, 4, 5]}
      renderItem={({ item }) => (
        <Text style={{ height: 96, borderBottomWidth: 1 }}>{item}</Text>
      )}
    />
  );
}

function PullToRefreshProgressViewOffset({
  progressViewOffset,
}: {
  progressViewOffset?: number;
}) {
  const [refreshing, setIsRefreshing] = useState(false);

  return (
    <ScrollView
      style={{ height: '90%', backgroundColor: 'lightgray' }}
      refreshControl={
        <RefreshControl
          refreshing={refreshing}
          onRefresh={() => {
            setIsRefreshing(true);
            setTimeout(() => setIsRefreshing(false), 3000);
          }}
          progressViewOffset={progressViewOffset}
        />
      }>
      <View style={{ height: 50, backgroundColor: 'lightblue' }}>
        <Text>First Content Component</Text>
      </View>
      <View style={{ height: 50, backgroundColor: 'lightgreen' }}>
        <Text>Second Content Component</Text>
      </View>
      <View style={{ height: 50, backgroundColor: 'lightblue' }}>
        <Text>Third Content Component</Text>
      </View>
    </ScrollView>
  );
}

const wait = (timeout: number) => {
  return new Promise(resolve => {
    setTimeout(resolve, timeout);
  });
};

const PullToRefreshInNestedScrollViews = () => {
  const [refreshing, setRefrehing] = useState(false);

  const onRefresh = () => {
    setRefrehing(true);
    wait(2000).then(() => {
      setRefrehing(false);
    });
  };

  return (
    <ScrollView
      contentContainerStyle={styles.scrollView}
      refreshControl={
        <RefreshControl refreshing={refreshing} onRefresh={onRefresh} />
      }>
      <Text>outer-scrollView</Text>
      <Text>outer-scrollView</Text>
      <Text>outer-scrollView</Text>
      <Text>outer-scrollView</Text>
      <Text>outer-scrollView</Text>
      <Text>outer-scrollView</Text>
      <ScrollView
        contentContainerStyle={{
          ...styles.scrollView,
          backgroundColor: 'white',
        }}
        refreshControl={
          <RefreshControl refreshing={refreshing} onRefresh={onRefresh} />
        }>
        <Text style={styles.text}>
          inner-scrollView Press and hold down the area to refresh. The refresh
          label does not bounce back
        </Text>
        <Text style={styles.text}>
          inner-scrollView Press and hold down the area to refresh. The refresh
          label does not bounce back
        </Text>
        <Text style={styles.text}>
          inner-scrollView Press and hold down the area to refresh. The refresh
          label does not bounce back
        </Text>
        <Text style={styles.text}>
          inner-scrollView 按住该区域下拉刷新,刷新标识不回弹回
        </Text>
        <Text style={styles.text}>
          inner-scrollView 按住该区域下拉刷新,刷新标识不回弹回
        </Text>
        <Text style={styles.text}>
          inner-scrollView 按住该区域下拉刷新,刷新标识不回弹回
        </Text>
        <Text style={styles.text}>
          inner-scrollView 按住该区域下拉刷新,刷新标识不回弹回
        </Text>
        <Text style={styles.text}>
          inner-scrollView 按住该区域下拉刷新,刷新标识不回弹回
        </Text>
        <Text style={styles.text}>
          inner-scrollView 按住该区域下拉刷新,刷新标识不回弹回
        </Text>
        <Text style={styles.text}>
          inner-scrollView Press and hold down the area to refresh. The refresh
          label does not bounce back
        </Text>
      </ScrollView>
    </ScrollView>
  );
};

const PullToRefreshInNestedScrollViewsDifferentSource = () => {
  const [firstRefreshing, setFirstRefrehing] = useState(false);
  const [secondRefreshing, setSecondRefrehing] = useState(false);

  const onFirstsRefresh = () => {
    setFirstRefrehing(true);
    wait(3000).then(() => {
      setFirstRefrehing(false);
    });
  };

  const onSecondRefresh = () => {
    setSecondRefrehing(true);
    wait(4000).then(() => {
      setSecondRefrehing(false);
    });
  };

  return (
    <ScrollView
      contentContainerStyle={styles.scrollView}
      refreshControl={
        <RefreshControl
          refreshing={firstRefreshing}
          onRefresh={onFirstsRefresh}
        />
      }>
      <Text>outer-scrollView</Text>
      <Text>outer-scrollView</Text>
      <Text>outer-scrollView</Text>
      <Text>outer-scrollView</Text>
      <Text>outer-scrollView</Text>
      <Text>outer-scrollView</Text>
      <ScrollView
        contentContainerStyle={{
          ...styles.scrollView,
          backgroundColor: 'white',
        }}
        refreshControl={
          <RefreshControl
            refreshing={secondRefreshing}
            onRefresh={onSecondRefresh}
          />
        }>
        <Text style={styles.text}>
          inner-scrollView Press and hold down the area to refresh. The refresh
          label does not bounce back
        </Text>
        <Text style={styles.text}>
          inner-scrollView Press and hold down the area to refresh. The refresh
          label does not bounce back
        </Text>
        <Text style={styles.text}>
          inner-scrollView Press and hold down the area to refresh. The refresh
          label does not bounce back
        </Text>
        <Text style={styles.text}>
          inner-scrollView 按住该区域下拉刷新,刷新标识不回弹回
        </Text>
        <Text style={styles.text}>
          inner-scrollView 按住该区域下拉刷新,刷新标识不回弹回
        </Text>
        <Text style={styles.text}>
          inner-scrollView 按住该区域下拉刷新,刷新标识不回弹回
        </Text>
        <Text style={styles.text}>
          inner-scrollView 按住该区域下拉刷新,刷新标识不回弹回
        </Text>
        <Text style={styles.text}>
          inner-scrollView 按住该区域下拉刷新,刷新标识不回弹回
        </Text>
        <Text style={styles.text}>
          inner-scrollView 按住该区域下拉刷新,刷新标识不回弹回
        </Text>
        <Text style={styles.text}>
          inner-scrollView Press and hold down the area to refresh. The refresh
          label does not bounce back
        </Text>
      </ScrollView>
    </ScrollView>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
  scrollView: {
    flex: 1,
    backgroundColor: 'pink',
    alignItems: 'center',
    justifyContent: 'center',
  },
  text: {
    backgroundColor: 'green',
  },
});