// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// This file is run as part of a reduced test set in CI on Mac and Windows
// machines.
@Tags(<String>['reduced-test-set'])

import 'dart:ui' as ui;

import 'package:flutter/cupertino.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart';

import '../widgets/semantics_tester.dart';

RenderBox getRenderSegmentedControl(WidgetTester tester) {
  return tester.allRenderObjects.firstWhere(
    (RenderObject currentObject) {
      return currentObject.toStringShort().contains('_RenderSegmentedControl');
    },
  ) as RenderBox;
}

StatefulBuilder setupSimpleSegmentedControl() {
  final Map<int, Widget> children = <int, Widget>{};
  children[0] = const Text('Child 1');
  children[1] = const Text('Child 2');
  int sharedValue = 0;

  return StatefulBuilder(
    builder: (BuildContext context, StateSetter setState) {
      return boilerplate(
        child: CupertinoSegmentedControl<int>(
          children: children,
          onValueChanged: (int newValue) {
            setState(() {
              sharedValue = newValue;
            });
          },
          groupValue: sharedValue,
        ),
      );
    },
  );
}

Widget boilerplate({ required Widget child }) {
  return Directionality(
    textDirection: TextDirection.ltr,
    child: Center(child: child),
  );
}

int getChildCount(WidgetTester tester) {
  return (getRenderSegmentedControl(tester) as RenderBoxContainerDefaultsMixin<RenderBox, ContainerBoxParentData<RenderBox>>)
      .getChildrenAsList().length;
}

ui.RRect getSurroundingRect(WidgetTester tester, {int child = 0}) {
  // Using dynamic so the test can access private classes.
  // ignore: avoid_dynamic_calls
  return ((getRenderSegmentedControl(tester) as RenderBoxContainerDefaultsMixin<RenderBox, ContainerBoxParentData<RenderBox>>)
      .getChildrenAsList()[child].parentData! as dynamic).surroundingRect as ui.RRect;
}

Size getChildSize(WidgetTester tester, {int child = 0}) {
  // Using dynamic so the test can access private classes.
  // ignore: avoid_dynamic_calls
  return ((getRenderSegmentedControl(tester) as RenderBoxContainerDefaultsMixin<RenderBox, ContainerBoxParentData<RenderBox>>)
      .getChildrenAsList()[child]).size;
}

Color getBorderColor(WidgetTester tester) {
  // Using dynamic so the test can access a private class.
  // ignore: avoid_dynamic_calls
  return (getRenderSegmentedControl(tester) as dynamic).borderColor as Color;
}

int? getSelectedIndex(WidgetTester tester) {
  // Using dynamic so the test can access a private class.
  // ignore: avoid_dynamic_calls
  return (getRenderSegmentedControl(tester) as dynamic).selectedIndex as int?;
}

Color getBackgroundColor(WidgetTester tester, int childIndex) {
  // Using dynamic so the test can access a private class.
  // ignore: avoid_dynamic_calls
  return (getRenderSegmentedControl(tester) as dynamic).backgroundColors[childIndex] as Color;
}

