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

class StateMarker extends StatefulWidget {
  const StateMarker({ super.key, this.child });

  final Widget? child;

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

class StateMarkerState extends State<StateMarker> {
  String? marker;

  @override
  Widget build(BuildContext context) {
    if (widget.child != null) {
      return widget.child!;
    }
    return Container();
  }
}

class DeactivateLogger extends StatefulWidget {
  const DeactivateLogger({ required Key key, required this.log }) : super(key: key);

  final List<String> log;

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

class DeactivateLoggerState extends State<DeactivateLogger> {
  @override
  void deactivate() {
    widget.log.add('deactivate');
    super.deactivate();
  }

  @override
  Widget build(BuildContext context) {
    widget.log.add('build');
    return Container();
  }
}

void main() {
  testWidgets('can reparent state', (WidgetTester tester) async {
    final GlobalKey left = GlobalKey();
    final GlobalKey right = GlobalKey();

    const StateMarker grandchild = StateMarker();
    await tester.pumpWidget(
      Stack(
        textDirection: TextDirection.ltr,
        children: <Widget>[
          ColoredBox(
            color: Colors.green,
            child: StateMarker(key: left),
          ),
          ColoredBox(
            color: Colors.green,
            child: StateMarker(
              key: right,
              child: grandchild,
            ),
          ),
        ],
      ),
    );

    final StateMarkerState leftState = left.currentState! as StateMarkerState;
    leftState.marker = 'left';
    final StateMarkerState rightState = right.currentState! as StateMarkerState;
    rightState.marker = 'right';

    final StateMarkerState grandchildState = tester.state(find.byWidget(grandchild));
    expect(grandchildState, isNotNull);
    grandchildState.marker = 'grandchild';

    const StateMarker newGrandchild = StateMarker();
    await tester.pumpWidget(
      Stack(
        textDirection: TextDirection.ltr,
        children: <Widget>[
          ColoredBox(
            color: Colors.green,
            child: StateMarker(
              key: right,
              child: newGrandchild,
            ),
          ),
          ColoredBox(
            color: Colors.green,
            child: StateMarker(key: left),
          ),
        ],
      ),
    );

    expect(left.currentState, equals(leftState));
    expect(leftState.marker, equals('left'));
    expect(right.currentState, equals(rightState));
    expect(rightState.marker, equals('right'));

    final StateMarkerState newGrandchildState = tester.state(find.byWidget(newGrandchild));
    expect(newGrandchildState, isNotNull);
    expect(newGrandchildState, equals(grandchildState));
    expect(newGrandchildState.marker, equals('grandchild'));

    await tester.pumpWidget(
      Center(
        child: ColoredBox(
          color: Colors.green,
          child: StateMarker(
            key: left,
            child: Container(),
          ),
        ),
      ),
    );

    expect(left.currentState, equals(leftState));
    expect(leftState.marker, equals('left'));
    expect(right.currentState, isNull);
  });

  testWidgets('can reparent state with multichild widgets', (WidgetTester tester) async {
    final GlobalKey left = GlobalKey();
    final GlobalKey right = GlobalKey();

    const StateMarker grandchild = StateMarker();
    await tester.pumpWidget(
      Stack(
        textDirection: TextDirection.ltr,
        children: <Widget>[
          StateMarker(key: left),
          StateMarker(
            key: right,
            child: grandchild,
          ),
        ],
      ),
    );

    final StateMarkerState leftState = left.currentState! as StateMarkerState;
    leftState.marker = 'left';
    final StateMarkerState rightState = right.currentState! as StateMarkerState;
    rightState.marker = 'right';

    final StateMarkerState grandchildState = tester.state(find.byWidget(grandchild));
    expect(grandchildState, isNotNull);
    grandchildState.marker = 'grandchild';

    const StateMarker newGrandchild = StateMarker();
    await tester.pumpWidget(
      Stack(
        textDirection: TextDirection.ltr,
        children: <Widget>[
          StateMarker(
            key: right,
            child: newGrandchild,
          ),
          StateMarker(key: left),
        ],
      ),
    );

    expect(left.currentState, equals(leftState));
    expect(leftState.marker, equals('left'));
    expect(right.currentState, equals(rightState));
    expect(rightState.marker, equals('right'));

    final StateMarkerState newGrandchildState = tester.state(find.byWidget(newGrandchild));
    expect(newGrandchildState, isNotNull);
    expect(newGrandchildState, equals(grandchildState));
    expect(newGrandchildState.marker, equals('grandchild'));

    await tester.pumpWidget(
      Center(
        child: ColoredBox(
          color: Colors.green,
          child: StateMarker(
            key: left,
            child: Container(),
          ),
        ),
      ),
    );

    expect(left.currentState, equals(leftState));
    expect(leftState.marker, equals('left'));
    expect(right.currentState, isNull);
  });

  testWidgets('can with scrollable list', (WidgetTester tester) async {
    final GlobalKey key = GlobalKey();

    await tester.pumpWidget(StateMarker(key: key));

    final StateMarkerState keyState = key.currentState! as StateMarkerState;
    keyState.marker = 'marked';

    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: ListView(
          itemExtent: 100.0,
          children: <Widget>[
            SizedBox(
              key: const Key('container'),
              height: 100.0,
              child: StateMarker(key: key),
            ),
          ],
        ),
      ),
    );

    expect(key.currentState, equals(keyState));
    expect(keyState.marker, equals('marked'));

    await tester.pumpWidget(StateMarker(key: key));

    expect(key.currentState, equals(keyState));
    expect(keyState.marker, equals('marked'));
  });

