/**
 * 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 {
  StyleSheet,
  Text,
  View,
  TextStyle,
  TouchableOpacity,
} from 'react-native';
import {TestSuite} from '@rnoh/testerino';
import {TestCase} from '../../components';
import {Button} from '../../components';
import {createRef, useState} from 'react';
import {SAMPLE_PARAGRAPH_TEXT} from './fixtures';
import {useEnvironment} from '../../contexts';

export function TextNestedTest() {
  const {
    env: {driver},
  } = useEnvironment();
  return (
    <TestSuite name="nested texts">
      <TestCase.Example itShould="show INNER and OUTER texts on the same height (various lineHeights)">
        <View
          style={{
            flexDirection: 'row',
          }}>
          <Text style={{lineHeight: 20, backgroundColor: 'green'}}>
            <Text style={{lineHeight: 25, backgroundColor: 'yellow'}}>
              INNER
            </Text>
            OUTER
          </Text>
        </View>
      </TestCase.Example>
      <TestCase.Example itShould="show text with ellipsize at the end of the first line">
        <Text ellipsizeMode="tail" numberOfLines={1}>
          Cupidatat irure velit id consequat magna irure quis laborum aute anim
          est cillum aliqua dolor.
        </Text>
      </TestCase.Example>
      <TestCase.Example itShould="use green background color for INNER (backgroundColor in text fragments)">
        <View
          style={{
            flexDirection: 'row',
          }}>
          <Text style={{backgroundColor: 'red'}}>
            <Text style={{backgroundColor: 'green'}}>INNER</Text>
            OUTER
          </Text>
        </View>
      </TestCase.Example>
      <TestCase.Example itShould="show text with different vertical alignments (verticalAlign)">
        <View style={{...styles.smallContainerRow}}>
          <Text style={{verticalAlign: 'auto'}}>
            -<Text style={styles.blueShortText}>Auto</Text>-
          </Text>
          <Text style={{verticalAlign: 'top'}}>
            -<Text style={styles.blueShortText}>Top</Text>-
          </Text>
          <Text style={{verticalAlign: 'middle'}}>
            -<Text style={styles.blueShortText}>Middle</Text>-
          </Text>
          <Text style={{verticalAlign: 'bottom'}}>
            -<Text style={styles.blueShortText}>Bottom</Text>-
          </Text>
        </View>
      </TestCase.Example>
      <TestCase.Example itShould="show text with different fontStyles">
        <View style={{...styles.smallContainerRow}}>
          <Text style={{fontStyle: 'normal'}}>
            <Text style={styles.blueShortText}>Normal</Text>
          </Text>
          <Text style={{fontStyle: 'italic'}}>
            <Text style={styles.blueShortText}>Top</Text>
          </Text>
        </View>
      </TestCase.Example>
      <TestCase.Example itShould="show text with different text decorations">
        <View style={{...styles.smallContainerRow}}>
          <Text
            style={{
              textDecorationLine: 'line-through',
              textDecorationColor: 'green',
            }}>
            <Text style={styles.blueShortText}>Green line-through</Text>
          </Text>
          <Text
            style={{
              textDecorationLine: 'underline',
              textDecorationColor: 'blue',
            }}>
            <Text style={styles.blueShortText}>Blue underline</Text>
          </Text>
        </View>
      </TestCase.Example>
      <TestCase.Example
        itShould="show text with shadow"
        //https://gl.swmansion.com/rnoh/react-native-harmony/-/issues/278
      >
        <View style={styles.smallContainer}>
          <Text
            style={{
              textShadowColor: 'rgba(0,0,255,0.8)',
              textShadowOffset: {width: 1, height: 1},
              textShadowRadius: 20,
            }}>
            <Text style={styles.smallText}>Text with shadow</Text>
          </Text>
        </View>
      </TestCase.Example>
      <TestCase.Example
        itShould="show text with correct textTransform "
        //  123 1one is added to the end of text to see if the code correctly handles number
      >
        <View style={styles.bigContainer}>
          <Text style={styles.smallText}>Text transform none 123 1one</Text>
          <Text
            style={{
              textTransform: 'capitalize',
            }}>
            <Text style={styles.blueShortText}>
              Text transform capitalize 123 1one
            </Text>
          </Text>
          <Text
            style={{
              textTransform: 'uppercase',
            }}>
            <Text style={styles.blueShortText}>
              Text transform uppercase 123 1one
            </Text>
          </Text>
          <Text
            style={{
              textTransform: 'lowercase',
            }}>
            <Text style={styles.blueShortText}>
              Text transform lowercase 123 1one
            </Text>
          </Text>
        </View>
      </TestCase.Example>
      <TestCase.Example itShould="show text with different vertical alignments (textAlignVertical)">
        <View style={{...styles.smallContainerRow}}>
          <Text style={{textAlignVertical: 'auto'}}>
            -<Text style={styles.blueShortText}>Auto</Text>-
          </Text>
          <Text style={{textAlignVertical: 'top'}}>
            -<Text style={styles.blueShortText}>Top</Text>-
          </Text>
          <Text style={{textAlignVertical: 'center'}}>
            -<Text style={styles.blueShortText}>Center</Text>-
          </Text>
          <Text style={{textAlignVertical: 'bottom'}}>
            -<Text style={styles.blueShortText}>Bottom</Text>-
          </Text>
        </View>
      </TestCase.Example>
      <TestCase.Example itShould="align text vertically">
        <View style={{width: 300, borderRightWidth: 1}}>
          <Text>
            <Text style={{lineHeight: 64, backgroundColor: 'red'}}>
              lineHeight: 64
            </Text>
            <Text style={{lineHeight: 16, backgroundColor: 'blue'}}>
              lineHeight: 16; lineHeight: 16; lineHeight: 16; lineHeight: 16;
            </Text>
            <View style={{backgroundColor: 'purple', width: 16, height: 16}} />
          </Text>
          <Text style={{marginTop: 16}}>
            <Text style={{lineHeight: 16, backgroundColor: 'blue'}}>
              lineHeight: 16
            </Text>
            <Text style={{lineHeight: 64, backgroundColor: 'red'}}>
              lineHeight: 64; lineHeight: 64; lineHeight: 64; lineHeight: 64
            </Text>
            <View style={{backgroundColor: 'purple', width: 16, height: 16}} />
          </Text>

          <Text style={{marginTop: 16}}>
            <Text
              style={{
                lineHeight: 64,
                backgroundColor: 'red',
                verticalAlign: 'bottom',
              }}>
              lineHeight: 16; verticalAlign: bottom; lineHeight: 16;
              verticalAlign: bottom;
            </Text>
            <Text
              style={{
                lineHeight: 16,
                backgroundColor: 'blue',
                verticalAlign: 'bottom',
              }}>
              lineHeight: 16; verticalAlign: bottom;
            </Text>
          </Text>
        </View>
      </TestCase.Example>
      <TestCase.Example itShould="show text with different horizontal alignments">
        <Text style={{textAlign: 'left'}}>
          <Text>Left: </Text>
          <Text style={{fontSize: 8}}>{SAMPLE_PARAGRAPH_TEXT}</Text>
        </Text>
        <Text style={{textAlign: 'center'}}>
          <Text>Center: </Text>
          <Text style={{fontSize: 8}}>{SAMPLE_PARAGRAPH_TEXT}</Text>
        </Text>
        <Text style={{textAlign: 'right'}}>
          <Text>Right: </Text>
          <Text style={{fontSize: 8}}>{SAMPLE_PARAGRAPH_TEXT}</Text>
        </Text>
        <Text style={{textAlign: 'justify'}}>
          <Text>Justify: </Text>
          <Text style={{fontSize: 8}}>{SAMPLE_PARAGRAPH_TEXT}</Text>
        </Text>
      </TestCase.Example>
      <TestCase.Example
        skip={{
          harmony: {arkTs: "justify isn't supported", cAPI: false},
          android: false,
        }}
        itShould="show nested view with different horizontal alignments">
        <Text>Left</Text>
        <Text style={{textAlign: 'left'}}>
          Non commodo et enim aliqua consequat. Nulla nostrud proident
          exercitation dolore commodo nisi minim do irure.
          <View style={styles.box} />
        </Text>
        <Text>Center</Text>
        <Text style={{textAlign: 'center'}}>
          Non commodo et enim aliqua consequat. Nulla nostrud proident
          exercitation dolore commodo nisi minim do irure.
          <View style={styles.box} />
        </Text>
        <Text>Right</Text>
        <Text style={{textAlign: 'right'}}>
          Non commodo et enim aliqua consequat. Nulla nostrud proident
          exercitation dolore commodo nisi minim do irure.
          <View style={styles.box} />
        </Text>
        <Text>Justify</Text>
        <Text style={{textAlign: 'justify'}}>
          Non commodo et enim aliqua consequat. Nulla nostrud proident
          exercitation dolore commodo nisi minim do irure.
          <View style={styles.box} />
        </Text>
      </TestCase.Example>
      <TestCase.Example itShould="display 1 line of text">
        <View style={{width: 200, backgroundColor: 'silver'}}>
          <Text style={{textAlign: 'left'}} numberOfLines={1}>
            <Text style={{fontSize: 12, backgroundColor: 'cyan'}}>{'>'}</Text>
            <Text style={{fontSize: 8}}>{SAMPLE_PARAGRAPH_TEXT}</Text>
          </Text>
        </View>
      </TestCase.Example>
      <TestCase.Example itShould="display 2 lines of text">
        <Text style={{textAlign: 'left'}} numberOfLines={2}>
          <Text style={{fontSize: 12, backgroundColor: 'cyan'}}>{'@@@@@'}</Text>
          <Text style={{fontSize: 8}}>{SAMPLE_PARAGRAPH_TEXT}</Text>
        </Text>
      </TestCase.Example>
      <TestCase.Example itShould="display 2 lines of text (placeholder test)">
        <Text style={{textAlign: 'left'}} numberOfLines={2}>
          <View style={{width: 0, height: 8, backgroundColor: 'red'}} />
          <Text style={{fontSize: 8}}>{SAMPLE_PARAGRAPH_TEXT}</Text>
        </Text>
      </TestCase.Example>
      <TestCase.Example itShould="wrap long words">
        <View style={{backgroundColor: 'silver', width: 200}}>
          <Text style={{textAlign: 'left'}}>
            <View style={{width: 8, height: 8, backgroundColor: 'red'}} />
            <Text style={{fontSize: 8}}>
              0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
            </Text>
          </Text>
        </View>
      </TestCase.Example>
      <TestCase.Example itShould="text should be disabled">
        <TextDisabledTest />
      </TestCase.Example>
      <TestCase.Example
        modal
        itShould="show justified text (manually added spaces)">
        <Text
          style={{
            textAlign: 'justify',
            backgroundColor: 'green',
          }}>
          <Text style={{fontSize: 16}}>Justify te st</Text>
          <Text style={{fontSize: 8, backgroundColor: 'purple'}}>
            Quis exercitation do eu in laboris nulla sit elit officia.
            Incididunt ipsum aliquip IncididuntIncididunt commodo proident
          </Text>
          <Text style={{fontSize: 38, backgroundColor: 'blue'}}>
            Quis exercitation do eu in laboris nulla sit elit officia.
            Incididunt ipsum aliquip IncididuntIncididunrumbumlublum commodo
            proident
          </Text>
        </Text>
      </TestCase.Example>
      <TestCase.Example
        modal
        itShould="activate onPress() on <Text /> if the touch moves up to 100px above or below the <Text /> body">
        <TextPressRetentionOffsetTest />
      </TestCase.Example>
      <TestCase.Example
        modal
        itShould="increase the counter when 'Press Me' is pressed (handling gestures in text fragments)">
        <TextPressNestedTest />
      </TestCase.Example>
      <TestCase.Automated
        itShould="pass after pressing the highlighted word (nested text touch handling)"
        tags={['sequential']}
        initialState={{
          wasPressed: false,
          ref: createRef<Text>(),
        }}
        arrange={({state, setState}) => (
          <View style={{flexDirection: 'row', justifyContent: 'space-between'}}>
            <Text ref={state.ref}>
              In a long text you can
              <Text
                style={{color: 'red'}}
                onPress={() => setState(prev => ({...prev, wasPressed: true}))}>
                {' '}
                Press me{' '}
              </Text>
              to pass
            </Text>
          </View>
        )}
        act={async ({state, done}) => {
          await driver?.click({ref: state.ref, offset: {x: 50, y: 0}});
          done();
        }}
        assert={({expect, state}) => {
          expect(state.wasPressed).to.be.true;
        }}
      />
      <TestCase.Automated
        itShould="pass after pressing the button embedded in text (nested text touch handling)"
        tags={['sequential']}
        initialState={{
          wasPressed: false,
          ref: createRef<View>(),
        }}
        arrange={({state, setState}) => {
          return (
            <View
              style={{flexDirection: 'row', justifyContent: 'space-between'}}>
              <Text>
                {'In a long text you can '}
                <Button
                  label="Press me"
                  ref={state.ref}
                  onPress={() =>
                    setState(prev => ({...prev, wasPressed: true}))
                  }
                />
                {' to pass'}
              </Text>
            </View>
          );
        }}
        act={async ({state, done}) => {
          await driver?.click({ref: state.ref});
          done();
        }}
        assert={({expect, state}) => {
          expect(state.wasPressed).to.be.true;
        }}
      />
    </TestSuite>
  );
}

const TextDisabledTest = () => {
  const [pressCount, setPressCount] = useState(0);
  const [disabled, setDisabled] = useState(false);

  return (
    <View>
      <Text> Press count: {pressCount} </Text>
      <Text disabled={disabled} onPress={() => setPressCount(pressCount + 1)}>
        {SAMPLE_PARAGRAPH_TEXT}
      </Text>
      <Button
        label={disabled ? 'Enable Text' : 'Disable Text'}
        onPress={() => setDisabled(!disabled)}
      />
    </View>
  );
};

const TextPressRetentionOffsetTest = () => {
  const [pressCount, setPressCount] = useState(0);

  return (
    <View style={{height: 500, justifyContent: 'center'}}>
      <Text style={{textAlign: 'center'}}> Press count: {pressCount} </Text>
      <View
        style={{
          backgroundColor: 'lightblue',
          height: 250,
          justifyContent: 'center',
        }}>
        <Text
          style={{
            backgroundColor: 'blue',
            height: 50,
            textAlign: 'center',
            textAlignVertical: 'center',
            color: 'white',
          }}
          onPress={() => setPressCount(pressCount + 1)}
          // @ts-ignore - pressRetentionOffset is not in the type definition
          pressRetentionOffset={{
            bottom: 100,
            left: 0,
            right: 0,
            top: 100,
          }}>
          pressRetentionOffset
        </Text>
      </View>
    </View>
  );
};

const TextPressNestedTest = () => {
  const [textPressCount, setTextPressCount] = useState(0);
  const [attachmentPressCount, setAttachmentPressCount] = useState(0);
  const TextAligns: Array<TextStyle['textAlign']> = [
    'auto',
    'left',
    'center',
    'right',
    'justify',
    undefined,
  ];
  const [alignIndex, setAlignIndex] = useState(0);
  const [mutil, setMutil] = useState(false);
  const [hasPadding, setHasPadding] = useState(false);
  const [hasMargin, setHasMargin] = useState(false);
  const [hasAttachment, setHasAttachment] = useState(false);

  return (
    <View style={{height: 500, justifyContent: 'center'}}>
      <Text style={{textAlign: 'center'}}>
        {' '}
        Text press count: {textPressCount}{' '}
      </Text>
      <Text style={{textAlign: 'center'}}>
        {' '}
        Attachment press count: {attachmentPressCount}{' '}
      </Text>
      <View
        style={{
          backgroundColor: 'lightblue',
          height: 250,
        }}>
        <Text
          style={{
            textAlign: TextAligns[alignIndex % 6],
            padding: hasPadding ? 40 : 0,
            margin: hasMargin ? 20 : 0,
          }}>
          {mutil
            ? 'Text with multiple lines ======================================== '
            : 'SingleLine '}
          <Text
            style={{
              color: 'blue',
              textAlign: 'right',
            }}
            onPress={() => setTextPressCount(textPressCount + 1)}>
            Press Me
          </Text>
          ====
          {hasAttachment ? (
            <View>
              <Button
                onPress={() => setAttachmentPressCount(prev => prev + 1)}
                label="Press Me"
              />
            </View>
          ) : null}
        </Text>
      </View>
      <View
        style={{
          backgroundColor: 'lightyellow',
        }}>
        <Text>Below is the property controller.</Text>
        <TouchableOpacity
          style={styles.button}
          onPress={() => setAlignIndex(alignIndex + 1)}>
          <Text>textAlign: {TextAligns[alignIndex % 6]}</Text>
        </TouchableOpacity>
        <TouchableOpacity
          style={styles.button}
          onPress={() => setMutil(!mutil)}>
          <Text>{mutil ? 'Multiline' : 'Singleline'}</Text>
        </TouchableOpacity>
        <TouchableOpacity
          style={styles.button}
          onPress={() => setHasPadding(!hasPadding)}>
          <Text>{hasPadding ? 'HasPadding' : 'NoPadding'}</Text>
        </TouchableOpacity>
        <TouchableOpacity
          style={styles.button}
          onPress={() => setHasMargin(!hasMargin)}>
          <Text>{hasMargin ? 'HasMargin' : 'NoMargin'}</Text>
        </TouchableOpacity>
        <TouchableOpacity
          style={styles.button}
          onPress={() => setHasAttachment(!hasAttachment)}>
          <Text>{hasAttachment ? 'HasAttachment' : 'NoAttachment'}</Text>
        </TouchableOpacity>
      </View>
    </View>
  );
};

const styles = StyleSheet.create({
  smallContainer: {
    width: 200,
    height: 40,
    backgroundColor: 'red',
  },
  smallContainerRow: {
    width: 200,
    height: 40,
    backgroundColor: 'red',
    flexDirection: 'row',
  },
  bigContainer: {
    width: 200,
    height: 120,
    backgroundColor: 'red',
  },
  smallText: {
    height: 30,
    color: 'white',
  },
  blueShortText: {
    height: 30,
    width: 50,
    color: 'white',
    backgroundColor: 'blue',
  },
  box: {
    height: 15,
    width: 15,
    backgroundColor: 'yellow',
  },
  button: {
    backgroundColor: 'pink',
    padding: 8,
  },
});