// Copyright (c) 2019 The Chromium 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:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:flutter_progress_button/flutter_progress_button.dart';
import 'package:url_launcher/url_launcher.dart';

import 'package:cocoon_service/protos.dart' show Commit;

import 'canvaskit_widget.dart';
import 'status_grid.dart';

/// Displays Git commit information.
///
/// On click, it will open an [OverlayEntry] with [CommitOverlayContents]
/// to show the information provided. Otherwise, it just shows the avatar
/// for the author of this commit. Clicking outside of the [OverlayEntry]
/// will close it.
class CommitBox extends StatefulWidget {
  const CommitBox({Key key, @required this.commit})
      : assert(commit != null),
        super(key: key);

  /// The commit being shown
  final Commit commit;

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

class _CommitBoxState extends State<CommitBox> {
  OverlayEntry _commitOverlay;

  @override
  Widget build(BuildContext context) {
    int authorHash = widget.commit.author.hashCode;
    return SizedBox(
      width: StatusGrid.cellSize,
      height: StatusGrid.cellSize,
      child: GestureDetector(
        onTap: _handleTap,
        // TODO(chillers): Show a Network Image in CanvasKit. https://github.com/flutter/flutter/issues/45955
        // Just show the first letter of the contributor's username.
        child: CanvasKitWidget(
          canvaskit: Container(
            margin: const EdgeInsets.all(1.0),
            decoration: BoxDecoration(
              shape: BoxShape.circle,
              color: Color.fromRGBO(authorHash & 255, authorHash >>= 8 & 255,
                  authorHash >>= 8 & 255, 1),
            ),
            child: Center(
              child: Text(
                widget.commit.author.substring(0, 1).toUpperCase(),
                textAlign: TextAlign.center,
                style: TextStyle(
                  color: Colors.white,
                  fontSize: 24.0,
                  fontWeight: FontWeight.bold,
                ),
              ),
            ),
          ),
          other: CachedNetworkImage(
            imageUrl: widget.commit.authorAvatarUrl,
            placeholder: (_, String url) => Container(color: Colors.grey),
            errorWidget: (_, String url, Object error) =>
                const Icon(Icons.error),
          ),
        ),
      ),
    );
  }

  void _handleTap() {
    _commitOverlay = OverlayEntry(
      builder: (_) => CommitOverlayContents(
          parentContext: context,
          commit: widget.commit,
          closeCallback: _closeOverlay),
    );

    Overlay.of(context).insert(_commitOverlay);
  }

  void _closeOverlay() => _commitOverlay.remove();
}

/// Displays the information from a Git commit.
///
/// This is intended to be inserted in an [OverlayEntry] as it requires
/// [closeCallback] that will remove the widget from the tree.
class CommitOverlayContents extends StatelessWidget {
  const CommitOverlayContents({
    Key key,
    @required this.parentContext,
    @required this.commit,
    @required this.closeCallback,
  })  : assert(parentContext != null),
        assert(commit != null),
        assert(closeCallback != null),
        super(key: key);

  /// The parent context that has the size of the whole screen
  final BuildContext parentContext;

  /// The commit data to display in the overlay
  final Commit commit;

  /// This callback removes the parent overlay from the widget tree.
  ///
  /// On a click that is outside the area of the overlay (the rest of the screen),
  /// this callback is called closing the overlay.
  final void Function() closeCallback;

  @override
  Widget build(BuildContext context) {
    final RenderBox renderBox = parentContext.findRenderObject();
    final Offset offsetLeft = renderBox.localToGlobal(Offset.zero);

    return Stack(
      children: <Widget>[
        // This is the area a user can click (the rest of the screen) to close the overlay.
        GestureDetector(
          onTap: closeCallback,
          child: Container(
            width: MediaQuery.of(parentContext).size.width,
            height: MediaQuery.of(parentContext).size.height,
            // Color must be defined otherwise the container can't be clicked on
            color: Colors.transparent,
          ),
        ),
        Positioned(
          width: 300,
          // Move this overlay to be where the parent is
          top: offsetLeft.dy + (renderBox.size.height / 2),
          left: offsetLeft.dx + (renderBox.size.width / 2),
          child: Card(
            child: Column(
              mainAxisSize: MainAxisSize.max,
              children: <Widget>[
                ListTile(
                  leading: CircleAvatar(
                    radius: 25.0,
                    backgroundImage: CachedNetworkImageProvider(
                      commit.authorAvatarUrl,
                    ),
                    backgroundColor: Colors.transparent,
                  ),
                  // TODO(chillers): Show commit message here instead: https://github.com/flutter/cocoon/issues/435
                  // Shorten the SHA as we only need first 7 digits to be able
                  // to lookup the commit.
                  title: SelectableText(commit.sha.substring(0, 7)),
                  subtitle: SelectableText(commit.author),
                ),
                ButtonBar(
                  children: <Widget>[
                    ProgressButton(
                      defaultWidget: const Text('GitHub'),
                      progressWidget: const CircularProgressIndicator(),
                      width: 100,
                      height: 50,
                      onPressed: _openGithub,
                      animate: false,
                    ),
                  ],
                ),
              ],
            ),
          ),
        ),
      ],
    );
  }

  Future<void> _openGithub() async {
    final String githubUrl =
        'https://github.com/${commit.repository}/commit/${commit.sha}';
    launch(githubUrl);
  }
}
