// 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.

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

void main() {
  const TextTheme defaultGeometryTheme = Typography.englishLike2014;
  const TextTheme defaultGeometryThemeM3 = Typography.englishLike2021;

  test('ThemeDataTween control test', () {
    final light = ThemeData();
    final dark = ThemeData.dark();
    final tween = ThemeDataTween(begin: light, end: dark);
    expect(tween.lerp(0.25), equals(ThemeData.lerp(light, dark, 0.25)));
  });

  testWidgets('PopupMenu inherits app theme', (WidgetTester tester) async {
    final Key popupMenuButtonKey = UniqueKey();
    await tester.pumpWidget(
      MaterialApp(
        theme: ThemeData(brightness: Brightness.dark),
        home: Scaffold(
          appBar: AppBar(
            actions: <Widget>[
              PopupMenuButton<String>(
                key: popupMenuButtonKey,
                itemBuilder: (BuildContext context) {
                  return <PopupMenuItem<String>>[
                    const PopupMenuItem<String>(child: Text('menuItem')),
                  ];
                },
              ),
            ],
          ),
        ),
      ),
    );

    await tester.tap(find.byKey(popupMenuButtonKey));
    await tester.pump(const Duration(seconds: 1));

    expect(Theme.of(tester.element(find.text('menuItem'))).brightness, equals(Brightness.dark));
  });

  group('Theme.brightnessOf', () {
    testWidgets('return correct brightness when just media query is given', (
      WidgetTester tester,
    ) async {
      await tester.pumpWidget(
        const MediaQuery(
          data: MediaQueryData(platformBrightness: Brightness.dark),
          child: SizedBox(),
        ),
      );

      expect(Theme.brightnessOf(tester.element(find.byType(SizedBox))), equals(Brightness.dark));
    });

    testWidgets('return correct brightness with overriding theme brightness over media query', (
      WidgetTester tester,
    ) async {
      await tester.pumpWidget(
        MediaQuery(
          data: const MediaQueryData(platformBrightness: Brightness.dark),
          child: Theme(
            data: ThemeData(brightness: Brightness.light),
            child: const SizedBox(),
          ),
        ),
      );

      expect(Theme.brightnessOf(tester.element(find.byType(SizedBox))), equals(Brightness.light));
    });

    testWidgets('returns Brightness.light when no theme or media query is present', (
      WidgetTester tester,
    ) async {
      // Prevent the implicitly added View from adding a MediaQuery
      await tester.pumpWidget(
        RawView(view: FakeFlutterView(tester.view, viewId: 77), child: const SizedBox()),
        wrapWithView: false,
      );

      expect(Theme.brightnessOf(tester.element(find.byType(SizedBox))), equals(Brightness.light));
    });
  });

  group('Theme.maybeBrightnessOf', () {
    testWidgets('return correct brightness when just media query is given', (
      WidgetTester tester,
    ) async {
      await tester.pumpWidget(
        const MediaQuery(
          data: MediaQueryData(platformBrightness: Brightness.dark),
          child: SizedBox(),
        ),
      );

      expect(
        Theme.maybeBrightnessOf(tester.element(find.byType(SizedBox))),
        equals(Brightness.dark),
      );
    });

    testWidgets('return correct brightness with overriding theme brightness over media query', (
      WidgetTester tester,
    ) async {
      await tester.pumpWidget(
        MediaQuery(
          data: const MediaQueryData(platformBrightness: Brightness.dark),
          child: Theme(
            data: ThemeData(brightness: Brightness.light),
            child: const SizedBox(),
          ),
        ),
      );

      expect(
        Theme.maybeBrightnessOf(tester.element(find.byType(SizedBox))),
        equals(Brightness.light),
      );
    });

    testWidgets('returns null when no theme or media query is present', (
      WidgetTester tester,
    ) async {
      // Prevent the implicitly added View from adding a MediaQuery
      await tester.pumpWidget(
        RawView(view: FakeFlutterView(tester.view, viewId: 77), child: const SizedBox()),
        wrapWithView: false,
      );

      expect(Theme.maybeBrightnessOf(tester.element(find.byType(SizedBox))), isNull);
    });
  });

  testWidgets('Theme overrides selection style', (WidgetTester tester) async {
    final Key key = UniqueKey();
    const defaultSelectionColor = Color(0x11111111);
    const defaultCursorColor = Color(0x22222222);
    const themeSelectionColor = Color(0x33333333);
    const themeCursorColor = Color(0x44444444);
    await tester.pumpWidget(
      MaterialApp(
        theme: ThemeData(brightness: Brightness.dark),
        home: Scaffold(
          body: DefaultSelectionStyle(
            selectionColor: defaultSelectionColor,
            cursorColor: defaultCursorColor,
            child: Theme(
              data: ThemeData(
                textSelectionTheme: const TextSelectionThemeData(
                  selectionColor: themeSelectionColor,
                  cursorColor: themeCursorColor,
                ),
              ),
              child: TextField(key: key),
            ),
          ),
        ),
      ),
    );
    // Finds RenderEditable.
    final RenderObject root = tester.renderObject(find.byType(EditableText));
    late RenderEditable renderEditable;
    void recursiveFinder(RenderObject child) {
      if (child is RenderEditable) {
        renderEditable = child;
        return;
      }
      child.visitChildren(recursiveFinder);
    }

    root.visitChildren(recursiveFinder);

    // Focus text field so it has a selection color. The selection color is null
    // on an unfocused text field.
    await tester.tap(find.byKey(key));
    await tester.pump();

    expect(renderEditable.selectionColor, themeSelectionColor);
    expect(tester.widget<EditableText>(find.byType(EditableText)).cursorColor, themeCursorColor);
  });

  testWidgets('Material2 - Fallback theme', (WidgetTester tester) async {
    late BuildContext capturedContext;
    await tester.pumpWidget(
      Theme(
        data: ThemeData(useMaterial3: false),
        child: Builder(
          builder: (BuildContext context) {
            capturedContext = context;
            return Container();
          },
        ),
      ),
    );

    expect(
      Theme.of(capturedContext),
      equals(ThemeData.localize(ThemeData.fallback(useMaterial3: false), defaultGeometryTheme)),
    );
  });

  testWidgets('Material3 - Fallback theme', (WidgetTester tester) async {
    late BuildContext capturedContextM3;
    await tester.pumpWidget(
      Theme(
        data: ThemeData(),
        child: Builder(
          builder: (BuildContext context) {
            capturedContextM3 = context;
            return Container();
          },
        ),
      ),
    );

    expect(
      Theme.of(capturedContextM3),
      equals(ThemeData.localize(ThemeData.fallback(), defaultGeometryThemeM3)),
    );
  });

  testWidgets('ThemeData.localize memoizes the result', (WidgetTester tester) async {
    final light = ThemeData();
    final dark = ThemeData.dark();

    // Same input, same output.
    expect(
      ThemeData.localize(light, defaultGeometryTheme),
      same(ThemeData.localize(light, defaultGeometryTheme)),
    );

    // Different text geometry, different output.
    expect(
      ThemeData.localize(light, defaultGeometryTheme),
      isNot(same(ThemeData.localize(light, Typography.tall2014))),
    );

    // Different base theme, different output.
    expect(
      ThemeData.localize(light, defaultGeometryTheme),
      isNot(same(ThemeData.localize(dark, defaultGeometryTheme))),
    );
  });

  testWidgets('Material2 - ThemeData with null typography uses proper defaults', (
    WidgetTester tester,
  ) async {
    final m2Theme = ThemeData(useMaterial3: false);
    expect(m2Theme.typography, Typography.material2014());
  });

  testWidgets('Material3 - ThemeData with null typography uses proper defaults', (
    WidgetTester tester,
  ) async {
    final m3Theme = ThemeData();
    expect(m3Theme.typography, Typography.material2021(colorScheme: m3Theme.colorScheme));
  });

  testWidgets('PopupMenu inherits shadowed app theme', (WidgetTester tester) async {
    // Regression test for https://github.com/flutter/flutter/issues/5572
    final Key popupMenuButtonKey = UniqueKey();
    await tester.pumpWidget(
      MaterialApp(
        theme: ThemeData(brightness: Brightness.dark),
        home: Theme(
          data: ThemeData(brightness: Brightness.light),
          child: Scaffold(
            appBar: AppBar(
              actions: <Widget>[
                PopupMenuButton<String>(
                  key: popupMenuButtonKey,
                  itemBuilder: (BuildContext context) {
                    return <PopupMenuItem<String>>[
                      const PopupMenuItem<String>(child: Text('menuItem')),
                    ];
                  },
                ),
              ],
            ),
          ),
        ),
      ),
    );

    await tester.tap(find.byKey(popupMenuButtonKey));
    await tester.pump(const Duration(seconds: 1));

    expect(Theme.of(tester.element(find.text('menuItem'))).brightness, equals(Brightness.light));
  });

  testWidgets('DropdownMenu inherits shadowed app theme', (WidgetTester tester) async {
    final Key dropdownMenuButtonKey = UniqueKey();
    await tester.pumpWidget(
      MaterialApp(
        theme: ThemeData(brightness: Brightness.dark),
        home: Theme(
          data: ThemeData(brightness: Brightness.light),
          child: Scaffold(
            appBar: AppBar(
              actions: <Widget>[
                DropdownButton<String>(
                  key: dropdownMenuButtonKey,
                  onChanged: (String? newValue) {},
                  value: 'menuItem',
                  items: const <DropdownMenuItem<String>>[
                    DropdownMenuItem<String>(value: 'menuItem', child: Text('menuItem')),
                  ],
                ),
              ],
            ),
          ),
        ),
      ),
    );

    await tester.tap(find.byKey(dropdownMenuButtonKey));
    await tester.pump(const Duration(seconds: 1));

    for (final Element item in tester.elementList(find.text('menuItem'))) {
      expect(Theme.of(item).brightness, equals(Brightness.light));
    }
  });

  testWidgets('ModalBottomSheet inherits shadowed app theme', (WidgetTester tester) async {
    await tester.pumpWidget(
      MaterialApp(
        theme: ThemeData(brightness: Brightness.dark),
        home: Theme(
          data: ThemeData(brightness: Brightness.light),
          child: Scaffold(
            body: Center(
              child: Builder(
                builder: (BuildContext context) {
                  return ElevatedButton(
                    onPressed: () {
                      showModalBottomSheet<void>(
                        context: context,
                        builder: (BuildContext context) => const Text('bottomSheet'),
                      );
                    },
                    child: const Text('SHOW'),
                  );
                },
              ),
            ),
          ),
        ),
      ),
    );

    await tester.tap(find.text('SHOW'));
    await tester.pump(); // start animation
    await tester.pump(const Duration(seconds: 1)); // end animation
    expect(Theme.of(tester.element(find.text('bottomSheet'))).brightness, equals(Brightness.light));
  });

  testWidgets('Dialog inherits shadowed app theme', (WidgetTester tester) async {
    final scaffoldKey = GlobalKey<ScaffoldState>();
    await tester.pumpWidget(
      MaterialApp(
        theme: ThemeData(brightness: Brightness.dark),
        home: Theme(
          data: ThemeData(brightness: Brightness.light),
          child: Scaffold(
            key: scaffoldKey,
            body: Center(
              child: Builder(
                builder: (BuildContext context) {
                  return ElevatedButton(
                    onPressed: () {
                      showDialog<void>(
                        context: context,
                        builder: (BuildContext context) => const Text('dialog'),
                      );
                    },
                    child: const Text('SHOW'),
                  );
                },
              ),
            ),
          ),
        ),
      ),
    );

    await tester.tap(find.text('SHOW'));
    await tester.pump(const Duration(seconds: 1));
    expect(Theme.of(tester.element(find.text('dialog'))).brightness, equals(Brightness.light));
  });

  testWidgets("Scaffold inherits theme's scaffoldBackgroundColor", (WidgetTester tester) async {
    const green = Color(0xFF00FF00);

    await tester.pumpWidget(
      MaterialApp(
        theme: ThemeData(scaffoldBackgroundColor: green),
        home: Scaffold(
          body: Center(
            child: Builder(
              builder: (BuildContext context) {
                return GestureDetector(
                  onTap: () {
                    showDialog<void>(
                      context: context,
                      builder: (BuildContext context) {
                        return const Scaffold(body: SizedBox(width: 200.0, height: 200.0));
                      },
                    );
                  },
                  child: const Text('SHOW'),
                );
              },
            ),
          ),
        ),
      ),
    );

    await tester.tap(find.text('SHOW'));
    await tester.pump(const Duration(seconds: 1));

    final List<Material> materials = tester.widgetList<Material>(find.byType(Material)).toList();
    expect(materials.length, equals(2));
    expect(materials[0].color, green); // app scaffold
    expect(materials[1].color, green); // dialog scaffold
  });

  testWidgets('IconThemes are applied', (WidgetTester tester) async {
    await tester.pumpWidget(
      MaterialApp(
        theme: ThemeData(iconTheme: const IconThemeData(color: Colors.green, size: 10.0)),
        home: const Icon(Icons.computer),
      ),
    );

    RenderParagraph glyphText = tester.renderObject(find.byType(RichText));

    expect(glyphText.text.style!.color, Colors.green);
    expect(glyphText.text.style!.fontSize, 10.0);

    await tester.pumpWidget(
      MaterialApp(
        theme: ThemeData(iconTheme: const IconThemeData(color: Colors.orange, size: 20.0)),
        home: const Icon(Icons.computer),
      ),
    );
    await tester.pump(const Duration(milliseconds: 100)); // Halfway through the theme transition

    glyphText = tester.renderObject(find.byType(RichText));

    expect(glyphText.text.style!.color, Color.lerp(Colors.green, Colors.orange, 0.5));
    expect(glyphText.text.style!.fontSize, 15.0);

    await tester.pump(const Duration(milliseconds: 100)); // Finish the transition
    glyphText = tester.renderObject(find.byType(RichText));

    expect(glyphText.text.style!.color, Colors.orange);
    expect(glyphText.text.style!.fontSize, 20.0);
  });

  testWidgets('Same ThemeData reapplied does not trigger descendants rebuilds', (
    WidgetTester tester,
  ) async {
    testBuildCalled = 0;
    var themeData = ThemeData(primaryColor: const Color(0xFF000000));

    Widget buildTheme() {
      return Theme(data: themeData, child: const Test());
    }

    await tester.pumpWidget(buildTheme());
    expect(testBuildCalled, 1);

    // Pump the same widgets again.
    await tester.pumpWidget(buildTheme());
    // No repeated build calls to the child since it's the same theme data.
    expect(testBuildCalled, 1);

    // New instance of theme data but still the same content.
    themeData = ThemeData(primaryColor: const Color(0xFF000000));
    await tester.pumpWidget(buildTheme());
    // Still no repeated calls.
    expect(testBuildCalled, 1);

    // Different now.
    themeData = ThemeData(primaryColor: const Color(0xFF222222));
    await tester.pumpWidget(buildTheme());
    // Should call build again.
    expect(testBuildCalled, 2);
  });

  testWidgets('Text geometry set in Theme has higher precedence than that of Localizations', (
    WidgetTester tester,
  ) async {
    const kMagicFontSize = 4321.0;
    final fallback = ThemeData.fallback();
    final ThemeData customTheme = fallback.copyWith(
      primaryTextTheme: fallback.primaryTextTheme.copyWith(
        bodyMedium: fallback.primaryTextTheme.bodyMedium!.copyWith(fontSize: kMagicFontSize),
      ),
    );
    expect(customTheme.primaryTextTheme.bodyMedium!.fontSize, kMagicFontSize);

    late double actualFontSize;
    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: Theme(
          data: customTheme,
          child: Builder(
            builder: (BuildContext context) {
              final ThemeData theme = Theme.of(context);
              actualFontSize = theme.primaryTextTheme.bodyMedium!.fontSize!;
              return Text('A', style: theme.primaryTextTheme.bodyMedium);
            },
          ),
        ),
      ),
    );

    expect(actualFontSize, kMagicFontSize);
  });

  testWidgets('Material2 - Default Theme provides all basic TextStyle properties', (
    WidgetTester tester,
  ) async {
    late ThemeData theme;
    await tester.pumpWidget(
      Theme(
        data: ThemeData(useMaterial3: false),
        child: Directionality(
          textDirection: TextDirection.ltr,
          child: Builder(
            builder: (BuildContext context) {
              theme = Theme.of(context);
              return const Text('A');
            },
          ),
        ),
      ),
    );

    List<TextStyle> extractStyles(TextTheme textTheme) {
      return <TextStyle>[
        textTheme.displayLarge!,
        textTheme.displayMedium!,
        textTheme.displaySmall!,
        textTheme.headlineLarge!,
        textTheme.headlineMedium!,
        textTheme.headlineSmall!,
        textTheme.titleLarge!,
        textTheme.titleMedium!,
        textTheme.bodyLarge!,
        textTheme.bodyMedium!,
        textTheme.bodySmall!,
        textTheme.labelLarge!,
        textTheme.labelMedium!,
        // textTheme.labelSmall!,
      ];
    }

    for (final textTheme in <TextTheme>[theme.textTheme, theme.primaryTextTheme]) {
      for (final TextStyle style in extractStyles(
        textTheme,
      ).map<TextStyle>((TextStyle style) => _TextStyleProxy(style))) {
        expect(style.inherit, false);
        expect(style.color, isNotNull);
        expect(style.fontFamily, isNotNull);
        expect(style.fontSize, isNotNull);
        expect(style.fontWeight, isNotNull);
        expect(style.fontStyle, null);
        expect(style.letterSpacing, null);
        expect(style.wordSpacing, null);
        expect(style.textBaseline, isNotNull);
        expect(style.height, null);
        expect(style.decoration, TextDecoration.none);
        expect(style.decorationColor, null);
        expect(style.decorationStyle, null);
        expect(style.debugLabel, isNotNull);
        expect(style.locale, null);
        expect(style.background, null);
      }
    }

    expect(
      theme.textTheme.displayLarge!.debugLabel,
      '(englishLike displayLarge 2014).merge(blackMountainView displayLarge)',
    );
  });

  testWidgets('Material3 - Default Theme provides all basic TextStyle properties', (
    WidgetTester tester,
  ) async {
    late ThemeData theme;
    await tester.pumpWidget(
      Theme(
        data: ThemeData(),
        child: Directionality(
          textDirection: TextDirection.ltr,
          child: Builder(
            builder: (BuildContext context) {
              theme = Theme.of(context);
              return const Text('A');
            },
          ),
        ),
      ),
    );

    List<TextStyle> extractStyles(TextTheme textTheme) {
      return <TextStyle>[
        textTheme.displayLarge!,
        textTheme.displayMedium!,
        textTheme.displaySmall!,
        textTheme.headlineLarge!,
        textTheme.headlineMedium!,
        textTheme.headlineSmall!,
        textTheme.titleLarge!,
        textTheme.titleMedium!,
        textTheme.bodyLarge!,
        textTheme.bodyMedium!,
        textTheme.bodySmall!,
        textTheme.labelLarge!,
        textTheme.labelMedium!,
      ];
    }

    for (final textTheme in <TextTheme>[theme.textTheme, theme.primaryTextTheme]) {
      for (final TextStyle style in extractStyles(
        textTheme,
      ).map<TextStyle>((TextStyle style) => _TextStyleProxy(style))) {
        expect(style.inherit, false);
        expect(style.color, isNotNull);
        expect(style.fontFamily, isNotNull);
        expect(style.fontSize, isNotNull);
        expect(style.fontWeight, isNotNull);
        expect(style.fontStyle, null);
        expect(style.letterSpacing, isNotNull);
        expect(style.wordSpacing, null);
        expect(style.textBaseline, isNotNull);
        expect(style.height, isNotNull);
        expect(style.decoration, TextDecoration.none);
        expect(style.decorationColor, isNotNull);
        expect(style.decorationStyle, null);
        expect(style.debugLabel, isNotNull);
        expect(style.locale, null);
        expect(style.background, null);
      }
    }

    expect(
      theme.textTheme.displayLarge!.debugLabel,
      '(englishLike displayLarge 2021).merge((blackMountainView displayLarge).apply)',
    );
  });

  group('Cupertino theme', () {
    late int buildCount;
    CupertinoThemeData? actualTheme;
    IconThemeData? actualIconTheme;
    BuildContext? context;

    final Widget singletonThemeSubtree = Builder(
      builder: (BuildContext localContext) {
        buildCount++;
        actualTheme = CupertinoTheme.of(localContext);
        actualIconTheme = IconTheme.of(localContext);
        context = localContext;
        return const Placeholder();
      },
    );

    Future<CupertinoThemeData> testTheme(WidgetTester tester, ThemeData theme) async {
      await tester.pumpWidget(Theme(data: theme, child: singletonThemeSubtree));
      return actualTheme!;
    }

    setUp(() {
      buildCount = 0;
      actualTheme = null;
      actualIconTheme = null;
      context = null;
    });

    testWidgets('Material2 - Default light theme has defaults', (WidgetTester tester) async {
      final CupertinoThemeData themeM2 = await testTheme(tester, ThemeData(useMaterial3: false));

      expect(themeM2.brightness, Brightness.light);
      expect(themeM2.primaryColor, Colors.blue);
      expect(themeM2.scaffoldBackgroundColor, Colors.grey[50]);
      expect(themeM2.primaryContrastingColor, Colors.white);
      expect(themeM2.textTheme.textStyle.fontFamily, 'CupertinoSystemText');
      expect(themeM2.textTheme.textStyle.fontSize, 17.0);
    });

    testWidgets('Material3 - Default light theme has defaults', (WidgetTester tester) async {
      final CupertinoThemeData themeM3 = await testTheme(tester, ThemeData());

      expect(themeM3.brightness, Brightness.light);
      expect(themeM3.primaryColor, const Color(0xff6750a4));
      expect(themeM3.scaffoldBackgroundColor, const Color(0xfffef7ff)); // ColorScheme.background
      expect(themeM3.primaryContrastingColor, Colors.white);
      expect(themeM3.textTheme.textStyle.fontFamily, 'CupertinoSystemText');
      expect(themeM3.textTheme.textStyle.fontSize, 17.0);
    });

    testWidgets('Material2 - Dark theme has defaults', (WidgetTester tester) async {
      final CupertinoThemeData themeM2 = await testTheme(
        tester,
        ThemeData.dark(useMaterial3: false),
      );

      expect(themeM2.brightness, Brightness.dark);
      expect(themeM2.primaryColor, Colors.blue);
      expect(themeM2.primaryContrastingColor, Colors.white);
      expect(themeM2.scaffoldBackgroundColor, Colors.grey[850]);
      expect(themeM2.textTheme.textStyle.fontFamily, 'CupertinoSystemText');
      expect(themeM2.textTheme.textStyle.fontSize, 17.0);
    });

    testWidgets('Material3 - Dark theme has defaults', (WidgetTester tester) async {
      final CupertinoThemeData themeM3 = await testTheme(tester, ThemeData.dark());

      expect(themeM3.brightness, Brightness.dark);
      expect(themeM3.primaryColor, const Color(0xffd0bcff));
      expect(themeM3.primaryContrastingColor, const Color(0xff381e72));
      expect(themeM3.scaffoldBackgroundColor, const Color(0xff141218));
      expect(themeM3.textTheme.textStyle.fontFamily, 'CupertinoSystemText');
      expect(themeM3.textTheme.textStyle.fontSize, 17.0);
    });

    testWidgets('MaterialTheme overrides the brightness', (WidgetTester tester) async {
      await testTheme(tester, ThemeData.dark());
      expect(CupertinoTheme.brightnessOf(context!), Brightness.dark);

      await testTheme(tester, ThemeData());
      expect(CupertinoTheme.brightnessOf(context!), Brightness.light);

      // Overridable by cupertinoOverrideTheme.
      await testTheme(
        tester,
        ThemeData(
          brightness: Brightness.light,
          cupertinoOverrideTheme: const CupertinoThemeData(brightness: Brightness.dark),
        ),
      );
      expect(CupertinoTheme.brightnessOf(context!), Brightness.dark);

      await testTheme(
        tester,
        ThemeData(
          brightness: Brightness.dark,
          cupertinoOverrideTheme: const CupertinoThemeData(brightness: Brightness.light),
        ),
      );
      expect(CupertinoTheme.brightnessOf(context!), Brightness.light);
    });

    testWidgets('Cupertino widgets correctly get the right text theme in dark mode', (
      WidgetTester tester,
    ) async {
      final GlobalKey textFieldKey = GlobalKey();
      await tester.pumpWidget(
        MaterialApp(
          theme: ThemeData.dark(),
          home: Scaffold(body: CupertinoTextField(key: textFieldKey)),
        ),
      );
      await tester.pumpAndSettle();

      final EditableTextState state = tester.state<EditableTextState>(find.byType(EditableText));

      // Default CupertinoTextStyle color is a CupertinoDynamicColor.
      final CupertinoThemeData cupertinoThemeData = CupertinoTheme.of(textFieldKey.currentContext!);
      expect(cupertinoThemeData.textTheme.textStyle.color, isA<CupertinoDynamicColor>());
      final themeTextStyleColor =
          cupertinoThemeData.textTheme.textStyle.color! as CupertinoDynamicColor;

      // The value of the textfield's color should resolve to the theme's dark color.
      expect(state.widget.style.color?.value, equals(themeTextStyleColor.darkColor.value));
    });

    testWidgets('Material2 - Can override material theme', (WidgetTester tester) async {
      final CupertinoThemeData themeM2 = await testTheme(
        tester,
        ThemeData(
          cupertinoOverrideTheme: const CupertinoThemeData(
            scaffoldBackgroundColor: CupertinoColors.lightBackgroundGray,
          ),
          useMaterial3: false,
        ),
      );

      expect(themeM2.brightness, Brightness.light);
      // We took the scaffold background override but the rest are still cascaded
      // to the material themeM2.
      expect(themeM2.primaryColor, Colors.blue);
      expect(themeM2.primaryContrastingColor, Colors.white);
      expect(themeM2.scaffoldBackgroundColor, CupertinoColors.lightBackgroundGray);
      expect(themeM2.textTheme.textStyle.fontFamily, 'CupertinoSystemText');
      expect(themeM2.textTheme.textStyle.fontSize, 17.0);
    });

    testWidgets('Material3 - Can override material theme', (WidgetTester tester) async {
      final CupertinoThemeData themeM3 = await testTheme(
        tester,
        ThemeData(
          cupertinoOverrideTheme: const CupertinoThemeData(
            scaffoldBackgroundColor: CupertinoColors.lightBackgroundGray,
          ),
        ),
      );

      expect(themeM3.brightness, Brightness.light);
      // We took the scaffold background override but the rest are still cascaded
      // to the material themeM3.
      expect(themeM3.primaryColor, const Color(0xff6750a4));
      expect(themeM3.primaryContrastingColor, Colors.white);
      expect(themeM3.scaffoldBackgroundColor, CupertinoColors.lightBackgroundGray);
      expect(themeM3.textTheme.textStyle.fontFamily, 'CupertinoSystemText');
      expect(themeM3.textTheme.textStyle.fontSize, 17.0);
    });

    testWidgets('Material2 - Can override properties that are independent of material', (
      WidgetTester tester,
    ) async {
      final CupertinoThemeData themeM2 = await testTheme(
        tester,
        ThemeData(
          cupertinoOverrideTheme: const CupertinoThemeData(
            // The bar colors ignore all things material except brightness.
            barBackgroundColor: CupertinoColors.black,
          ),
          useMaterial3: false,
        ),
      );

      expect(themeM2.primaryColor, Colors.blue);
      // MaterialBasedCupertinoThemeData should also function like a normal CupertinoThemeData.
      expect(themeM2.barBackgroundColor, CupertinoColors.black);
    });

    testWidgets('Material3 - Can override properties that are independent of material', (
      WidgetTester tester,
    ) async {
      final CupertinoThemeData themeM3 = await testTheme(
        tester,
        ThemeData(
          cupertinoOverrideTheme: const CupertinoThemeData(
            // The bar colors ignore all things material except brightness.
            barBackgroundColor: CupertinoColors.black,
          ),
        ),
      );

      expect(themeM3.primaryColor, const Color(0xff6750a4));
      // MaterialBasedCupertinoThemeData should also function like a normal CupertinoThemeData.
      expect(themeM3.barBackgroundColor, CupertinoColors.black);
    });

    testWidgets('Material2 - Changing material theme triggers rebuilds', (
      WidgetTester tester,
    ) async {
      CupertinoThemeData themeM2 = await testTheme(
        tester,
        ThemeData(useMaterial3: false, primarySwatch: Colors.red),
      );

      expect(buildCount, 1);
      expect(themeM2.primaryColor, Colors.red);

      themeM2 = await testTheme(
        tester,
        ThemeData(useMaterial3: false, primarySwatch: Colors.orange),
      );

      expect(buildCount, 2);
      expect(themeM2.primaryColor, Colors.orange);
    });

    testWidgets('Material3 - Changing material theme triggers rebuilds', (
      WidgetTester tester,
    ) async {
      CupertinoThemeData themeM3 = await testTheme(
        tester,
        ThemeData(colorScheme: const ColorScheme.light(primary: Colors.red)),
      );

      expect(buildCount, 1);
      expect(themeM3.primaryColor, Colors.red);

      themeM3 = await testTheme(
        tester,
        ThemeData(colorScheme: const ColorScheme.light(primary: Colors.orange)),
      );

      expect(buildCount, 2);
      expect(themeM3.primaryColor, Colors.orange);
    });

    testWidgets("CupertinoThemeData does not override material theme's icon theme", (
      WidgetTester tester,
    ) async {
      const Color materialIconColor = Colors.blue;
      const Color cupertinoIconColor = Colors.black;

      await testTheme(
        tester,
        ThemeData(
          iconTheme: const IconThemeData(color: materialIconColor),
          cupertinoOverrideTheme: const CupertinoThemeData(primaryColor: cupertinoIconColor),
        ),
      );

      expect(buildCount, 1);
      expect(actualIconTheme!.color, materialIconColor);
    });

    testWidgets('Changing cupertino theme override triggers rebuilds', (WidgetTester tester) async {
      CupertinoThemeData theme = await testTheme(
        tester,
        ThemeData(
          primarySwatch: Colors.purple,
          cupertinoOverrideTheme: const CupertinoThemeData(
            primaryColor: CupertinoColors.activeOrange,
          ),
        ),
      );

      expect(buildCount, 1);
      expect(theme.primaryColor, CupertinoColors.activeOrange);

      theme = await testTheme(
        tester,
        ThemeData(
          primarySwatch: Colors.purple,
          cupertinoOverrideTheme: const CupertinoThemeData(
            primaryColor: CupertinoColors.activeGreen,
          ),
        ),
      );

      expect(buildCount, 2);
      expect(theme.primaryColor, CupertinoColors.activeGreen);
    });

    testWidgets('Cupertino theme override blocks derivative changes', (WidgetTester tester) async {
      CupertinoThemeData theme = await testTheme(
        tester,
        ThemeData(
          primarySwatch: Colors.purple,
          cupertinoOverrideTheme: const CupertinoThemeData(
            primaryColor: CupertinoColors.activeOrange,
          ),
        ),
      );

      expect(buildCount, 1);
      expect(theme.primaryColor, CupertinoColors.activeOrange);

      // Change the upstream material primary color.
      theme = await testTheme(
        tester,
        ThemeData(
          primarySwatch: Colors.blue,
          cupertinoOverrideTheme: const CupertinoThemeData(
            // But the primary material color is preempted by the override.
            primaryColor: CupertinoColors.systemRed,
          ),
        ),
      );

      expect(buildCount, 2);
      expect(theme.primaryColor, CupertinoColors.systemRed);
    });

    testWidgets(
      'Material2 - Cupertino overrides do not block derivatives triggering rebuilds when derivatives are not overridden',
      (WidgetTester tester) async {
        CupertinoThemeData theme = await testTheme(
          tester,
          ThemeData(
            useMaterial3: false,
            primarySwatch: Colors.purple,
            cupertinoOverrideTheme: const CupertinoThemeData(
              primaryContrastingColor: CupertinoColors.destructiveRed,
            ),
          ),
        );

        expect(buildCount, 1);
        expect(theme.textTheme.actionTextStyle.color, Colors.purple);
        expect(theme.primaryContrastingColor, CupertinoColors.destructiveRed);

        theme = await testTheme(
          tester,
          ThemeData(
            useMaterial3: false,
            primarySwatch: Colors.green,
            cupertinoOverrideTheme: const CupertinoThemeData(
              primaryContrastingColor: CupertinoColors.destructiveRed,
            ),
          ),
        );

        expect(buildCount, 2);
        expect(theme.textTheme.actionTextStyle.color, Colors.green);
        expect(theme.primaryContrastingColor, CupertinoColors.destructiveRed);
      },
    );

    testWidgets(
      'Material3 - Cupertino overrides do not block derivatives triggering rebuilds when derivatives are not overridden',
      (WidgetTester tester) async {
        CupertinoThemeData theme = await testTheme(
          tester,
          ThemeData(
            colorScheme: const ColorScheme.light(primary: Colors.purple),
            cupertinoOverrideTheme: const CupertinoThemeData(
              primaryContrastingColor: CupertinoColors.destructiveRed,
            ),
          ),
        );

        expect(buildCount, 1);
        expect(theme.textTheme.actionTextStyle.color, Colors.purple);
        expect(theme.primaryContrastingColor, CupertinoColors.destructiveRed);

        theme = await testTheme(
          tester,
          ThemeData(
            colorScheme: const ColorScheme.light(primary: Colors.green),
            cupertinoOverrideTheme: const CupertinoThemeData(
              primaryContrastingColor: CupertinoColors.destructiveRed,
            ),
          ),
        );

        expect(buildCount, 2);
        expect(theme.textTheme.actionTextStyle.color, Colors.green);
        expect(theme.primaryContrastingColor, CupertinoColors.destructiveRed);
      },
    );

    testWidgets(
      'Material2 - copyWith only copies the overrides, not the material or cupertino derivatives',
      (WidgetTester tester) async {
        final CupertinoThemeData originalTheme = await testTheme(
          tester,
          ThemeData(
            useMaterial3: false,
            primarySwatch: Colors.purple,
            cupertinoOverrideTheme: const CupertinoThemeData(
              primaryContrastingColor: CupertinoColors.activeOrange,
            ),
          ),
        );

        final CupertinoThemeData copiedTheme = originalTheme.copyWith(
          barBackgroundColor: CupertinoColors.destructiveRed,
        );

        final CupertinoThemeData theme = await testTheme(
          tester,
          ThemeData(
            useMaterial3: false,
            primarySwatch: Colors.blue,
            cupertinoOverrideTheme: copiedTheme,
          ),
        );

        expect(theme.primaryColor, Colors.blue);
        expect(theme.primaryContrastingColor, CupertinoColors.activeOrange);
        expect(theme.barBackgroundColor, CupertinoColors.destructiveRed);
      },
    );

    testWidgets(
      'Material3 - copyWith only copies the overrides, not the material or cupertino derivatives',
      (WidgetTester tester) async {
        final CupertinoThemeData originalTheme = await testTheme(
          tester,
          ThemeData(
            colorScheme: const ColorScheme.light(primary: Colors.purple),
            cupertinoOverrideTheme: const CupertinoThemeData(
              primaryContrastingColor: CupertinoColors.activeOrange,
            ),
          ),
        );

        final CupertinoThemeData copiedTheme = originalTheme.copyWith(
          barBackgroundColor: CupertinoColors.destructiveRed,
        );

        final CupertinoThemeData theme = await testTheme(
          tester,
          ThemeData(
            colorScheme: const ColorScheme.light(primary: Colors.blue),
            cupertinoOverrideTheme: copiedTheme,
          ),
        );

        expect(theme.primaryColor, Colors.blue);
        expect(theme.primaryContrastingColor, CupertinoColors.activeOrange);
        expect(theme.barBackgroundColor, CupertinoColors.destructiveRed);
      },
    );

    testWidgets("Material2 - Material themes with no cupertino overrides can also be copyWith'ed", (
      WidgetTester tester,
    ) async {
      final CupertinoThemeData originalTheme = await testTheme(
        tester,
        ThemeData(useMaterial3: false, primarySwatch: Colors.purple),
      );

      final CupertinoThemeData copiedTheme = originalTheme.copyWith(
        primaryContrastingColor: CupertinoColors.destructiveRed,
      );

      final CupertinoThemeData theme = await testTheme(
        tester,
        ThemeData(
          useMaterial3: false,
          primarySwatch: Colors.blue,
          cupertinoOverrideTheme: copiedTheme,
        ),
      );

      expect(theme.primaryColor, Colors.blue);
      expect(theme.primaryContrastingColor, CupertinoColors.destructiveRed);
    });

    testWidgets("Material3 - Material themes with no cupertino overrides can also be copyWith'ed", (
      WidgetTester tester,
    ) async {
      final CupertinoThemeData originalTheme = await testTheme(
        tester,
        ThemeData(colorScheme: const ColorScheme.light(primary: Colors.purple)),
      );

      final CupertinoThemeData copiedTheme = originalTheme.copyWith(
        primaryContrastingColor: CupertinoColors.destructiveRed,
      );

      final CupertinoThemeData theme = await testTheme(
        tester,
        ThemeData(
          colorScheme: const ColorScheme.light(primary: Colors.blue),
          cupertinoOverrideTheme: copiedTheme,
        ),
      );

      expect(theme.primaryColor, Colors.blue);
      expect(theme.primaryContrastingColor, CupertinoColors.destructiveRed);
    });
  });
}

