// 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 TestWidget extends StatefulWidget {
  const TestWidget({
    super.key,
    required this.child,
    required this.persistentState,
    required this.syncedState,
  });

  final Widget child;
  final int persistentState;
  final int syncedState;

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

class TestWidgetState extends State<TestWidget> {
  late int persistentState;
  late int syncedState;
  int updates = 0;

  @override
  void initState() {
    super.initState();
    persistentState = widget.persistentState;
    syncedState = widget.syncedState;
  }

  @override
  void didUpdateWidget(TestWidget oldWidget) {
    super.didUpdateWidget(oldWidget);
    syncedState = widget.syncedState;
    // we explicitly do NOT sync the persistentState from the new instance
    // because we're using that to track whether we got recreated
    updates += 1;
  }

  @override
  Widget build(BuildContext context) => widget.child;
}

void main() {

  testWidgets('no change', (WidgetTester tester) async {
    await tester.pumpWidget(
      Container(
        color: Colors.blue,
        child: Container(
          color: Colors.blue,
          child: TestWidget(
            persistentState: 1,
            syncedState: 0,
            child: Container(),
          ),
        ),
      ),
    );

    final TestWidgetState state = tester.state(find.byType(TestWidget));

    expect(state.persistentState, equals(1));
    expect(state.updates, equals(0));

    await tester.pumpWidget(
      Container(
        color: Colors.blue,
        child: Container(
          color: Colors.blue,
          child: TestWidget(
            persistentState: 2,
            syncedState: 0,
            child: Container(),
          ),
        ),
      ),
    );

    expect(state.persistentState, equals(1));
    expect(state.updates, equals(1));

    await tester.pumpWidget(Container());
  });

  testWidgets('remove one', (WidgetTester tester) async {
    await tester.pumpWidget(
      Container(
        color: Colors.blue,
        child: Container(
          color: Colors.blue,
          child: TestWidget(
            persistentState: 10,
            syncedState: 0,
            child: Container(),
          ),
        ),
      ),
    );

    TestWidgetState state = tester.state(find.byType(TestWidget));

    expect(state.persistentState, equals(10));
    expect(state.updates, equals(0));

    await tester.pumpWidget(
      Container(
        color: Colors.green,
        child: TestWidget(
          persistentState: 11,
          syncedState: 0,
          child: Container(),
        ),
      ),
    );

    state = tester.state(find.byType(TestWidget));

    expect(state.persistentState, equals(11));
    expect(state.updates, equals(0));

    await tester.pumpWidget(Container());
  });

  testWidgets('swap instances around', (WidgetTester tester) async {
    const Widget a = TestWidget(persistentState: 0x61, syncedState: 0x41, child: Text('apple', textDirection: TextDirection.ltr));
    const Widget b = TestWidget(persistentState: 0x62, syncedState: 0x42, child: Text('banana', textDirection: TextDirection.ltr));
    await tester.pumpWidget(Column());

    final GlobalKey keyA = GlobalKey();
    final GlobalKey keyB = GlobalKey();

    await tester.pumpWidget(
      Column(
        children: <Widget>[
          Container(
            key: keyA,
            child: a,
          ),
          Container(
            key: keyB,
            child: b,
          ),
        ],
      ),
    );

    TestWidgetState first, second;

    first = tester.state(find.byWidget(a));
    second = tester.state(find.byWidget(b));

    expect(first.widget, equals(a));
    expect(first.persistentState, equals(0x61));
    expect(first.syncedState, equals(0x41));
    expect(second.widget, equals(b));
    expect(second.persistentState, equals(0x62));
    expect(second.syncedState, equals(0x42));

    await tester.pumpWidget(
      Column(
        children: <Widget>[
          Container(
            key: keyA,
            child: a,
          ),
          Container(
            key: keyB,
            child: b,
          ),
        ],
      ),
    );

    first = tester.state(find.byWidget(a));
    second = tester.state(find.byWidget(b));

    // same as before
    expect(first.widget, equals(a));
    expect(first.persistentState, equals(0x61));
    expect(first.syncedState, equals(0x41));
    expect(second.widget, equals(b));
    expect(second.persistentState, equals(0x62));
    expect(second.syncedState, equals(0x42));

    // now we swap the nodes over
    // since they are both "old" nodes, they shouldn't sync with each other even though they look alike

    await tester.pumpWidget(
      Column(
        children: <Widget>[
          Container(
            key: keyA,
            child: b,
          ),
          Container(
            key: keyB,
            child: a,
          ),
        ],
      ),
    );

    first = tester.state(find.byWidget(b));
    second = tester.state(find.byWidget(a));

    expect(first.widget, equals(b));
    expect(first.persistentState, equals(0x61));
    expect(first.syncedState, equals(0x42));
    expect(second.widget, equals(a));
    expect(second.persistentState, equals(0x62));
    expect(second.syncedState, equals(0x41));
  });
}
