// 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 '../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, {required this.cellSize});

  final double cellSize;

  /// 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 double cellSize,
    required Offset target,
  }) {
    const double margin = 10.0;
    final double verticalOffset = 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,
      cellSize: cellSize,
      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 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.of(context),
          height: TaskBox.of(context),
          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, cellSize: TaskBox.of(context)),
            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 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 || QualifiedTask.fromTask(task).isDartInternal)
                            LuciTaskAttemptSummary(task: task),
                        ],
                      ),
                    ),
                  ],
                ),
              ),
              Row(
                mainAxisAlignment: MainAxisAlignment.end,
                children: <Widget>[
                  if (qualifiedTask.isLuci)
                    Padding(
                      padding: const EdgeInsets.only(left: 8.0),
                      // The RERUN button is only enabled if the user is authenticated.
                      child: AnimatedBuilder(
                        animation: buildState,
                        builder: (context, child) {
                          final bool isAuthenticated = buildState.authService.isAuthenticated;
                          return ProgressButton(
                            onPressed: isAuthenticated
                                ? () {
                                    return _rerunTask(task);
                                  }
                                : null,
                            child: child,
                          );
                        },
                        child: const Text('RERUN'),
                      ),
                    ),
                ],
              ),
            ],
          ),
        ),
      ),
    );
  }

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