int testBuildCalled = 0;

class Test extends StatelessWidget {
  const Test({super.key});

  @override
  Widget build(BuildContext context) {
    testBuildCalled += 1;
    return Container(decoration: BoxDecoration(color: Theme.of(context).primaryColor));
  }
}

/// This class exists only to make sure that we test all the properties of the
/// [TextStyle] class. If a property is added/removed/renamed, the analyzer will
/// complain that this class has incorrect overrides.
class _TextStyleProxy implements TextStyle {
  _TextStyleProxy(this._delegate);

  final TextStyle _delegate;

  // Do make sure that all the properties correctly forward to the _delegate.
  @override
  Color? get color => _delegate.color;
  @override
  Color? get backgroundColor => _delegate.backgroundColor;
  @override
  String? get debugLabel => _delegate.debugLabel;
  @override
  TextDecoration? get decoration => _delegate.decoration;
  @override
  Color? get decorationColor => _delegate.decorationColor;
  @override
  TextDecorationStyle? get decorationStyle => _delegate.decorationStyle;
  @override
  double? get decorationThickness => _delegate.decorationThickness;
  @override
  String? get fontFamily => _delegate.fontFamily;
  @override
  List<String>? get fontFamilyFallback => _delegate.fontFamilyFallback;
  @override
  double? get fontSize => _delegate.fontSize;
  @override
  FontStyle? get fontStyle => _delegate.fontStyle;
  @override
  FontWeight? get fontWeight => _delegate.fontWeight;
  @override
  double? get height => _delegate.height;
  @override
  TextLeadingDistribution? get leadingDistribution => _delegate.leadingDistribution;
  @override
  Locale? get locale => _delegate.locale;
  @override
  ui.Paint? get foreground => _delegate.foreground;
  @override
  ui.Paint? get background => _delegate.background;
  @override
  bool get inherit => _delegate.inherit;
  @override
  double? get letterSpacing => _delegate.letterSpacing;
  @override
  TextBaseline? get textBaseline => _delegate.textBaseline;
  @override
  double? get wordSpacing => _delegate.wordSpacing;
  @override
  List<Shadow>? get shadows => _delegate.shadows;
  @override
  List<ui.FontFeature>? get fontFeatures => _delegate.fontFeatures;
  @override
  List<ui.FontVariation>? get fontVariations => _delegate.fontVariations;
  @override
  TextOverflow? get overflow => _delegate.overflow;

