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

// TODO(mattkae): remove invalid_use_of_internal_member ignore comment when this API is stable.
// See: https://github.com/flutter/flutter/issues/177586
// TODO(mattkae): refactor this example for better widget position tracking
// This positioning logic is simpler than you might want in production. See https://github.com/flutter/flutter/issues/178829.
// ignore_for_file: invalid_use_of_internal_member
// ignore_for_file: implementation_imports
import 'package:flutter/material.dart';
import 'package:flutter/src/widgets/_window.dart';
import 'package:flutter/src/widgets/_window_positioner.dart';

void main() {
  try {
    runWidget(
      RegularWindow(
        controller: RegularWindowController(
          preferredSize: const Size(800, 600),
          preferredConstraints: const BoxConstraints(
            minWidth: 640,
            minHeight: 480,
          ),
          title: 'Example Window',
        ),
        child: const MaterialApp(home: MyApp()),
      ),
    );
  } on UnsupportedError catch (e) {
    // TODO(mattkae): Remove this catch block when Windows tooltips are supported in tests.
    // For now, we need to catch the error so that the API smoke tests pass.
    runApp(
      MaterialApp(
        home: Scaffold(body: Center(child: Text(e.message ?? 'Unsupported'))),
      ),
    );
  }
}

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  @override
  State<MyApp> createState() {
    return _MyAppState();
  }
}

class _CallbackPopupDelegate extends PopupWindowControllerDelegate {
  _CallbackPopupDelegate({required this.onDestroyCallback});

  final VoidCallback onDestroyCallback;

  @override
  void onWindowDestroyed() {
    onDestroyCallback();
  }
}

class _MyAppState extends State<MyApp> {
  final GlobalKey _key = GlobalKey();
  PopupWindowController? _popupController;

  @override
  Widget build(BuildContext context) {
    final List<Widget> children = <Widget>[
      ElevatedButton(
        key: _key,
        onPressed: () {
          setState(() {
            _popupController ??= PopupWindowController(
              parent: WindowScope.of(context),
              anchorRect: _getAnchorRect()!,
              positioner: const WindowPositioner(
                parentAnchor: .right,
                childAnchor: .left,
              ),
              delegate: _CallbackPopupDelegate(
                onDestroyCallback: () {
                  setState(() {
                    _popupController = null;
                  });
                },
              ),
            );
          });
        },
        child: const Text('Show Popup'),
      ),
    ];

    if (_popupController != null) {
      children.add(
        PopupWindow(
          controller: _popupController!,
          child: Container(
            padding: const .all(8),
            color: Colors.black,
            child: Column(
              mainAxisSize: .min,
              children: <Widget>[
                const Text(
                  'This is a popup',
                  style: TextStyle(color: Colors.white),
                ),
                const SizedBox(height: 8),
                ElevatedButton(
                  onPressed: () {
                    setState(() {
                      _popupController?.destroy();
                    });
                  },
                  child: const Text('Close'),
                ),
              ],
            ),
          ),
        ),
      );
    }

    return Scaffold(
      body: Center(
        child: Row(mainAxisSize: .min, children: children),
      ),
    );
  }

  Rect? _getAnchorRect() {
    final RenderBox? renderBox =
        _key.currentContext?.findRenderObject() as RenderBox?;
    if (renderBox != null) {
      final Offset position = renderBox.localToGlobal(Offset.zero);
      final Size size = renderBox.size;
      return position & size; // creates a Rect
    }

    return null;
  }
}
