// Copyright 2019 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 'dart:math' as math;

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

import '../logic/qualified_task.dart';
import '../model/commit.pb.dart';
import '../model/task.pb.dart';
import '../state/build.dart';
import 'luci_task_attempt_summary.dart';
import 'now.dart';
import 'progress_button.dart';
import 'task_box.dart';

class TaskOverlayEntryPositionDelegate extends SingleChildLayoutDelegate {
  TaskOverlayEntryPositionDelegate(this.target);

  /// The offset of the target the tooltip is positioned near in the global
  /// coordinate system.
  final Offset target;

  static Offset positionDependentBox({
    required Size size,
    required Size childSize,
    required Offset target,
  }) {
    const double margin = 10.0;
    const double verticalOffset = TaskBox.cellSize * .9;

    // VERTICAL DIRECTION
    final bool fitsBelow = target.dy + verticalOffset + childSize.height <= size.height - margin;
    double y;
    if (fitsBelow) {
      y = math.min(target.dy + verticalOffset, size.height - margin);
    } else {
      y = math.max(target.dy - childSize.height, margin);
    }
    // HORIZONTAL DIRECTION
    double x;
    // The whole size isn't big enough, just center it.
    if (size.width - margin * 2.0 < childSize.width) {
      x = (size.width - childSize.width) / 2.0;
    } else {
      final double normalizedTargetX = (target.dx).clamp(margin, size.width - margin);
      final double edge = normalizedTargetX + childSize.width;
      // Position the box as close to the left edge of the full size
      // without going over the margin.
      if (edge > size.width) {
        x = size.width - margin - childSize.width;
      } else {
        x = normalizedTargetX;
      }
    }
    return Offset(x, y);
  }

  @override
  Offset getPositionForChild(Size size, Size childSize) {
    return positionDependentBox(
      size: size,
      childSize: childSize,
      target: target,
    );
  }

  @override
  bool shouldRelayout(TaskOverlayEntryPositionDelegate oldDelegate) {
    return oldDelegate.target != target;
  }
}

/// Displays the information from [Task] and allows interacting with a [Task].
///
/// This is intended to be inserted in an [OverlayEntry] as it requires
/// [closeCallback] that will remove the widget from the tree.
class TaskOverlayEntry extends StatelessWidget {
  const TaskOverlayEntry({
    super.key,
    required this.position,
    required this.task,
    required this.showSnackBarCallback,
    required this.closeCallback,
    required this.buildState,
    required this.commit,
  });

  /// The global position where to show the task overlay.
  final Offset position;

  /// The [Task] to display in the overlay.
  final Task task;

  final ShowSnackBarCallback showSnackBarCallback;

  /// 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 VoidCallback closeCallback;

  /// A reference to the [BuildState] for performing operations on this [Task].
  final BuildState buildState;

  /// [Commit] for cirrus tasks to show log.
  final Commit commit;

  @override
  Widget build(BuildContext context) {
    // If this is ever positioned not at the top-left of the viewport, then
    // we should make sure to convert the position to the Overlay's coordinate
    // space otherwise it'll be misaligned.
    return Stack(
      children: <Widget>[
        // This is a focus container to emphasize the cell that this
        // [Overlay] is currently showing information from.
        Positioned(
          top: position.dy,
          left: position.dx,
          width: TaskBox.cellSize,
          height: TaskBox.cellSize,
          child: Container(
            decoration: BoxDecoration(
              border: Border.all(color: Colors.black, width: 4.0),
              color: Colors.white70,
            ),
          ),
        ),
        // This is the area a user can click (the rest of the screen) to close the overlay.
        GestureDetector(
          onTap: closeCallback,
          behavior: HitTestBehavior.opaque,
          child: const SizedBox.expand(),
        ),
        Positioned(
          // Move this overlay to be where the parent is
          child: CustomSingleChildLayout(
            delegate: TaskOverlayEntryPositionDelegate(position),
            child: TaskOverlayContents(
              showSnackBarCallback: showSnackBarCallback,
              buildState: buildState,
              task: task,
              commit: commit,
              closeCallback: closeCallback,
            ),
          ),
        ),
      ],
    );
  }
}

/// Displays the information from [Task] and allows interacting with a [Task].
///
/// This is intended to be inserted in [TaskOverlayEntry].
///
/// Offers the functionality of opening the log for this [Task] and rerunning
/// this [Task] through the build system.
class TaskOverlayContents extends StatelessWidget {
  const TaskOverlayContents({
    super.key,
    required this.showSnackBarCallback,
    required this.buildState,
    required this.task,
    required this.closeCallback,
    this.commit,
  });

  final ShowSnackBarCallback showSnackBarCallback;

  /// A reference to the [BuildState] for performing operations on this [Task].
  final BuildState buildState;

  /// The [Task] to display in the overlay
  final Task task;

  /// [Commit] for cirrus tasks to show log.
  final Commit? commit;