  @override
  String toString({DiagnosticLevel minLevel = DiagnosticLevel.info}) => super.toString();

  @override
  DiagnosticsNode toDiagnosticsNode({String? name, DiagnosticsTreeStyle? style}) {
    throw UnimplementedError();
  }

  @override
  String toStringShort() {
    throw UnimplementedError();
  }

  @override
  TextStyle apply({
    Color? color,
    Color? backgroundColor,
    TextDecoration? decoration,
    Color? decorationColor,
    TextDecorationStyle? decorationStyle,
    double decorationThicknessFactor = 1.0,
    double decorationThicknessDelta = 0.0,
    String? fontFamily,
    List<String>? fontFamilyFallback,
    double fontSizeFactor = 1.0,
    double fontSizeDelta = 0.0,
    int fontWeightDelta = 0,
    FontStyle? fontStyle,
    double letterSpacingFactor = 1.0,
    double letterSpacingDelta = 0.0,
    double wordSpacingFactor = 1.0,
    double wordSpacingDelta = 0.0,
    double heightFactor = 1.0,
    double heightDelta = 0.0,
    TextLeadingDistribution? leadingDistribution,
    TextBaseline? textBaseline,
    Locale? locale,
    List<ui.Shadow>? shadows,
    List<ui.FontFeature>? fontFeatures,
    List<ui.FontVariation>? fontVariations,
    TextOverflow? overflow,
    String? package,
  }) {
    throw UnimplementedError();
  }

