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

import 'package:flutter/material.dart';
import 'package:flutter_driver/driver_extension.dart';

import 'component1.dart' deferred as component1;

void main() {
  enableFlutterDriverExtension();
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Deferred Components Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: const MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key}) : super(key: key);

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

class MyHomePageState extends State<MyHomePage> {
  Future<void>? libraryFuture;

  Widget postLoadDisplayWidget = const Text(
      'placeholder',
      key: Key('PlaceholderText'),
    );

  @override
  void initState() {
    // Automatically trigger load for release test without driver.
    Future<void>.delayed(const Duration(milliseconds: 3000), () {
      _pressHandler();
    });
    super.initState();
  }

  void _pressHandler() {
    if (libraryFuture == null) {
      setState(() {
        libraryFuture = component1.loadLibrary().then((dynamic _) {
          // Delay to give debug runs more than one frame to capture
          // the placeholder text.
          Future<void>.delayed(const Duration(milliseconds: 750), () {
            setState(() {
              // See https://github.com/dart-lang/sdk/issues/46894
              // ignore: prefer_const_constructors
              postLoadDisplayWidget = component1.LogoScreen();
            });
          });
        });
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    final Widget testWidget = libraryFuture == null ? const Text('preload', key: Key('PreloadText')) :
      FutureBuilder<void>(
        future: libraryFuture,
        builder: (BuildContext context, AsyncSnapshot<void> snapshot) {
          if (snapshot.connectionState == ConnectionState.done) {
            if (snapshot.hasError) {
              return Text('Error: ${snapshot.error}');
            }
            return postLoadDisplayWidget;
          }
          return postLoadDisplayWidget;
        },
      );
    return Scaffold(
      appBar: AppBar(
        title: const Text('Deferred components test'),
      ),
      body: Center(
        child: testWidget,
      ),
      floatingActionButton: FloatingActionButton(
        key: const Key('FloatingActionButton'),
        onPressed: _pressHandler,
        tooltip: 'Load',
        child: const Icon(Icons.add),
      ),
    );
  }
}
