// 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';

class MultiWidgetConstructTable extends StatefulWidget {
  const MultiWidgetConstructTable(this.columnCount, this.rowCount, {super.key});

  final int columnCount;
  final int rowCount;

  @override
  State<MultiWidgetConstructTable> createState() => _MultiWidgetConstructTableState();
}

class _MultiWidgetConstructTableState extends State<MultiWidgetConstructTable>
    with SingleTickerProviderStateMixin {
  static const List<MaterialColor> colorList = <MaterialColor>[
    Colors.pink, Colors.red, Colors.deepOrange, Colors.orange, Colors.amber,
    Colors.yellow, Colors.lime, Colors.lightGreen, Colors.green, Colors.teal,
    Colors.cyan, Colors.lightBlue, Colors.blue, Colors.indigo, Colors.purple,
  ];
  int counter = 0;

  late AnimationController _controller;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
      vsync: this,
      duration: const Duration(milliseconds: 10000),
      upperBound: colorList.length + 1.0,
    )..repeat();
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return AnimatedBuilder(
      animation: _controller,
      builder: (BuildContext context, _) {
        final int totalLength = widget.rowCount * widget.columnCount;
        final int widgetCounter = counter * totalLength;
        final double height = MediaQuery.of(context).size.height / widget.rowCount;
        final double colorPosition = _controller.value;
        final int c1Position = colorPosition.floor();
        final Color c1 = colorList[c1Position % colorList.length][900]!;
        final Color c2 = colorList[(c1Position + 1) % colorList.length][900]!;
        final Color baseColor = Color.lerp(c1, c2, colorPosition - c1Position)!;
        counter++;
        return Scaffold(
          body: Table(
            children: List<TableRow>.generate(
              widget.rowCount,
              (int row) => TableRow(
                children: List<Widget>.generate(
                  widget.columnCount,
                  (int column) {
                    final int label = row * widget.columnCount + column;
                    // This implementation rebuild the widget tree for every
                    // frame, and is intentionally designed of poor performance
                    // for benchmark purposes.
                    return counter.isEven
                        ? Container(
                            // This key forces rebuilding the element
                            key: ValueKey<int>(widgetCounter + label),
                            color: Color.lerp(
                                Colors.white, baseColor, label / totalLength),
                            constraints: BoxConstraints.expand(height: height),
                            child: Text('${widgetCounter + label}'),
                          )
                        : MyContainer(
                            // This key forces rebuilding the element
                            key: ValueKey<int>(widgetCounter + label),
                            color: Color.lerp(
                                Colors.white, baseColor, label / totalLength)!,
                            constraints: BoxConstraints.expand(height: height),
                            child: Text('${widgetCounter + label}'),
                          );
                  },
                ),
              ),
            ),
          ),
        );
      },
    );
  }
}

// This class is intended to break the original Widget tree
class MyContainer extends StatelessWidget {
  const MyContainer({required this.color, required this.child, required this.constraints, super.key});
  final Color color;
  final Widget child;
  final BoxConstraints constraints;

  @override
  Widget build(BuildContext context) {
    return Container(
      color: color,
      constraints: constraints,
      child: child,
    );
  }
}
