// 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 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart';

import '../rendering/mock_canvas.dart';

class TestIcon extends StatefulWidget {
  const TestIcon({ super.key });

  @override
  TestIconState createState() => TestIconState();
}

class TestIconState extends State<TestIcon> {
  late IconThemeData iconTheme;

  @override
  Widget build(BuildContext context) {
    iconTheme = IconTheme.of(context);
    return const Icon(Icons.add);
  }
}

class TestText extends StatefulWidget {
  const TestText(this.text, { super.key });

  final String text;

  @override
  TestTextState createState() => TestTextState();
}

class TestTextState extends State<TestText> {
  late TextStyle textStyle;

  @override
  Widget build(BuildContext context) {
    textStyle = DefaultTextStyle.of(context).style;
    return Text(widget.text);
  }
}

void main() {
  test('ListTileThemeData copyWith, ==, hashCode basics', () {
    expect(const ListTileThemeData(), const ListTileThemeData().copyWith());
    expect(const ListTileThemeData().hashCode, const ListTileThemeData().copyWith().hashCode);
  });

  test('ListTileThemeData defaults', () {
    const ListTileThemeData themeData = ListTileThemeData();
    expect(themeData.dense, null);
    expect(themeData.shape, null);
    expect(themeData.style, null);
    expect(themeData.selectedColor, null);
    expect(themeData.iconColor, null);
    expect(themeData.textColor, null);
    expect(themeData.contentPadding, null);
    expect(themeData.tileColor, null);
    expect(themeData.selectedTileColor, null);
    expect(themeData.horizontalTitleGap, null);
    expect(themeData.minVerticalPadding, null);
    expect(themeData.minLeadingWidth, null);
    expect(themeData.enableFeedback, null);
    expect(themeData.mouseCursor, null);
    expect(themeData.visualDensity, null);
  });

  testWidgets('Default ListTileThemeData debugFillProperties', (WidgetTester tester) async {
    final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder();
    const ListTileThemeData().debugFillProperties(builder);

    final List<String> description = builder.properties
      .where((DiagnosticsNode node) => !node.isFiltered(DiagnosticLevel.info))
      .map((DiagnosticsNode node) => node.toString())
      .toList();

    expect(description, <String>[]);
  });

  testWidgets('ListTileThemeData implements debugFillProperties', (WidgetTester tester) async {
    final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder();
    const ListTileThemeData(
      dense: true,
      shape: StadiumBorder(),
      style: ListTileStyle.drawer,
      selectedColor: Color(0x00000001),
      iconColor: Color(0x00000002),
      textColor: Color(0x00000003),
      contentPadding: EdgeInsets.all(100),
      tileColor: Color(0x00000004),
      selectedTileColor: Color(0x00000005),
      horizontalTitleGap: 200,
      minVerticalPadding: 300,
      minLeadingWidth: 400,
      enableFeedback: true,
      mouseCursor: MaterialStateMouseCursor.clickable,
      visualDensity: VisualDensity.comfortable,
    ).debugFillProperties(builder);

    final List<String> description = builder.properties
      .where((DiagnosticsNode node) => !node.isFiltered(DiagnosticLevel.info))
      .map((DiagnosticsNode node) => node.toString())
      .toList();

    expect(description[0], 'dense: true');
    expect(description[1], 'shape: StadiumBorder(BorderSide(Color(0xff000000), 0.0, BorderStyle.none))');
    expect(description[2], 'style: drawer');
    expect(description[3], 'selectedColor: Color(0x00000001)');
    expect(description[4], 'iconColor: Color(0x00000002)');
    expect(description[5], 'textColor: Color(0x00000003)');
    expect(description[6], 'contentPadding: EdgeInsets.all(100.0)');
    expect(description[7], 'tileColor: Color(0x00000004)');
    expect(description[8], 'selectedTileColor: Color(0x00000005)');
    expect(description[9], 'horizontalTitleGap: 200.0');
    expect(description[10], 'minVerticalPadding: 300.0');
    expect(description[11], 'minLeadingWidth: 400.0');
    expect(description[12], 'enableFeedback: true');
    expect(description[13], 'mouseCursor: MaterialStateMouseCursor(clickable)');
    expect(
      description[14],
      equalsIgnoringHashCodes('visualDensity: VisualDensity#00000(h: -1.0, v: -1.0)(horizontal: -1.0, vertical: -1.0)'),
    );
  });

  testWidgets('ListTileTheme backwards compatibility constructor', (WidgetTester tester) async {
    late ListTileThemeData theme;

    await tester.pumpWidget(
      MaterialApp(
        home: Material(
          child: ListTileTheme(
            dense: true,
            shape: const StadiumBorder(),
            style: ListTileStyle.drawer,
            selectedColor: const Color(0x00000001),
            iconColor: const Color(0x00000002),
            textColor: const Color(0x00000003),
            contentPadding: const EdgeInsets.all(100),
            tileColor: const Color(0x00000004),
            selectedTileColor: const Color(0x00000005),
            horizontalTitleGap: 200,
            minVerticalPadding: 300,
            minLeadingWidth: 400,
            enableFeedback: true,
            mouseCursor: MaterialStateMouseCursor.clickable,
            child: Center(
              child: Builder(
                builder: (BuildContext context) {
                  theme = ListTileTheme.of(context);
                  return const Placeholder();
                },
              ),
            ),
          ),
        ),
      ),
    );

    expect(theme.dense, true);
    expect(theme.shape, const StadiumBorder());
    expect(theme.style, ListTileStyle.drawer);
    expect(theme.selectedColor, const Color(0x00000001));
    expect(theme.iconColor, const Color(0x00000002));
    expect(theme.textColor, const Color(0x00000003));
    expect(theme.contentPadding, const EdgeInsets.all(100));
    expect(theme.tileColor, const Color(0x00000004));
    expect(theme.selectedTileColor, const Color(0x00000005));
    expect(theme.horizontalTitleGap, 200);
    expect(theme.minVerticalPadding, 300);
    expect(theme.minLeadingWidth, 400);
    expect(theme.enableFeedback, true);
    expect(theme.mouseCursor, MaterialStateMouseCursor.clickable);
  });

  testWidgets('ListTileTheme', (WidgetTester tester) async {
    final Key listTileKey = UniqueKey();
    final Key titleKey = UniqueKey();
    final Key subtitleKey = UniqueKey();
    final Key leadingKey = UniqueKey();
    final Key trailingKey = UniqueKey();
    late ThemeData theme;

    Widget buildFrame({
      bool enabled = true,
      bool dense = false,
      bool selected = false,
      ShapeBorder? shape,
      Color? selectedColor,
      Color? iconColor,
      Color? textColor,
    }) {
      return MaterialApp(
        home: Material(
          child: Center(
            child: ListTileTheme(
              data: ListTileThemeData(
                dense: dense,
                shape: shape,
                selectedColor: selectedColor,
                iconColor: iconColor,
                textColor: textColor,
                mouseCursor: MaterialStateProperty.resolveWith((Set<MaterialState> states) {
                  if (states.contains(MaterialState.disabled)) {
                    return SystemMouseCursors.forbidden;
                  }

                  return SystemMouseCursors.click;
                }),
                visualDensity: VisualDensity.compact,
              ),
              child: Builder(
                builder: (BuildContext context) {
                  theme = Theme.of(context);
                  return ListTile(
                    key: listTileKey,
                    enabled: enabled,
                    selected: selected,
                    leading: TestIcon(key: leadingKey),
                    trailing: TestIcon(key: trailingKey),
                    title: TestText('title', key: titleKey),
                    subtitle: TestText('subtitle', key: subtitleKey),
                  );
                },
              ),
            ),
          ),
        ),
      );
    }

    const Color green = Color(0xFF00FF00);
    const Color red = Color(0xFFFF0000);
    const ShapeBorder roundedShape = RoundedRectangleBorder(
      borderRadius: BorderRadius.all(Radius.circular(4.0)),
    );

    Color iconColor(Key key) => tester.state<TestIconState>(find.byKey(key)).iconTheme.color!;
    Color textColor(Key key) => tester.state<TestTextState>(find.byKey(key)).textStyle.color!;
    ShapeBorder inkWellBorder() => tester.widget<InkWell>(find.descendant(of: find.byType(ListTile), matching: find.byType(InkWell))).customBorder!;

    // A selected ListTile's leading, trailing, and text get the primary color by default
    await tester.pumpWidget(buildFrame(selected: true));
    await tester.pump(const Duration(milliseconds: 300)); // DefaultTextStyle changes animate
    expect(iconColor(leadingKey), theme.primaryColor);
    expect(iconColor(trailingKey), theme.primaryColor);
    expect(textColor(titleKey), theme.primaryColor);
    expect(textColor(subtitleKey), theme.primaryColor);

    // A selected ListTile's leading, trailing, and text get the ListTileTheme's selectedColor
    await tester.pumpWidget(buildFrame(selected: true, selectedColor: green));
    await tester.pump(const Duration(milliseconds: 300)); // DefaultTextStyle changes animate
    expect(iconColor(leadingKey), green);
    expect(iconColor(trailingKey), green);
    expect(textColor(titleKey), green);
    expect(textColor(subtitleKey), green);

    // An unselected ListTile's leading and trailing get the ListTileTheme's iconColor
    // An unselected ListTile's title texts get the ListTileTheme's textColor
    await tester.pumpWidget(buildFrame(iconColor: red, textColor: green));
    await tester.pump(const Duration(milliseconds: 300)); // DefaultTextStyle changes animate
    expect(iconColor(leadingKey), red);
    expect(iconColor(trailingKey), red);
    expect(textColor(titleKey), green);
    expect(textColor(subtitleKey), green);

    // If the item is disabled it's rendered with the theme's disabled color.
    await tester.pumpWidget(buildFrame(enabled: false));
    await tester.pump(const Duration(milliseconds: 300)); // DefaultTextStyle changes animate
    expect(iconColor(leadingKey), theme.disabledColor);
    expect(iconColor(trailingKey), theme.disabledColor);
    expect(textColor(titleKey), theme.disabledColor);
    expect(textColor(subtitleKey), theme.disabledColor);

    // If the item is disabled it's rendered with the theme's disabled color.
    // Even if it's selected.
    await tester.pumpWidget(buildFrame(enabled: false, selected: true));
    await tester.pump(const Duration(milliseconds: 300)); // DefaultTextStyle changes animate
    expect(iconColor(leadingKey), theme.disabledColor);
    expect(iconColor(trailingKey), theme.disabledColor);
    expect(textColor(titleKey), theme.disabledColor);
    expect(textColor(subtitleKey), theme.disabledColor);

    // A selected ListTile's InkWell gets the ListTileTheme's shape
    await tester.pumpWidget(buildFrame(selected: true, shape: roundedShape));
    expect(inkWellBorder(), roundedShape);

    // Cursor updates when hovering disabled ListTile
    await tester.pumpWidget(buildFrame(enabled: false));
    final Offset listTile = tester.getCenter(find.byKey(titleKey));
    final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
    await gesture.addPointer();
    addTearDown(gesture.removePointer);
    await gesture.moveTo(listTile);
    await tester.pumpAndSettle();
    expect(RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.forbidden);

    // VisualDensity is respected
    final RenderBox box = tester.renderObject(find.byKey(listTileKey));
    expect(box.size, equals(const Size(800, 64.0)));
  });

  testWidgets('ListTileTheme colors are applied to leading and trailing text widgets', (WidgetTester tester) async {
    final Key leadingKey = UniqueKey();
    final Key trailingKey = UniqueKey();

    const Color selectedColor = Colors.orange;
    const Color defaultColor = Colors.black;

    late ThemeData theme;
    Widget buildFrame({
      bool enabled = true,
      bool selected = false,
    }) {
      return MaterialApp(
        home: Material(
          child: Center(
            child: ListTileTheme(
              data: const ListTileThemeData(
                selectedColor: selectedColor,
                textColor: defaultColor,
              ),
              child: Builder(
                builder: (BuildContext context) {
                  theme = Theme.of(context);
                  return ListTile(
                    enabled: enabled,
                    selected: selected,
                    leading: TestText('leading', key: leadingKey),
                    title: const TestText('title'),
                    trailing: TestText('trailing', key: trailingKey),
                  );
                },
              ),
            ),
          ),
        ),
      );
    }

    Color textColor(Key key) => tester.state<TestTextState>(find.byKey(key)).textStyle.color!;

    await tester.pumpWidget(buildFrame());
    // Enabled color should use ListTileTheme.textColor.
    expect(textColor(leadingKey), defaultColor);
    expect(textColor(trailingKey), defaultColor);

    await tester.pumpWidget(buildFrame(selected: true));
    // Wait for text color to animate.
    await tester.pumpAndSettle();
    // Selected color should use ListTileTheme.selectedColor.
    expect(textColor(leadingKey), selectedColor);
    expect(textColor(trailingKey), selectedColor);

    await tester.pumpWidget(buildFrame(enabled: false));
    // Wait for text color to animate.
    await tester.pumpAndSettle();
    // Disabled color should be ThemeData.disabledColor.
    expect(textColor(leadingKey), theme.disabledColor);
    expect(textColor(trailingKey), theme.disabledColor);
  });

  testWidgets("ListTile respects ListTileTheme's tileColor & selectedTileColor", (WidgetTester tester) async {
    late ListTileThemeData theme;
    bool isSelected = false;

    await tester.pumpWidget(
      MaterialApp(
        home: Material(
          child: ListTileTheme(
            data: ListTileThemeData(
              tileColor: Colors.green.shade500,
              selectedTileColor: Colors.red.shade500,
            ),
            child: Center(
              child: StatefulBuilder(
                builder: (BuildContext context, StateSetter setState) {
                  theme = ListTileTheme.of(context);
                  return ListTile(
                    selected: isSelected,
                    onTap: () {
                      setState(()=> isSelected = !isSelected);
                    },
                    title: const Text('Title'),
                  );
                },
              ),
            ),
          ),
        ),
      ),
    );

    expect(find.byType(Material), paints..path(color: theme.tileColor));

    // Tap on tile to change isSelected.
    await tester.tap(find.byType(ListTile));
    await tester.pumpAndSettle();

    expect(find.byType(Material), paints..path(color: theme.selectedTileColor));
  });

  testWidgets("ListTileTheme's tileColor & selectedTileColor are overridden by ListTile properties", (WidgetTester tester) async {
    bool isSelected = false;
    final Color tileColor = Colors.green.shade500;
    final Color selectedTileColor = Colors.red.shade500;

    await tester.pumpWidget(
      MaterialApp(
        home: Material(
          child: ListTileTheme(
            data: const ListTileThemeData(
              selectedTileColor: Colors.green,
              tileColor: Colors.red,
            ),
            child: Center(
              child: StatefulBuilder(
                builder: (BuildContext context, StateSetter setState) {
                  return ListTile(
                    tileColor: tileColor,
                    selectedTileColor: selectedTileColor,
                    selected: isSelected,
                    onTap: () {
                      setState(()=> isSelected = !isSelected);
                    },
                    title: const Text('Title'),
                  );
                },
              ),
            ),
          ),
        ),
      ),
    );

    expect(find.byType(Material), paints..path(color: tileColor));

    // Tap on tile to change isSelected.
    await tester.tap(find.byType(ListTile));
    await tester.pumpAndSettle();

    expect(find.byType(Material), paints..path(color: selectedTileColor));
  });
}