  testWidgets('Reparent during update children', (WidgetTester tester) async {
    final GlobalKey key = GlobalKey();

    await tester.pumpWidget(Stack(
      textDirection: TextDirection.ltr,
      children: <Widget>[
        StateMarker(key: key),
        const SizedBox(width: 100.0, height: 100.0),
      ],
    ));

    final StateMarkerState keyState = key.currentState!as StateMarkerState;
    keyState.marker = 'marked';

    await tester.pumpWidget(Stack(
      textDirection: TextDirection.ltr,
      children: <Widget>[
        const SizedBox(width: 100.0, height: 100.0),
        StateMarker(key: key),
      ],
    ));

    expect(key.currentState, equals(keyState));
    expect(keyState.marker, equals('marked'));

    await tester.pumpWidget(Stack(
      textDirection: TextDirection.ltr,
      children: <Widget>[
        StateMarker(key: key),
        const SizedBox(width: 100.0, height: 100.0),
      ],
    ));

    expect(key.currentState, equals(keyState));
    expect(keyState.marker, equals('marked'));
  });

  testWidgets('Reparent to child during update children', (WidgetTester tester) async {
    final GlobalKey key = GlobalKey();

    await tester.pumpWidget(Stack(
      textDirection: TextDirection.ltr,
      children: <Widget>[
        const SizedBox(width: 100.0, height: 100.0),
        StateMarker(key: key),
        const SizedBox(width: 100.0, height: 100.0),
      ],
    ));

    final StateMarkerState keyState = key.currentState! as StateMarkerState;
    keyState.marker = 'marked';

    await tester.pumpWidget(Stack(
      textDirection: TextDirection.ltr,
      children: <Widget>[
        SizedBox(width: 100.0, height: 100.0, child: StateMarker(key: key)),
        const SizedBox(width: 100.0, height: 100.0),
      ],
    ));

    expect(key.currentState, equals(keyState));
    expect(keyState.marker, equals('marked'));

    await tester.pumpWidget(Stack(
      textDirection: TextDirection.ltr,
      children: <Widget>[
        const SizedBox(width: 100.0, height: 100.0),
        StateMarker(key: key),
        const SizedBox(width: 100.0, height: 100.0),
      ],
    ));

    expect(key.currentState, equals(keyState));
    expect(keyState.marker, equals('marked'));

    await tester.pumpWidget(Stack(
      textDirection: TextDirection.ltr,
      children: <Widget>[
        const SizedBox(width: 100.0, height: 100.0),
        SizedBox(width: 100.0, height: 100.0, child: StateMarker(key: key)),
      ],
    ));

    expect(key.currentState, equals(keyState));
    expect(keyState.marker, equals('marked'));

    await tester.pumpWidget(Stack(
      textDirection: TextDirection.ltr,
      children: <Widget>[
        const SizedBox(width: 100.0, height: 100.0),
        StateMarker(key: key),
        const SizedBox(width: 100.0, height: 100.0),
      ],
    ));

    expect(key.currentState, equals(keyState));
    expect(keyState.marker, equals('marked'));
  });

  testWidgets('Deactivate implies build', (WidgetTester tester) async {
    final GlobalKey key = GlobalKey();
    final List<String> log = <String>[];
    final DeactivateLogger logger = DeactivateLogger(key: key, log: log);

    await tester.pumpWidget(
      Container(key: UniqueKey(), child: logger),
    );

    expect(log, equals(<String>['build']));

    await tester.pumpWidget(
      Container(key: UniqueKey(), child: logger),
    );

    expect(log, equals(<String>['build', 'deactivate', 'build']));
    log.clear();

    await tester.pump();
    expect(log, isEmpty);
  });

  testWidgets('Reparenting with multiple moves', (WidgetTester tester) async {
    final GlobalKey key1 = GlobalKey();
    final GlobalKey key2 = GlobalKey();
    final GlobalKey key3 = GlobalKey();

    await tester.pumpWidget(
      Row(
        textDirection: TextDirection.ltr,
        children: <Widget>[
          StateMarker(
            key: key1,
            child: StateMarker(
              key: key2,
              child: StateMarker(
                key: key3,
                child: StateMarker(child: Container(width: 100.0)),
              ),
            ),
          ),
        ],
      ),
    );

    await tester.pumpWidget(
      Row(
        textDirection: TextDirection.ltr,
        children: <Widget>[
          StateMarker(
            key: key2,
            child: StateMarker(child: Container(width: 100.0)),
          ),
          StateMarker(
            key: key1,
            child: StateMarker(
              key: key3,
              child: StateMarker(child: Container(width: 100.0)),
            ),
          ),
        ],
      ),
    );
  });
}