void main() {
  testWidgets('Tap changes toggle state', (WidgetTester tester) async {
    final Map<int, Widget> children = <int, Widget>{};
    children[0] = const Text('Child 1');
    children[1] = const Text('Child 2');
    children[2] = const Text('Child 3');

    int sharedValue = 0;

    await tester.pumpWidget(
      StatefulBuilder(
        builder: (BuildContext context, StateSetter setState) {
          return boilerplate(
            child: CupertinoSegmentedControl<int>(
              key: const ValueKey<String>('Segmented Control'),
              children: children,
              onValueChanged: (int newValue) {
                setState(() {
                  sharedValue = newValue;
                });
              },
              groupValue: sharedValue,
            ),
          );
        },
      ),
    );

    expect(sharedValue, 0);

    await tester.tap(find.byKey(const ValueKey<String>('Segmented Control')));

    expect(sharedValue, 1);
  });

  testWidgets('Need at least 2 children', (WidgetTester tester) async {
    await expectLater(
      () => tester.pumpWidget(
        boilerplate(
          child: CupertinoSegmentedControl<int>(
            children: const <int, Widget>{},
            onValueChanged: (int newValue) { },
          ),
        ),
      ),
      throwsA(isAssertionError.having(
        (AssertionError error) => error.toString(),
        '.toString()',
        contains('children.length'),
      )),
    );

    await expectLater(
      () => tester.pumpWidget(
        boilerplate(
          child: CupertinoSegmentedControl<int>(
            children: const <int, Widget>{0: Text('Child 1')},
            onValueChanged: (int newValue) { },
          ),
        ),
      ),
      throwsA(isAssertionError.having(
        (AssertionError error) => error.toString(),
        '.toString()',
        contains('children.length'),
      )),
    );
  });

  testWidgets('Padding works', (WidgetTester tester) async {
    const Key key = Key('Container');

    final Map<int, Widget> children = <int, Widget>{};
    children[0] = const SizedBox(
      height: double.infinity,
      child: Text('Child 1'),
    ) ;
    children[1] = const SizedBox(
      height: double.infinity,
      child: Text('Child 2'),
    ) ;

    Future<void> verifyPadding({ EdgeInsets? padding }) async {
      final EdgeInsets effectivePadding = padding ?? const EdgeInsets.symmetric(horizontal: 16);
      final Rect segmentedControlRect = tester.getRect(find.byKey(key));
      expect(
          tester.getTopLeft(find.byWidget(children[0]!)),
          segmentedControlRect.topLeft.translate(
            effectivePadding.topLeft.dx,
            effectivePadding.topLeft.dy,
          ),
      );
      expect(
        tester.getBottomLeft(find.byWidget(children[0]!)),
        segmentedControlRect.bottomLeft.translate(
          effectivePadding.bottomLeft.dx,
          effectivePadding.bottomLeft.dy,
        ),
      );

      expect(
        tester.getTopRight(find.byWidget(children[1]!)),
        segmentedControlRect.topRight.translate(
          effectivePadding.topRight.dx,
          effectivePadding.topRight.dy,
        ),
      );
      expect(
        tester.getBottomRight(find.byWidget(children[1]!)),
        segmentedControlRect.bottomRight.translate(
          effectivePadding.bottomRight.dx,
          effectivePadding.bottomRight.dy,
        ),
      );
    }

    await tester.pumpWidget(
        boilerplate(
          child: CupertinoSegmentedControl<int>(
            key: key,
            children: children,
            onValueChanged: (int newValue) { },
          ),
        ),
    );

    // Default padding works.
    await verifyPadding();

    // Switch to Child 2 padding should remain the same.
    await tester.tap(find.text('Child 2'));
    await tester.pumpAndSettle();

    await verifyPadding();

    await tester.pumpWidget(
        boilerplate(
          child: CupertinoSegmentedControl<int>(
            key: key,
            padding: const EdgeInsets.fromLTRB(1, 3, 5, 7),
            children: children,
            onValueChanged: (int newValue) { },
          ),
        ),
    );

    // Custom padding works.
    await verifyPadding(padding: const EdgeInsets.fromLTRB(1, 3, 5, 7));

    // Switch back to Child 1 padding should remain the same.
    await tester.tap(find.text('Child 1'));
    await tester.pumpAndSettle();

    await verifyPadding(padding: const EdgeInsets.fromLTRB(1, 3, 5, 7));
  });

  testWidgets('Value attribute must be the key of one of the children widgets', (WidgetTester tester) async {
    final Map<int, Widget> children = <int, Widget>{};
    children[0] = const Text('Child 1');
    children[1] = const Text('Child 2');

    await expectLater(
      () => tester.pumpWidget(
        boilerplate(
          child: CupertinoSegmentedControl<int>(
            children: children,
            onValueChanged: (int newValue) { },
            groupValue: 2,
          ),
        ),
      ),
      throwsA(isAssertionError.having(
        (AssertionError error) => error.toString(),
        '.toString()',
        contains('children'),
      )),
    );
  });

  testWidgets('Widgets have correct default text/icon styles, change correctly on selection', (WidgetTester tester) async {
    final Map<int, Widget> children = <int, Widget>{};
    children[0] = const Text('Child 1');
    children[1] = const Icon(IconData(1));

    int sharedValue = 0;

    await tester.pumpWidget(
      StatefulBuilder(
        builder: (BuildContext context, StateSetter setState) {
          return boilerplate(
            child: CupertinoSegmentedControl<int>(
              children: children,
              onValueChanged: (int newValue) {
                setState(() {
                  sharedValue = newValue;
                });
              },
              groupValue: sharedValue,
            ),
          );
        },
      ),
    );

    await tester.pumpAndSettle();

    DefaultTextStyle textStyle = tester.widget(find.widgetWithText(DefaultTextStyle, 'Child 1'));
    IconTheme iconTheme = tester.widget(find.widgetWithIcon(IconTheme, const IconData(1)));

    expect(textStyle.style.color, isSameColorAs(CupertinoColors.white));
    expect(iconTheme.data.color, CupertinoColors.activeBlue);

    await tester.tap(find.widgetWithIcon(IconTheme, const IconData(1)));
    await tester.pumpAndSettle();

    textStyle = tester.widget(find.widgetWithText(DefaultTextStyle, 'Child 1'));
    iconTheme = tester.widget(find.widgetWithIcon(IconTheme, const IconData(1)));

    expect(textStyle.style.color, CupertinoColors.activeBlue);
    expect(iconTheme.data.color, isSameColorAs(CupertinoColors.white));
  });

  testWidgets(
    'Segmented controls respects themes',
    (WidgetTester tester) async {
      final Map<int, Widget> children = <int, Widget>{};
      children[0] = const Text('Child 1');
      children[1] = const Icon(IconData(1));

      int sharedValue = 0;

      await tester.pumpWidget(
        CupertinoApp(
          theme: const CupertinoThemeData(brightness: Brightness.dark),
          home: StatefulBuilder(
            builder: (BuildContext context, StateSetter setState) {
              return CupertinoSegmentedControl<int>(
                children: children,
                onValueChanged: (int newValue) {
                  setState(() {
                    sharedValue = newValue;
                  });
                },
                groupValue: sharedValue,
              );
            },
          ),
        ),
      );

      DefaultTextStyle textStyle = tester.widget(find.widgetWithText(DefaultTextStyle, 'Child 1').first);
      IconThemeData iconTheme = IconTheme.of(tester.element(find.byIcon(const IconData(1))));

      expect(textStyle.style.color, isSameColorAs(CupertinoColors.black));
      expect(iconTheme.color, isSameColorAs(CupertinoColors.systemBlue.darkColor));

      await tester.tap(find.byIcon(const IconData(1)));
      await tester.pump();
      await tester.pump(const Duration(milliseconds: 500));

      textStyle = tester.widget(find.widgetWithText(DefaultTextStyle, 'Child 1').first);
      iconTheme = IconTheme.of(tester.element(find.byIcon(const IconData(1))));

      expect(textStyle.style.color, isSameColorAs(CupertinoColors.systemBlue.darkColor));
      expect(iconTheme.color, isSameColorAs(CupertinoColors.black));
    },
  );

  testWidgets('SegmentedControl is correct when user provides custom colors', (WidgetTester tester) async {
    final Map<int, Widget> children = <int, Widget>{};
    children[0] = const Text('Child 1');
    children[1] = const Icon(IconData(1));

    int sharedValue = 0;

    await tester.pumpWidget(
      StatefulBuilder(
        builder: (BuildContext context, StateSetter setState) {
          return boilerplate(
            child: CupertinoSegmentedControl<int>(
              children: children,
              onValueChanged: (int newValue) {
                setState(() {
                  sharedValue = newValue;
                });
              },
              groupValue: sharedValue,
              unselectedColor: CupertinoColors.lightBackgroundGray,
              selectedColor: CupertinoColors.activeGreen.color,
              borderColor: CupertinoColors.black,
              pressedColor: const Color(0x638CFC7B),
            ),
          );
        },
      ),
    );

    DefaultTextStyle textStyle = tester.widget(find.widgetWithText(DefaultTextStyle, 'Child 1'));
    IconTheme iconTheme = tester.widget(find.widgetWithIcon(IconTheme, const IconData(1)));

    expect(getBorderColor(tester), CupertinoColors.black);
    expect(textStyle.style.color, CupertinoColors.lightBackgroundGray);
    expect(iconTheme.data.color, CupertinoColors.activeGreen.color);
    expect(getBackgroundColor(tester, 0), CupertinoColors.activeGreen.color);
    expect(getBackgroundColor(tester, 1), CupertinoColors.lightBackgroundGray);

    await tester.tap(find.widgetWithIcon(IconTheme, const IconData(1)));
    await tester.pumpAndSettle();

    textStyle = tester.widget(find.widgetWithText(DefaultTextStyle, 'Child 1'));
    iconTheme = tester.widget(find.widgetWithIcon(IconTheme, const IconData(1)));

    expect(textStyle.style.color, CupertinoColors.activeGreen.color);
    expect(iconTheme.data.color, CupertinoColors.lightBackgroundGray);
    expect(getBackgroundColor(tester, 0), CupertinoColors.lightBackgroundGray);
    expect(getBackgroundColor(tester, 1), CupertinoColors.activeGreen.color);

    final Offset center = tester.getCenter(find.text('Child 1'));
    await tester.startGesture(center);
    await tester.pumpAndSettle();

    expect(getBackgroundColor(tester, 0), const Color(0x638CFC7B));
    expect(getBackgroundColor(tester, 1), CupertinoColors.activeGreen.color);
  });

  testWidgets('Widgets are centered within segments', (WidgetTester tester) async {
    final Map<int, Widget> children = <int, Widget>{};
    children[0] = const Text('Child 1');
    children[1] = const Text('Child 2');

    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: Align(
          alignment: Alignment.topLeft,
          child: SizedBox(
            width: 200.0,
            height: 200.0,
            child: CupertinoSegmentedControl<int>(
              children: children,
              onValueChanged: (int newValue) { },
            ),
          ),
        ),
      ),
    );

    // Widgets are centered taking into account 16px of horizontal padding
    expect(tester.getCenter(find.text('Child 1')), const Offset(58.0, 100.0));
    expect(tester.getCenter(find.text('Child 2')), const Offset(142.0, 100.0));
  });

  testWidgets('Tap calls onValueChanged', (WidgetTester tester) async {
    final Map<int, Widget> children = <int, Widget>{};
    children[0] = const Text('Child 1');
    children[1] = const Text('Child 2');

    bool value = false;

    await tester.pumpWidget(
      StatefulBuilder(
        builder: (BuildContext context, StateSetter setState) {
          return boilerplate(
            child: CupertinoSegmentedControl<int>(
              children: children,
              onValueChanged: (int newValue) {
                value = true;
              },
            ),
          );
        },
      ),
    );

    expect(value, isFalse);

    await tester.tap(find.text('Child 2'));

    expect(value, isTrue);
  });

  testWidgets('State does not change if onValueChanged does not call setState()', (WidgetTester tester) async {
    final Map<int, Widget> children = <int, Widget>{};
    children[0] = const Text('Child 1');
    children[1] = const Text('Child 2');

    const int sharedValue = 0;

    await tester.pumpWidget(
      StatefulBuilder(
        builder: (BuildContext context, StateSetter setState) {
          return boilerplate(
            child: CupertinoSegmentedControl<int>(
              children: children,
              onValueChanged: (int newValue) { },
              groupValue: sharedValue,
            ),
          );
        },
      ),
    );

    expect(getBackgroundColor(tester, 0), CupertinoColors.activeBlue);
    expect(getBackgroundColor(tester, 1), isSameColorAs(CupertinoColors.white));

    await tester.tap(find.text('Child 2'));
    await tester.pump();

    expect(getBackgroundColor(tester, 0), CupertinoColors.activeBlue);
    expect(getBackgroundColor(tester, 1), isSameColorAs(CupertinoColors.white));
  });

  testWidgets(
    'Background color of child should change on selection, '
    'and should not change when tapped again',
    (WidgetTester tester) async {
      await tester.pumpWidget(setupSimpleSegmentedControl());

      expect(getBackgroundColor(tester, 1), isSameColorAs(CupertinoColors.white));

      await tester.tap(find.text('Child 2'));
      await tester.pumpAndSettle(const Duration(milliseconds: 200));

      expect(getBackgroundColor(tester, 1), CupertinoColors.activeBlue);

      await tester.tap(find.text('Child 2'));
      await tester.pump();

      expect(getBackgroundColor(tester, 1), CupertinoColors.activeBlue);
    },
  );

  testWidgets(
    'Children can be non-Text or Icon widgets (in this case, '
        'a Container or Placeholder widget)',
    (WidgetTester tester) async {
      final Map<int, Widget> children = <int, Widget>{};
      children[0] = const Text('Child 1');
      children[1] = Container(
        constraints: const BoxConstraints.tightFor(width: 50.0, height: 50.0),
      );
      children[2] = const Placeholder();

      int sharedValue = 0;

      await tester.pumpWidget(
        StatefulBuilder(
          builder: (BuildContext context, StateSetter setState) {
            return boilerplate(
              child: CupertinoSegmentedControl<int>(
                children: children,
                onValueChanged: (int newValue) {
                  setState(() {
                    sharedValue = newValue;
                  });
                },
                groupValue: sharedValue,
              ),
            );
          },
        ),
      );
    },
  );

  testWidgets('Passed in value is child initially selected', (WidgetTester tester) async {
    await tester.pumpWidget(setupSimpleSegmentedControl());

    expect(getSelectedIndex(tester), 0);

    expect(getBackgroundColor(tester, 0), CupertinoColors.activeBlue);
    expect(getBackgroundColor(tester, 1), isSameColorAs(CupertinoColors.white));
  });

  testWidgets('Null input for value results in no child initially selected', (WidgetTester tester) async {
    final Map<int, Widget> children = <int, Widget>{};
    children[0] = const Text('Child 1');
    children[1] = const Text('Child 2');

    int? sharedValue;

    await tester.pumpWidget(
      StatefulBuilder(
        builder: (BuildContext context, StateSetter setState) {
          return boilerplate(
            child: CupertinoSegmentedControl<int>(
              children: children,
              onValueChanged: (int newValue) {
                setState(() {
                  sharedValue = newValue;
                });
              },
              groupValue: sharedValue,
            ),
          );
        },
      ),
    );

    expect(getSelectedIndex(tester), null);

    expect(getBackgroundColor(tester, 0), isSameColorAs(CupertinoColors.white));
    expect(getBackgroundColor(tester, 1), isSameColorAs(CupertinoColors.white));
  });

  testWidgets('Long press changes background color of not-selected child', (WidgetTester tester) async {
    await tester.pumpWidget(setupSimpleSegmentedControl());

    expect(getBackgroundColor(tester, 0), CupertinoColors.activeBlue);
    expect(getBackgroundColor(tester, 1), isSameColorAs(CupertinoColors.white));

    final Offset center = tester.getCenter(find.text('Child 2'));
    await tester.startGesture(center);
    await tester.pumpAndSettle();

    expect(getBackgroundColor(tester, 0), CupertinoColors.activeBlue);
    expect(getBackgroundColor(tester, 1), const Color(0x33007aff));
  });

  testWidgets('Long press does not change background color of currently-selected child', (WidgetTester tester) async {
    await tester.pumpWidget(setupSimpleSegmentedControl());

    expect(getBackgroundColor(tester, 0), CupertinoColors.activeBlue);
    expect(getBackgroundColor(tester, 1), isSameColorAs(CupertinoColors.white));

    final Offset center = tester.getCenter(find.text('Child 1'));
    await tester.startGesture(center);
    await tester.pumpAndSettle();

    expect(getBackgroundColor(tester, 0), CupertinoColors.activeBlue);
    expect(getBackgroundColor(tester, 1), isSameColorAs(CupertinoColors.white));
  });

  testWidgets('Height of segmented control is determined by tallest widget', (WidgetTester tester) async {
    final Map<int, Widget> children = <int, Widget>{};
    children[0] = Container(
      constraints: const BoxConstraints.tightFor(height: 100.0),
    );
    children[1] = Container(
      constraints: const BoxConstraints.tightFor(height: 400.0),
    );
    children[2] = Container(
      constraints: const BoxConstraints.tightFor(height: 200.0),
    );

    await tester.pumpWidget(
      StatefulBuilder(
        builder: (BuildContext context, StateSetter setState) {
          return boilerplate(
            child: CupertinoSegmentedControl<int>(
              key: const ValueKey<String>('Segmented Control'),
              children: children,
              onValueChanged: (int newValue) { },
            ),
          );
        },
      ),
    );

    final RenderBox buttonBox = tester.renderObject(find.byKey(const ValueKey<String>('Segmented Control')));

    expect(buttonBox.size.height, 400.0);
  });

  testWidgets('Width of each segmented control segment is determined by widest widget', (WidgetTester tester) async {
    final Map<int, Widget> children = <int, Widget>{};
    children[0] = Container(
      constraints: const BoxConstraints.tightFor(width: 50.0),
    );
    children[1] = Container(
      constraints: const BoxConstraints.tightFor(width: 100.0),
    );
    children[2] = Container(
      constraints: const BoxConstraints.tightFor(width: 200.0),
    );

    await tester.pumpWidget(
      StatefulBuilder(
        builder: (BuildContext context, StateSetter setState) {
          return boilerplate(
            child: CupertinoSegmentedControl<int>(
              key: const ValueKey<String>('Segmented Control'),
              children: children,
              onValueChanged: (int newValue) { },
            ),
          );
        },
      ),
    );

    final RenderBox segmentedControl = tester.renderObject(find.byKey(const ValueKey<String>('Segmented Control')));

    // Subtract the 16.0px from each side. Remaining width should be allocated
    // to each child equally.
    final double childWidth = (segmentedControl.size.width - 32.0) / 3;

    expect(childWidth, 200.0);

    expect(childWidth, getSurroundingRect(tester).width);
    expect(childWidth, getSurroundingRect(tester, child: 1).width);
    expect(childWidth, getSurroundingRect(tester, child: 2).width);
  });

  testWidgets('Width is finite in unbounded space', (WidgetTester tester) async {
    final Map<int, Widget> children = <int, Widget>{};
    children[0] = const Text('Child 1');
    children[1] = const Text('Child 2');

    await tester.pumpWidget(
      StatefulBuilder(
        builder: (BuildContext context, StateSetter setState) {
          return boilerplate(
            child: Row(
              children: <Widget>[
                CupertinoSegmentedControl<int>(
                  key: const ValueKey<String>('Segmented Control'),
                  children: children,
                  onValueChanged: (int newValue) { },
                ),
              ],
            ),
          );
        },
      ),
    );

    final RenderBox segmentedControl = tester.renderObject(find.byKey(const ValueKey<String>('Segmented Control')));

    expect(segmentedControl.size.width.isFinite, isTrue);
  });

  testWidgets('Directionality test - RTL should reverse order of widgets', (WidgetTester tester) async {
    final Map<int, Widget> children = <int, Widget>{};
    children[0] = const Text('Child 1');
    children[1] = const Text('Child 2');

    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.rtl,
        child: Center(
          child: CupertinoSegmentedControl<int>(
            children: children,
            onValueChanged: (int newValue) { },
          ),
        ),
      ),
    );

    expect(tester.getTopRight(find.text('Child 1')).dx > tester.getTopRight(find.text('Child 2')).dx, isTrue);
  });

  testWidgets('Correct initial selection and toggling behavior - RTL', (WidgetTester tester) async {
    final Map<int, Widget> children = <int, Widget>{};
    children[0] = const Text('Child 1');
    children[1] = const Text('Child 2');

    int sharedValue = 0;

    await tester.pumpWidget(
      StatefulBuilder(
        builder: (BuildContext context, StateSetter setState) {
          return Directionality(
            textDirection: TextDirection.rtl,
            child: Center(
              child: CupertinoSegmentedControl<int>(
                children: children,
                onValueChanged: (int newValue) {
                  setState(() {
                    sharedValue = newValue;
                  });
                },
                groupValue: sharedValue,
              ),
            ),
          );
        },
      ),
    );

    expect(getBackgroundColor(tester, 0), CupertinoColors.activeBlue);
    expect(getBackgroundColor(tester, 1), isSameColorAs(CupertinoColors.white));

    await tester.tap(find.text('Child 2'));
    await tester.pumpAndSettle();

    expect(getBackgroundColor(tester, 0), isSameColorAs(CupertinoColors.white));
    expect(getBackgroundColor(tester, 1), CupertinoColors.activeBlue);

    await tester.tap(find.text('Child 2'));
    await tester.pump();

    expect(getBackgroundColor(tester, 1), CupertinoColors.activeBlue);
  });

  testWidgets('Segmented control semantics', (WidgetTester tester) async {
    final SemanticsTester semantics = SemanticsTester(tester);

    final Map<int, Widget> children = <int, Widget>{};
    children[0] = const Text('Child 1');
    children[1] = const Text('Child 2');
    int sharedValue = 0;

    await tester.pumpWidget(
      StatefulBuilder(
        builder: (BuildContext context, StateSetter setState) {
          return Directionality(
            textDirection: TextDirection.ltr,
            child: Center(
              child: CupertinoSegmentedControl<int>(
                children: children,
                onValueChanged: (int newValue) {
                  setState(() {
                    sharedValue = newValue;
                  });
                },
                groupValue: sharedValue,
              ),
            ),
          );
        },
      ),
    );

    expect(
      semantics,
        hasSemantics(
          TestSemantics.root(
            children: <TestSemantics>[
              TestSemantics.rootChild(
                label: 'Child 1',
                flags: <SemanticsFlag>[
                  SemanticsFlag.isButton,
                  SemanticsFlag.isInMutuallyExclusiveGroup,
                  SemanticsFlag.isSelected,
                ],
                actions: <SemanticsAction>[
                  SemanticsAction.tap,
                ],
              ),
              TestSemantics.rootChild(
                label: 'Child 2',
                flags: <SemanticsFlag>[
                  SemanticsFlag.isButton,
                  SemanticsFlag.isInMutuallyExclusiveGroup,
                ],
                actions: <SemanticsAction>[
                  SemanticsAction.tap,
                ],
              ),
            ],
          ),
          ignoreId: true,
          ignoreRect: true,
          ignoreTransform: true,
        ),
    );

    await tester.tap(find.text('Child 2'));
    await tester.pump();

    expect(
      semantics,
      hasSemantics(
        TestSemantics.root(
          children: <TestSemantics>[
            TestSemantics.rootChild(
              label: 'Child 1',
              flags: <SemanticsFlag>[
                SemanticsFlag.isButton,
                SemanticsFlag.isInMutuallyExclusiveGroup,
              ],
              actions: <SemanticsAction>[
                SemanticsAction.tap,
              ],
            ),
            TestSemantics.rootChild(
              label: 'Child 2',
              flags: <SemanticsFlag>[
                SemanticsFlag.isButton,
                SemanticsFlag.isInMutuallyExclusiveGroup,
                SemanticsFlag.isSelected,
              ],
              actions: <SemanticsAction>[
                SemanticsAction.tap,
              ],
            ),
          ],
        ),
        ignoreId: true,
        ignoreRect: true,
        ignoreTransform: true,
      ),
    );

    semantics.dispose();
  });

  testWidgets('Non-centered taps work on smaller widgets', (WidgetTester tester) async {
    final Map<int, Widget> children = <int, Widget>{};
    children[0] = const Text('Child 1');
    children[1] = const Text('Child 2');

    int sharedValue = 1;

    await tester.pumpWidget(
      StatefulBuilder(
        builder: (BuildContext context, StateSetter setState) {
          return boilerplate(
            child: CupertinoSegmentedControl<int>(
              key: const ValueKey<String>('Segmented Control'),
              children: children,
              onValueChanged: (int newValue) {
                setState(() {
                  sharedValue = newValue;
                });
              },
              groupValue: sharedValue,
            ),
          );
        },
      ),
    );

    expect(sharedValue, 1);

    final double childWidth = getChildSize(tester).width;
    final Offset centerOfSegmentedControl = tester.getCenter(find.text('Child 1'));

    // Tap just inside segment bounds
    await tester.tapAt(
      Offset(
        centerOfSegmentedControl.dx + (childWidth / 2) - 10.0,
        centerOfSegmentedControl.dy,
      ),
    );

    expect(sharedValue, 0);
  });

  testWidgets('Hit-tests report accurate local position in segments', (WidgetTester tester) async {
    final Map<int, Widget> children = <int, Widget>{};
    late TapDownDetails tapDownDetails;
    children[0] = GestureDetector(
      behavior: HitTestBehavior.opaque,
      onTapDown: (TapDownDetails details) { tapDownDetails = details; },
      child: const SizedBox(width: 200, height: 200),
    );
    children[1] = const Text('Child 2');

    int sharedValue = 1;

    await tester.pumpWidget(
      StatefulBuilder(
        builder: (BuildContext context, StateSetter setState) {
          return boilerplate(
            child: CupertinoSegmentedControl<int>(
              key: const ValueKey<String>('Segmented Control'),
              children: children,
              onValueChanged: (int newValue) {
                setState(() {
                  sharedValue = newValue;
                });
              },
              groupValue: sharedValue,
            ),
          );
        },
      ),
    );

    expect(sharedValue, 1);

    final Offset segment0GlobalOffset = tester.getTopLeft(find.byWidget(children[0]!));
    await tester.tapAt(segment0GlobalOffset + const Offset(7, 11));

    expect(tapDownDetails.localPosition, const Offset(7, 11));
    expect(tapDownDetails.globalPosition, segment0GlobalOffset + const Offset(7, 11));
  });

  testWidgets(
    'Segment still hittable with a child that has no hitbox',
    (WidgetTester tester) async {
      // Regression test for https://github.com/flutter/flutter/issues/57326.
      final Map<int, Widget> children = <int, Widget>{};
      children[0] = const Text('Child 1');
      children[1] = const SizedBox();
      int sharedValue = 0;

      await tester.pumpWidget(
        StatefulBuilder(
          builder: (BuildContext context, StateSetter setState) {
            return boilerplate(
              child: CupertinoSegmentedControl<int>(
                key: const ValueKey<String>('Segmented Control'),
                children: children,
                onValueChanged: (int newValue) {
                  setState(() {
                    sharedValue = newValue;
                  });
                },
                groupValue: sharedValue,
              ),
            );
          },
        ),
      );

      expect(sharedValue, 0);

      final Offset centerOfTwo = tester.getCenter(find.byWidget(children[1]!));
      // Tap within the bounds of children[1], but not at the center.
      // children[1] is a SizedBox thus not hittable by itself.
      await tester.tapAt(centerOfTwo + const Offset(10, 0));

      expect(sharedValue, 1);
    },
  );

  testWidgets('Animation is correct when the selected segment changes', (WidgetTester tester) async {
    await tester.pumpWidget(setupSimpleSegmentedControl());

    await tester.tap(find.text('Child 2'));

    await tester.pump();
    expect(getBackgroundColor(tester, 0), CupertinoColors.activeBlue);
    expect(getBackgroundColor(tester, 1), const Color(0x33007aff));

    await tester.pump(const Duration(milliseconds: 40));
    expect(getBackgroundColor(tester, 0), const Color(0xff3d9aff));
    expect(getBackgroundColor(tester, 1), const Color(0x64007aff));

    await tester.pump(const Duration(milliseconds: 40));
    expect(getBackgroundColor(tester, 0), const Color(0xff7bbaff));
    expect(getBackgroundColor(tester, 1), const Color(0x95007aff));

    await tester.pump(const Duration(milliseconds: 40));
    expect(getBackgroundColor(tester, 0), const Color(0xffb9daff));
    expect(getBackgroundColor(tester, 1), const Color(0xc7007aff));

    await tester.pump(const Duration(milliseconds: 40));
    expect(getBackgroundColor(tester, 0), const Color(0xfff7faff));
    expect(getBackgroundColor(tester, 1), const Color(0xf8007aff));

    await tester.pump(const Duration(milliseconds: 40));
    expect(getBackgroundColor(tester, 0), isSameColorAs(CupertinoColors.white));
    expect(getBackgroundColor(tester, 1), CupertinoColors.activeBlue);
  });

  testWidgets('Animation is correct when widget is rebuilt', (WidgetTester tester) async {
    final Map<int, Widget> children = <int, Widget>{};
    children[0] = const Text('Child 1');
    children[1] = const Text('Child 2');
    int sharedValue = 0;

    await tester.pumpWidget(
      StatefulBuilder(
        builder: (BuildContext context, StateSetter setState) {
          return boilerplate(
            child: CupertinoSegmentedControl<int>(
              children: children,
              onValueChanged: (int newValue) {
                setState(() {
                  sharedValue = newValue;
                });
              },
              groupValue: sharedValue,
            ),
          );
        },
      ),
    );

    await tester.tap(find.text('Child 2'));

    await tester.pumpWidget(
      StatefulBuilder(
        builder: (BuildContext context, StateSetter setState) {
          return boilerplate(
            child: CupertinoSegmentedControl<int>(
              children: children,
              onValueChanged: (int newValue) {
                setState(() {
                  sharedValue = newValue;
                });
              },
              groupValue: sharedValue,
            ),
          );
        },
      ),
    );
    expect(getBackgroundColor(tester, 0), CupertinoColors.activeBlue);
    expect(getBackgroundColor(tester, 1), const Color(0x33007aff));

    await tester.pumpWidget(
      StatefulBuilder(
        builder: (BuildContext context, StateSetter setState) {
          return boilerplate(
            child: CupertinoSegmentedControl<int>(
              children: children,
              onValueChanged: (int newValue) {
                setState(() {
                  sharedValue = newValue;
                });
              },
              groupValue: sharedValue,
            ),
          );
        },
      ),
      const Duration(milliseconds: 40),
    );
    expect(getBackgroundColor(tester, 0), const Color(0xff3d9aff));
    expect(getBackgroundColor(tester, 1), const Color(0x64007aff));

    await tester.pumpWidget(
      StatefulBuilder(
        builder: (BuildContext context, StateSetter setState) {
          return boilerplate(
            child: CupertinoSegmentedControl<int>(
              children: children,
              onValueChanged: (int newValue) {
                setState(() {
                  sharedValue = newValue;
                });
              },
              groupValue: sharedValue,
            ),
          );
        },
      ),
      const Duration(milliseconds: 40),
    );
    expect(getBackgroundColor(tester, 0), const Color(0xff7bbaff));
    expect(getBackgroundColor(tester, 1), const Color(0x95007aff));

    await tester.pumpWidget(
      StatefulBuilder(
        builder: (BuildContext context, StateSetter setState) {
          return boilerplate(
            child: CupertinoSegmentedControl<int>(
              children: children,
              onValueChanged: (int newValue) {
                setState(() {
                  sharedValue = newValue;
                });
              },
              groupValue: sharedValue,
            ),
          );
        },
      ),
      const Duration(milliseconds: 40),
    );
    expect(getBackgroundColor(tester, 0), const Color(0xffb9daff));
    expect(getBackgroundColor(tester, 1), const Color(0xc7007aff));

    await tester.pumpWidget(
      StatefulBuilder(
        builder: (BuildContext context, StateSetter setState) {
          return boilerplate(
            child: CupertinoSegmentedControl<int>(
              children: children,
              onValueChanged: (int newValue) {
                setState(() {
                  sharedValue = newValue;
                });
              },
              groupValue: sharedValue,
            ),
          );
        },
      ),
      const Duration(milliseconds: 40),
    );
    expect(getBackgroundColor(tester, 0), const Color(0xfff7faff));
    expect(getBackgroundColor(tester, 1), const Color(0xf8007aff));

    await tester.pumpWidget(
      StatefulBuilder(
        builder: (BuildContext context, StateSetter setState) {
          return boilerplate(
            child: CupertinoSegmentedControl<int>(
              children: children,
              onValueChanged: (int newValue) {
                setState(() {
                  sharedValue = newValue;
                });
              },
              groupValue: sharedValue,
            ),
          );
        },
      ),
      const Duration(milliseconds: 40),
    );
    expect(getBackgroundColor(tester, 0), isSameColorAs(CupertinoColors.white));
    expect(getBackgroundColor(tester, 1), CupertinoColors.activeBlue);
  });

  testWidgets('Multiple segments are pressed', (WidgetTester tester) async {
    final Map<int, Widget> children = <int, Widget>{};
    children[0] = const Text('A');
    children[1] = const Text('B');
    children[2] = const Text('C');
    int sharedValue = 0;

    await tester.pumpWidget(
      StatefulBuilder(
        builder: (BuildContext context, StateSetter setState) {
          return boilerplate(
            child: CupertinoSegmentedControl<int>(
              key: const ValueKey<String>('Segmented Control'),
              children: children,
              onValueChanged: (int newValue) {
                setState(() {
                  sharedValue = newValue;
                });
              },
              groupValue: sharedValue,
            ),
          );
        },
      ),
    );

    expect(getBackgroundColor(tester, 1), isSameColorAs(CupertinoColors.white));

    await tester.startGesture(tester.getCenter(find.text('B')));
    await tester.pumpAndSettle(const Duration(milliseconds: 200));

    expect(getBackgroundColor(tester, 1), const Color(0x33007aff));
    expect(getBackgroundColor(tester, 2), isSameColorAs(CupertinoColors.white));

    await tester.startGesture(tester.getCenter(find.text('C')));
    await tester.pumpAndSettle(const Duration(milliseconds: 200));

    // Press on C has no effect while B is held down.
    expect(getBackgroundColor(tester, 1), const Color(0x33007aff));
    expect(getBackgroundColor(tester, 2), isSameColorAs(CupertinoColors.white));
  });

  testWidgets('Transition is triggered while a transition is already occurring', (WidgetTester tester) async {
    final Map<int, Widget> children = <int, Widget>{};
    children[0] = const Text('A');
    children[1] = const Text('B');
    children[2] = const Text('C');
    int sharedValue = 0;

    await tester.pumpWidget(
      StatefulBuilder(
        builder: (BuildContext context, StateSetter setState) {
          return boilerplate(
            child: CupertinoSegmentedControl<int>(
              key: const ValueKey<String>('Segmented Control'),
              children: children,
              onValueChanged: (int newValue) {
                setState(() {
                  sharedValue = newValue;
                });
              },
              groupValue: sharedValue,
            ),
          );
        },
      ),
    );

    await tester.tap(find.text('B'));

    await tester.pump();
    expect(getBackgroundColor(tester, 0), CupertinoColors.activeBlue);
    expect(getBackgroundColor(tester, 1), const Color(0x33007aff));

    await tester.pump(const Duration(milliseconds: 40));
    expect(getBackgroundColor(tester, 0), const Color(0xff3d9aff));
    expect(getBackgroundColor(tester, 1), const Color(0x64007aff));

    // While A to B transition is occurring, press on C.
    await tester.tap(find.text('C'));

    await tester.pump();

    // A and B are now both transitioning to white.
    expect(getBackgroundColor(tester, 0), const Color(0xff3d9aff));
    expect(getBackgroundColor(tester, 1), const Color(0xffc1deff));
    expect(getBackgroundColor(tester, 2), const Color(0x33007aff));

    await tester.pump(const Duration(milliseconds: 40));
    // B background color has reached unselected state.
    expect(getBackgroundColor(tester, 0), const Color(0xff7bbaff));
    expect(getBackgroundColor(tester, 1), isSameColorAs(CupertinoColors.white));
    expect(getBackgroundColor(tester, 2), const Color(0x64007aff));

    await tester.pump(const Duration(milliseconds: 100));
    // A background color has reached unselected state.
    expect(getBackgroundColor(tester, 0), isSameColorAs(CupertinoColors.white));
    expect(getBackgroundColor(tester, 2), const Color(0xe0007aff));

    await tester.pump(const Duration(milliseconds: 40));
    // C background color has reached selected state.
    expect(getBackgroundColor(tester, 2), CupertinoColors.activeBlue);
  });

  testWidgets('Segment is selected while it is transitioning to unselected state', (WidgetTester tester) async {
    await tester.pumpWidget(setupSimpleSegmentedControl());

    await tester.tap(find.text('Child 2'));

    await tester.pump();
    expect(getBackgroundColor(tester, 0), CupertinoColors.activeBlue);
    expect(getBackgroundColor(tester, 1), const Color(0x33007aff));

    await tester.pump(const Duration(milliseconds: 40));
    expect(getBackgroundColor(tester, 0), const Color(0xff3d9aff));
    expect(getBackgroundColor(tester, 1), const Color(0x64007aff));

    // While A to B transition is occurring, press on A again.
    await tester.tap(find.text('Child 1'));

    await tester.pump();

    // Both transitions start to reverse.
    expect(getBackgroundColor(tester, 0), const Color(0xcd007aff));
    expect(getBackgroundColor(tester, 1), const Color(0xffc1deff));

    await tester.pump(const Duration(milliseconds: 40));
    // A and B finish transitioning.
    expect(getBackgroundColor(tester, 0), CupertinoColors.activeBlue);
    expect(getBackgroundColor(tester, 1), isSameColorAs(CupertinoColors.white));
  });

  testWidgets('Add segment while animation is running', (WidgetTester tester) async {
    Map<int, Widget> children = <int, Widget>{};
    children[0] = const Text('A');
    children[1] = const Text('B');
    children[2] = const Text('C');
    int sharedValue = 0;

    await tester.pumpWidget(
      StatefulBuilder(
        builder: (BuildContext context, StateSetter setState) {
          return boilerplate(
            child: CupertinoSegmentedControl<int>(
              key: const ValueKey<String>('Segmented Control'),
              children: children,
              onValueChanged: (int newValue) {
                setState(() {
                  sharedValue = newValue;
                });
                if (sharedValue == 1) {
                  children = Map<int, Widget>.from(children);
                  children[3] = const Text('D');
                }
              },
              groupValue: sharedValue,
            ),
          );
        },
      ),
    );

    await tester.tap(find.text('B'));

    await tester.pump();
    expect(getBackgroundColor(tester, 0), isSameColorAs(CupertinoColors.white));
    expect(getBackgroundColor(tester, 1), CupertinoColors.activeBlue);
    expect(getBackgroundColor(tester, 3), isSameColorAs(CupertinoColors.white));

    await tester.pump(const Duration(milliseconds: 40));
    expect(getBackgroundColor(tester, 0), isSameColorAs(CupertinoColors.white));
    expect(getBackgroundColor(tester, 1), CupertinoColors.activeBlue);
    expect(getBackgroundColor(tester, 3), isSameColorAs(CupertinoColors.white));

    await tester.pump(const Duration(milliseconds: 150));
    expect(getBackgroundColor(tester, 0), isSameColorAs(CupertinoColors.white));
    expect(getBackgroundColor(tester, 1), CupertinoColors.activeBlue);
    expect(getBackgroundColor(tester, 3), isSameColorAs(CupertinoColors.white));
  });

  testWidgets('Remove segment while animation is running', (WidgetTester tester) async {
    Map<int, Widget> children = <int, Widget>{};
    children[0] = const Text('A');
    children[1] = const Text('B');
    children[2] = const Text('C');
    int sharedValue = 0;

    await tester.pumpWidget(
      StatefulBuilder(
        builder: (BuildContext context, StateSetter setState) {
          return boilerplate(
            child: CupertinoSegmentedControl<int>(
              key: const ValueKey<String>('Segmented Control'),
              children: children,
              onValueChanged: (int newValue) {
                setState(() {
                  sharedValue = newValue;
                });
                if (sharedValue == 1) {
                  children.remove(2);
                  children = Map<int, Widget>.from(children);
                }
              },
              groupValue: sharedValue,
            ),
          );
        },
      ),
    );

    expect(getChildCount(tester), 3);

    await tester.tap(find.text('B'));

    await tester.pump();
    expect(getBackgroundColor(tester, 1), const Color(0x33007aff));
    expect(getChildCount(tester), 2);

    await tester.pump(const Duration(milliseconds: 40));
    expect(getBackgroundColor(tester, 1), const Color(0x64007aff));

    await tester.pump(const Duration(milliseconds: 150));
    expect(getBackgroundColor(tester, 1), CupertinoColors.activeBlue);
  });

  testWidgets('Remove currently animating segment', (WidgetTester tester) async {
    Map<int, Widget> children = <int, Widget>{};
    children[0] = const Text('A');
    children[1] = const Text('B');
    children[2] = const Text('C');
    int? sharedValue = 0;

    await tester.pumpWidget(
      StatefulBuilder(
        builder: (BuildContext context, StateSetter setState) {
          return boilerplate(
            child: CupertinoSegmentedControl<int>(
              key: const ValueKey<String>('Segmented Control'),
              children: children,
              onValueChanged: (int newValue) {
                setState(() {
                  sharedValue = newValue;
                });
                if (sharedValue == 1) {
                  children.remove(1);
                  children = Map<int, Widget>.from(children);
                  sharedValue = null;
                }
              },
              groupValue: sharedValue,
            ),
          );
        },
      ),
    );

    expect(getChildCount(tester), 3);

    await tester.tap(find.text('B'));

    await tester.pump();
    expect(getChildCount(tester), 2);

    await tester.pump(const Duration(milliseconds: 40));
    expect(getBackgroundColor(tester, 0), const Color(0xff3d9aff));
    expect(getBackgroundColor(tester, 1), isSameColorAs(CupertinoColors.white));

    await tester.pump(const Duration(milliseconds: 40));
    expect(getBackgroundColor(tester, 0), const Color(0xff7bbaff));
    expect(getBackgroundColor(tester, 1), isSameColorAs(CupertinoColors.white));

    await tester.pump(const Duration(milliseconds: 100));
    expect(getBackgroundColor(tester, 0), isSameColorAs(CupertinoColors.white));
    expect(getBackgroundColor(tester, 1), isSameColorAs(CupertinoColors.white));
  });

  // Regression test: https://github.com/flutter/flutter/issues/43414.
  testWidgets("Quick double tap doesn't break the internal state", (WidgetTester tester) async {
    const Map<int, Widget> children = <int, Widget>{
      0: Text('A'),
      1: Text('B'),
      2: Text('C'),
    };
    int sharedValue = 0;

    await tester.pumpWidget(
      StatefulBuilder(
        builder: (BuildContext context, StateSetter setState) {
          return boilerplate(
            child: CupertinoSegmentedControl<int>(
              key: const ValueKey<String>('Segmented Control'),
              children: children,
              onValueChanged: (int newValue) {
                setState(() { sharedValue = newValue; });
              },
              groupValue: sharedValue,
            ),
          );
        },
      ),
    );

    await tester.tap(find.text('B'));
    // sharedValue has been updated but widget.groupValue is not.
    expect(sharedValue, 1);

    // Land the second tap before the widget gets a chance to rebuild.
    final TestGesture secondTap = await tester.startGesture(tester.getCenter(find.text('B')));
    await tester.pump();

    await secondTap.up();
    expect(sharedValue, 1);

    await tester.tap(find.text('C'));
    expect(sharedValue, 2);
  });

  testWidgets('Golden Test Placeholder Widget', (WidgetTester tester) async {
    final Map<int, Widget> children = <int, Widget>{};
    children[0] = Container();
    children[1] = const Placeholder();
    children[2] = Container();

    const int currentValue = 0;

    await tester.pumpWidget(
      RepaintBoundary(
        child: StatefulBuilder(
          builder: (BuildContext context, StateSetter setState) {
            return boilerplate(
              child: SizedBox(
                width: 800.0,
                child: CupertinoSegmentedControl<int>(
                  key: const ValueKey<String>('Segmented Control'),
                  children: children,
                  onValueChanged: (int newValue) { },
                  groupValue: currentValue,
                ),
              ),
            );
          },
        ),
      ),
    );

    await expectLater(
      find.byType(RepaintBoundary),
      matchesGoldenFile('segmented_control_test.0.png'),
    );
  });

  testWidgets('Golden Test Pressed State', (WidgetTester tester) async {
    final Map<int, Widget> children = <int, Widget>{};
    children[0] = const Text('A');
    children[1] = const Text('B');
    children[2] = const Text('C');

    const int currentValue = 0;

    await tester.pumpWidget(
      RepaintBoundary(
        child: StatefulBuilder(
          builder: (BuildContext context, StateSetter setState) {
            return boilerplate(
              child: SizedBox(
                width: 800.0,
                child: CupertinoSegmentedControl<int>(
                  key: const ValueKey<String>('Segmented Control'),
                  children: children,
                  onValueChanged: (int newValue) { },
                  groupValue: currentValue,
                ),
              ),
            );
          },
        ),
      ),
    );

    final Offset center = tester.getCenter(find.text('B'));
    await tester.startGesture(center);
    await tester.pumpAndSettle();

    await expectLater(
      find.byType(RepaintBoundary),
      matchesGoldenFile('segmented_control_test.1.png'),
    );
  });
}
