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

import {TestSuite} from '@rnoh/testerino';
import {
  View,
  ScrollView,
  StyleSheet,
  ScrollViewProps,
  Text,
} from 'react-native';
import {COMMON_PROPS} from './fixtures';
import React, {useRef} from 'react';
import {Button, TestCase} from '../../components';

export function ScrollToTest() {
  return (
    <TestSuite name="scrollTo">
      <TestCase.Example
        modal
        itShould="scroll down on button press (no animation)">
        <ScrollToTestCase animated={false} />
      </TestCase.Example>
      <TestCase.Example
        modal
        itShould="scroll down on button press (with animation)">
        <ScrollToTestCase animated={true} />
      </TestCase.Example>
      <TestCase.Manual
        modal
        itShould="call onScroll once when scrolling without animation"
        initialState={0}
        arrange={({setState}) => (
          <ScrollToTestCase
            animated={false}
            onScroll={() => setState(c => c + 1)}
          />
        )}
        assert={({state, expect}) => {
          expect(state).to.eq(1);
        }}
      />
      <TestCase.Manual
        modal
        itShould="call onScroll multiple times when scrolling with animation"
        initialState={0}
        arrange={AnimatedScrollToEventCountTestCase}
        assert={({state, expect}) => {
          expect(state).to.be.greaterThan(10);
        }}
      />
      <TestCase.Example
        modal
        itShould="scroll overflow top/bottom when clicking a button"
        skip={''} // iOS only - https://gl.swmansion.com/rnoh/react-native-harmony/-/issues/315
      >
        <ScrollToOverflowEnabledBasicTest />
      </TestCase.Example>
      <TestCase.Example
        modal
        itShould="scroll overflow left/right when clicking a button"
        skip={''} // iOS only - https://gl.swmansion.com/rnoh/react-native-harmony/-/issues/315
      >
        <ScrollToOverflowEnabledHorizontalTest />
      </TestCase.Example>
    </TestSuite>
  );
}

function ScrollToTestCase({
  animated,
  onScroll,
}: {animated: boolean} & ScrollViewProps) {
  const scrollToOffset = 600;
  const scrollRef = React.useRef<ScrollView>(null);

  const scrollTo = () => {
    scrollRef.current?.scrollTo({y: scrollToOffset, animated});
  };

  return (
    <View style={styles.wrapperView}>
      <ScrollView
        ref={scrollRef}
        {...COMMON_PROPS}
        onScroll={onScroll}
        scrollEnabled={false}
      />
      <Button label={`Scroll to ${scrollToOffset}`} onPress={scrollTo} />
    </View>
  );
}

function AnimatedScrollToEventCountTestCase({
  setState,
}: {
  setState: (state: number) => void;
}) {
  const counter = React.useRef(0);
  const done = React.useRef(false);

  return (
    <ScrollToTestCase
      animated
      onScroll={e => {
        counter.current += 1;
        if (!done.current && e.nativeEvent.contentOffset.y >= 600) {
          setState(counter.current);
          done.current = true;
        }
      }}
      scrollEnabled={false}
    />
  );
}

function ScrollToOverflowEnabledBasicTest() {
  const scrollViewRef = useRef<ScrollView>(null);

  const scrollToY = (y: number) => {
    if (scrollViewRef.current) {
      scrollViewRef.current.scrollTo({y, animated: true});
    }
  };

  return (
    <View style={{height: 500, backgroundColor: 'deepskyblue'}}>
      <ScrollView
        ref={scrollViewRef}
        scrollToOverflowEnabled={true}
        contentContainerStyle={{padding: 10}}>
        <View style={[styles.contentView, {backgroundColor: 'lightgreen'}]}>
          <Text style={{textAlign: 'center'}}>Some other content</Text>
        </View>
        <View style={[styles.contentView, {backgroundColor: 'lightblue'}]}>
          <Text style={{textAlign: 'center'}}>Some other content</Text>
        </View>
      </ScrollView>
      <View style={{flexDirection: 'column'}}>
        <Button
          label="Scroll to overflow top by 100px"
          onPress={() => scrollToY(-100)}
        />
        <Button
          label="Scroll to overlow bottom by 500px"
          onPress={() => scrollToY(500)}
        />
        <Button
          label="Scroll to Reset (starting point)"
          onPress={() => scrollToY(0)}
        />
      </View>
    </View>
  );
}

function ScrollToOverflowEnabledHorizontalTest() {
  const scrollViewRef = useRef<ScrollView>(null);

  const scrollToX = (x: number) => {
    if (scrollViewRef.current) {
      scrollViewRef.current.scrollTo({x, animated: true});
    }
  };

  return (
    <View style={{height: 500, backgroundColor: 'deepskyblue'}}>
      <ScrollView
        ref={scrollViewRef}
        horizontal
        scrollToOverflowEnabled={true}
        contentContainerStyle={{padding: 10}}>
        <View
          style={[
            styles.horizontalContentView,
            {backgroundColor: 'lightgreen'},
          ]}>
          <Text style={{textAlign: 'center'}}>Some other content</Text>
        </View>
        <View
          style={[
            styles.horizontalContentView,
            {backgroundColor: 'lightblue'},
          ]}>
          <Text style={{textAlign: 'center'}}>Some other content</Text>
        </View>
      </ScrollView>
      <View style={{flexDirection: 'column'}}>
        <Button
          label="Scroll to overflow left by 100px"
          onPress={() => scrollToX(-100)}
        />
        <Button
          label="Scroll to overflow right by 1000px"
          onPress={() => scrollToX(100)}
        />
        <Button
          label="Scroll to Reset (starting point)"
          onPress={() => scrollToX(0)}
        />
      </View>
    </View>
  );
}

const styles = StyleSheet.create({
  wrapperView: {
    height: 300,
    flexDirection: 'row',
  },
  contentView: {
    width: '100%',
    height: 250,
    justifyContent: 'center',
  },
  horizontalContentView: {
    height: 250,
    width: 500,
    justifyContent: 'center',
  },
});