// Copyright 2013 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.

// This file is hand-formatted.

import 'dart:io';

import 'package:flutter/material.dart';
import 'package:path/path.dart' as path;
import 'package:path_provider/path_provider.dart';
import 'package:rfw/rfw.dart';

const String urlPrefix = 'https://raw.githubusercontent.com/flutter/packages/main/packages/rfw/example/remote/remote_widget_libraries';

void main() {
  runApp(const MaterialApp(home: Example()));
}

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

  @override
  State<Example> createState() => _ExampleState();
}

class _ExampleState extends State<Example> {
  final Runtime _runtime = Runtime();
  final DynamicContent _data = DynamicContent();

  bool _ready = false;
  int _counter = 0;

  @override
  void initState() {
    super.initState();
    _runtime.update(const LibraryName(<String>['core', 'widgets']), createCoreWidgets());
    _runtime.update(const LibraryName(<String>['core', 'material']), createMaterialWidgets());
    _updateData();
    _updateWidgets();
  }

  void _updateData() {
    _data.update('counter', _counter.toString());
  }

  Future<void> _updateWidgets() async {
    final Directory home = await getApplicationSupportDirectory();
    final File settingsFile = File(path.join(home.path, 'settings.txt'));
    String nextFile = 'counter_app1.rfw';
    if (settingsFile.existsSync()) {
      final String settings = await settingsFile.readAsString();
      if (settings == nextFile) {
        nextFile = 'counter_app2.rfw';
      }
    }
    final File currentFile = File(path.join(home.path, 'current.rfw'));
    if (currentFile.existsSync()) {
      try {
        _runtime.update(const LibraryName(<String>['main']), decodeLibraryBlob(await currentFile.readAsBytes()));
        setState(() {
          _ready = true;
        });
      } catch (e, stack) {
        FlutterError.reportError(FlutterErrorDetails(exception: e, stack: stack));
      }
    }
    print('Fetching: $urlPrefix/$nextFile');
    final HttpClientResponse client = await (await HttpClient().getUrl(Uri.parse('$urlPrefix/$nextFile'))).close();
    await currentFile.writeAsBytes(await client.expand((List<int> chunk) => chunk).toList());
    await settingsFile.writeAsString(nextFile);
  }

  @override
  Widget build(BuildContext context) {
    final Widget result;
    if (_ready) {
      result = RemoteWidget(
        runtime: _runtime,
        data: _data,
        widget: const FullyQualifiedWidgetName(LibraryName(<String>['main']), 'Counter'),
        onEvent: (String name, DynamicMap arguments) {
          if (name == 'increment') {
            _counter += 1;
            _updateData();
          }
        },
      );
    } else {
      result = Material(
        child: SafeArea(
          child: Padding(
            padding: const EdgeInsets.all(20.0),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.stretch,
              children: const <Widget>[
                Padding(padding: EdgeInsets.only(right: 100.0), child: Text('REMOTE', textAlign: TextAlign.center, style: TextStyle(letterSpacing: 12.0))),
                Expanded(child: DecoratedBox(decoration: FlutterLogoDecoration(style: FlutterLogoStyle.horizontal))),
                Padding(padding: EdgeInsets.only(left: 100.0), child: Text('WIDGETS', textAlign: TextAlign.center, style: TextStyle(letterSpacing: 12.0))),
                Spacer(),
                Expanded(child: Text('Every time this program is run, it fetches a new remote widgets library.', textAlign: TextAlign.center)),
                Expanded(child: Text('The interface that it shows is whatever library was last fetched.', textAlign: TextAlign.center)),
                Expanded(child: Text('Restart this application to see the new interface!', textAlign: TextAlign.center)),
              ],
            ),
          ),
        ),
      );
    }
    return AnimatedSwitcher(duration: const Duration(milliseconds: 1250), switchOutCurve: Curves.easeOut, switchInCurve: Curves.easeOut, child: result);
  }
}