  @override
  RenderComparison compareTo(TextStyle other) {
    throw UnimplementedError();
  }

  @override
  TextStyle copyWith({
    bool? inherit,
    Color? color,
    Color? backgroundColor,
    String? fontFamily,
    List<String>? fontFamilyFallback,
    double? fontSize,
    FontWeight? fontWeight,
    FontStyle? fontStyle,
    double? letterSpacing,
    double? wordSpacing,
    TextBaseline? textBaseline,
    double? height,
    TextLeadingDistribution? leadingDistribution,
    Locale? locale,
    ui.Paint? foreground,
    ui.Paint? background,
    List<Shadow>? shadows,
    List<ui.FontFeature>? fontFeatures,
    List<ui.FontVariation>? fontVariations,
    TextDecoration? decoration,
    Color? decorationColor,
    TextDecorationStyle? decorationStyle,
    double? decorationThickness,
    String? debugLabel,
    TextOverflow? overflow,
    String? package,
  }) {
    throw UnimplementedError();
  }

  @override
  void debugFillProperties(DiagnosticPropertiesBuilder properties, {String prefix = ''}) {
    throw UnimplementedError();
  }

  @override
  ui.ParagraphStyle getParagraphStyle({
    TextAlign? textAlign,
    TextDirection? textDirection,
    double textScaleFactor = 1.0,
    TextScaler textScaler = TextScaler.noScaling,
    String? ellipsis,
    int? maxLines,
    ui.TextHeightBehavior? textHeightBehavior,
    Locale? locale,
    String? fontFamily,
    double? fontSize,
    FontWeight? fontWeight,
    FontStyle? fontStyle,
    double? height,
    StrutStyle? strutStyle,
  }) {
    throw UnimplementedError();
  }

  @override
  ui.TextStyle getTextStyle({
    double textScaleFactor = 1.0,
    TextScaler textScaler = TextScaler.noScaling,
  }) {
    throw UnimplementedError();
  }

  @override
  TextStyle merge(TextStyle? other) {
    throw UnimplementedError();
  }
}

class FakeFlutterView extends TestFlutterView {
  FakeFlutterView(TestFlutterView view, {required this.viewId})
    : super(view: view, display: view.display, platformDispatcher: view.platformDispatcher);

  @override
  final int viewId;
}
