/**
 * 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 { View, ScrollView, Text, StyleSheet } from 'react-native';
import { TestSuite, TestCase } from '@rnoh/testerino';
import React, { useState } from 'react';
import { Button } from '../../components';
import { StylesTest } from './StylesTest';
import { ContentContainerStyleTest } from './ContentContainerStyleTest';
import { ScrollBarsTest } from './ScrollBarsTest';
import { StickyHeadersTest } from './StickyHeadersTest';
import { PointerEventsTest } from './PointerEventsTest';
import { SnapTest } from './SnapTest';
import { MomentumCallbacksTest } from './MomentumCallbacksTest';
import { KeyboardTest } from './KeyboardTest';
import { MiscPropsTest } from './MiscPropsTest';
import { ScrollToTest } from './ScrollToTest';

export function ScrollViewTest() {
  return (
    <TestSuite name="ScrollView">
      <StylesTest />
      <ContentContainerStyleTest />
      <ScrollBarsTest />
      <StickyHeadersTest />
      <PointerEventsTest />
      <SnapTest />
      <MomentumCallbacksTest />
      <KeyboardTest />
      <ScrollToTest />
      <MiscPropsTest />
      <TestCase
        modal
        itShould="maintain scroll position when adding/removing elements">
        <AppendingList />
      </TestCase>
      <TestCase
        modal
        skip // https://gl.swmansion.com/rnoh/react-native-harmony/-/issues/498
        itShould="fill the remaining space of scroll view with yellow color but the element inside scroll view remains transparent">
        <ScrollViewEndFillColorTest />
      </TestCase>
    </TestSuite>
  );
}

const Item = (props: { label: string; mode: 'dark' | 'light' }) => {
  const stylesheet = StyleSheet.create({
    dark: {
      backgroundColor: '#47443D',
      color: 'white',
    },
    light: {
      backgroundColor: '#D9D0BB',
      color: 'black',
    },
    item: {
      height: 100,
    },
  });
  return (
    <View
      style={[
        props.mode === 'dark' ? stylesheet.dark : stylesheet.light,
        stylesheet.item,
      ]}>
      <Text>{props.label}</Text>
    </View>
  );
};

const ITEMS = Array.from({ length: 20 }, (_, index) => (
  <Item
    label={`Item${index}`}
    key={`item${index}`}
    mode={index % 2 ? 'light' : 'dark'}
  />
));
let itemCount = 20;
const AppendingList = () => {
  const [items, setItems] = useState<React.JSX.Element[]>(ITEMS);
  const styles = StyleSheet.create({
    scrollView: {
      width: 300,
      marginVertical: 50,
      height: 500,
    },
    row: {
      flexDirection: 'row',
    },
  });
  return (
    <View>
      <ScrollView
        automaticallyAdjustContentInsets={false}
        maintainVisibleContentPosition={{
          minIndexForVisible: 0,
          autoscrollToTopThreshold: 10,
        }}
        nestedScrollEnabled
        style={styles.scrollView}>
        {items.map((value, _index, _array) => React.cloneElement(value))}
      </ScrollView>
      <View style={styles.row}>
        <Button
          label="Add to top"
          onPress={() => {
            setItems(prev => {
              const idx = itemCount++;
              return [
                <Item
                  label={`added Item ${idx}`}
                  key={`item${idx}`}
                  mode={idx % 2 ? 'light' : 'dark'}
                />,
              ].concat(prev);
            });
          }}
        />
        <Button
          label="Remove top"
          onPress={() => {
            setItems(prev => prev.slice(1));
          }}
        />
      </View>
      <View style={styles.row}>
        <Button
          label="Add to end"
          onPress={() => {
            setItems(prev => {
              const idx = itemCount++;
              return prev.concat([
                <Item
                  label={`added Item ${idx}`}
                  key={`item${idx}`}
                  mode={idx % 2 ? 'light' : 'dark'}
                />,
              ]);
            });
          }}
        />
        <Button
          label="Remove end"
          onPress={() => {
            setItems(prev => prev.slice(0, -1));
          }}
        />
      </View>
    </View>
  );
};

function ScrollViewEndFillColorTest() {
  return (
    <View
      style={{
        backgroundColor: 'pink',
        width: '100%',
        justifyContent: 'center',
      }}>
      <View
        style={{
          height: 400,
          marginTop: 50,
          marginBottom: 50,
        }}>
        <ScrollView endFillColor={'yellow'}>
          <View
            style={{
              height: 100,
              borderWidth: 1,
              borderColor: '#000',
              padding: 10,
            }}>
            <Text>Content smaller than scroll view</Text>
          </View>
        </ScrollView>
      </View>
    </View>
  );
}