  /// This callback removes the parent overlay from the widget tree.
  ///
  /// This is used in this scope to close this overlay on redirection to view
  /// the agent for this task in the agent dashboard.
  final void Function() closeCallback;

  @visibleForTesting
  static const String rerunErrorMessage = 'Failed to rerun task.';
  @visibleForTesting
  static const String rerunSuccessMessage = 'Devicelab is rerunning the task. This can take a minute to propagate.';
  @visibleForTesting
  static const Duration rerunSnackBarDuration = Duration(seconds: 15);

  /// A lookup table to define the [Icon] for this task, based on
  /// the values returned by [TaskBox.effectiveTaskStatus].
  static const Map<String, Icon> statusIcon = <String, Icon>{
    TaskBox.statusFailed: Icon(Icons.clear, color: Colors.red, size: 32),
    TaskBox.statusNew: Icon(Icons.new_releases, color: Colors.blue, size: 32),
    TaskBox.statusInProgress: Icon(Icons.autorenew, color: Colors.blue, size: 32),
    TaskBox.statusSucceeded: Icon(Icons.check_circle, color: Colors.green, size: 32),
  };

  @override
  Widget build(BuildContext context) {
    final QualifiedTask qualifiedTask = QualifiedTask.fromTask(task);

    final DateTime? now = Now.of(context);
    final DateTime createTime = DateTime.fromMillisecondsSinceEpoch(task.createTimestamp.toInt());
    final DateTime startTime = DateTime.fromMillisecondsSinceEpoch(task.startTimestamp.toInt());
    final DateTime endTime = DateTime.fromMillisecondsSinceEpoch(task.endTimestamp.toInt());

    final Duration queueDuration =
        task.startTimestamp == 0 ? now!.difference(createTime) : startTime.difference(createTime);
    final Duration runDuration = task.endTimestamp == 0 ? now!.difference(startTime) : endTime.difference(startTime);

    /// There are 2 possible states for queue time:
    ///   1. Task is waiting to be scheduled (in queue)
    ///   2. Task has been scheduled (out of queue)
    final String queueText = (task.status != TaskBox.statusNew)
        ? 'Queue time: ${queueDuration.inMinutes} minutes'
        : 'Queueing for ${queueDuration.inMinutes} minutes';

    /// There are 3 possible states for the runtime:
    ///   1. Task has not run yet (new)
    ///   2. Task is running (in progress)
    ///   3. Task ran (other status)
    final String runText = (task.status == TaskBox.statusInProgress)
        ? 'Running for ${runDuration.inMinutes} minutes'
        : (task.status != TaskBox.statusNew)
            ? 'Run time: ${runDuration.inMinutes} minutes'
            : '';

    final String summaryText = <String>[
      'Attempts: ${task.attempts}',
      if (runText.isNotEmpty) runText,
      queueText,
      if (task.isFlaky) 'Flaky: ${task.isFlaky}',
    ].join('\n');

    return Card(
      child: Padding(
        padding: const EdgeInsets.symmetric(horizontal: 8.0, vertical: 4.0),
        child: IntrinsicWidth(
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.stretch,
            mainAxisSize: MainAxisSize.min,
            children: <Widget>[
              Padding(
                padding: const EdgeInsets.symmetric(vertical: 8.0),
                child: Row(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: <Widget>[
                    Tooltip(
                      message: task.status,
                      child: Padding(
                        padding: const EdgeInsets.only(left: 8.0, top: 10.0, right: 12.0),
                        child: statusIcon[task.status],
                      ),
                    ),
                    Expanded(
                      child: ListBody(
                        children: <Widget>[
                          SelectableText(
                            task.name,
                            style: Theme.of(context).textTheme.bodyLarge,
                          ),
                          Text(
                            summaryText,
                            style: Theme.of(context).textTheme.bodyMedium,
                          ),
                          if (QualifiedTask.fromTask(task).isLuci) LuciTaskAttemptSummary(task: task),
                        ],
                      ),
                    ),
                  ],
                ),
              ),
              Row(
                mainAxisAlignment: MainAxisAlignment.end,
                children: <Widget>[
                  Padding(
                    padding: const EdgeInsets.only(left: 8.0),
                    child: ProgressButton(
                      child: const Text('VIEW LOGS'),
                      onPressed: () => launchUrl(Uri.parse(logUrl(task, commit: commit))),
                    ),
                  ),
                  if (qualifiedTask.isLuci)
                    Padding(
                      padding: const EdgeInsets.only(left: 8.0),
                      child: ProgressButton(
                        onPressed: _rerunTask,
                        child: const Text('RERUN'),
                      ),
                    ),
                ],
              ),
            ],
          ),
        ),
      ),
    );
  }

  Future<void> _rerunTask() async {
    final bool rerunResponse = await buildState.rerunTask(task);
    if (rerunResponse) {
      showSnackBarCallback(
        const SnackBar(
          content: Text(rerunSuccessMessage),
          duration: rerunSnackBarDuration,
        ),
      );
    }
  }
}
