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

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

import 'android_platform_view.dart';
import 'future_data_handler.dart';
import 'page.dart';

class NestedViewEventPage extends PageWidget {
  const NestedViewEventPage({Key? key})
      : super('Nested View Event Tests', const ValueKey<String>('NestedViewEventTile'), key: key);

  @override
  Widget build(BuildContext context) => const NestedViewEventBody();
}

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

  @override
  State<NestedViewEventBody> createState() => NestedViewEventBodyState();
}

enum _LastTestStatus {
  pending,
  success,
  error
}

class NestedViewEventBodyState extends State<NestedViewEventBody> {
  MethodChannel? viewChannel;
  _LastTestStatus _lastTestStatus = _LastTestStatus.pending;
  String? lastError;
  int? id;
  int nestedViewClickCount = 0;
  bool showPlatformView = true;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Nested view event'),
      ),
      body: Column(
        children: <Widget>[
          SizedBox(
            height: 300,
              child: showPlatformView ?
                AndroidPlatformView(
                  key: const ValueKey<String>('PlatformView'),
                  viewType: 'simple_view',
                  onPlatformViewCreated: onPlatformViewCreated,
                ) : null,
          ),
          if (_lastTestStatus != _LastTestStatus.pending) _statusWidget(),
          if (viewChannel != null) ... <Widget>[
            ElevatedButton(
              key: const ValueKey<String>('ShowAlertDialog'),
              onPressed: onShowAlertDialogPressed,
              child: const Text('SHOW ALERT DIALOG'),
            ),
            ElevatedButton(
              key: const ValueKey<String>('TogglePlatformView'),
              onPressed: onTogglePlatformView,
              child: const Text('TOGGLE PLATFORM VIEW'),
            ),
            Row(
              children: <Widget>[
                ElevatedButton(
                  key: const ValueKey<String>('AddChildView'),
                  onPressed: onChildViewPressed,
                  child: const Text('ADD CHILD VIEW'),
                ),
                ElevatedButton(
                  key: const ValueKey<String>('TapChildView'),
                  onPressed: onTapChildViewPressed,
                  child: const Text('TAP CHILD VIEW'),
                ),
                if (nestedViewClickCount > 0)
                  Text(
                      'Click count: $nestedViewClickCount',
                      key: const ValueKey<String>('NestedViewClickCount'),
                  ),
              ],
            ),
          ],
        ],
      ),
    );
  }

  Widget _statusWidget() {
    assert(_lastTestStatus != _LastTestStatus.pending);
    final String message = _lastTestStatus == _LastTestStatus.success ? 'Success' : lastError!;
    return Container(
      color: _lastTestStatus == _LastTestStatus.success ? Colors.green : Colors.red,
      child: Text(
        message,
        key: const ValueKey<String>('Status'),
        style: TextStyle(
          color: _lastTestStatus == _LastTestStatus.error ? Colors.yellow : null,
        ),
      ),
    );
  }

  Future<void> onShowAlertDialogPressed() async {
    if (_lastTestStatus != _LastTestStatus.pending) {
      setState(() {
        _lastTestStatus = _LastTestStatus.pending;
      });
    }
    try {
      await viewChannel!.invokeMethod<void>('showAndHideAlertDialog');
      setState(() {
        _lastTestStatus = _LastTestStatus.success;
      });
    } catch(e) {
      setState(() {
        _lastTestStatus = _LastTestStatus.error;
        lastError = '$e';
      });
    }
  }

  Future<void> onTogglePlatformView() async {
    setState(() {
      showPlatformView = !showPlatformView;
    });
  }

  Future<void> onChildViewPressed() async {
    try {
      await viewChannel!.invokeMethod<void>('addChildViewAndWaitForClick');
      setState(() {
        nestedViewClickCount++;
      });
    } catch(e) {
      setState(() {
        _lastTestStatus = _LastTestStatus.error;
        lastError = '$e';
      });
    }
  }

  Future<void> onTapChildViewPressed() async {
    await Future<void>.delayed(const Duration(seconds: 1));

    // Dispatch a tap event on the child view inside the platform view.
    //
    // Android mutates `MotionEvent` instances, so in this case *do not* dispatch
    // new instances as it won't cover the `MotionEventTracker` class in the embedding
    // which tracks events.
    //
    // See the issue this prevents: https://github.com/flutter/flutter/issues/61169
    await Process.run('input', const <String>['tap', '250', '550']);
  }

  void onPlatformViewCreated(int id) {
    this.id = id;
    setState(() {
      viewChannel = MethodChannel('simple_view/$id');
    });
    driverDataHandler.registerHandler('hierarchy')
      .complete(() async => (await channel.invokeMethod<String>('getViewHierarchy'))!);
  }
}
