// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
// for details. 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:html' show window;

import 'package:angular/angular.dart';
import 'package:angular_components/angular_components.dart';
import 'package:angular_components/material_button/material_button.dart';
import 'package:angular_components/material_input/material_input.dart';
import 'package:angular_components/material_input/material_input_multiline.dart';
import 'package:angular_components/simple_html/simple_html.dart';
import 'package:angular_forms/angular_forms.dart' show formDirectives;
import 'package:angular_router/angular_router.dart';

import '../formatting.dart';
import '../model/comment.dart';
import '../model/commit.dart';
import '../services/try_data_service.dart';
import 'results_panel.dart';
import 'results_selector_panel.dart';

@Component(
    selector: 'try-results',
    directives: [
      coreDirectives,
      formDirectives,
      materialInputDirectives,
      MaterialButtonComponent,
      MaterialMultilineInputComponent,
      ResultsPanel,
      ResultsSelectorPanel,
      SimpleHtmlComponent,
    ],
    providers: [
      ClassProvider(TryDataService),
      overlayBindings,
    ],
    templateUrl: 'try_results_component.html',
    exports: [formattedDate, formattedEmail],
    styles: ['div {padding: 8px;}'])
class TryResultsComponent implements OnActivate {
  TryDataService _tryDataService;
  ApplicationRef _applicationRef;

  int review;
  int patchset;
  ReviewInfo reviewInfo;
  ChangeGroup changeGroup =
      ChangeGroup(null, {}, [], [], LoadedResultsStatus());
  int cachedReview;
  int cachedPatchset;
  List<Change> changes;
  List<Comment> comments;
  Map<int, Map<String, TryBuild>> builds;
  Map<String, String> builders;
  final IntRange emptyRange = IntRange(1, 0);
  bool updating = false;
  bool updatePending = false;
  bool _approving = false;
  final selected = Set<Change>();
  String commentText;

  TryResultsComponent(this._tryDataService, this._applicationRef);

  bool get approveEnabled =>
      changeGroup.changes.flat.any((change) => change.failed);

  bool get approving => _approving;

  set approving(bool approve) {
    if (approve) {
      _tryDataService.logIn().then((_) {
        _approving = _tryDataService.isLoggedIn;
      });
    } else {
      _approving = false;
    }
  }

  Future<void> approve(bool approval) async {
    for (Change result in selected) {
      result.approved = approval ?? result.approved;
    }
    final comment = await _tryDataService.saveApproval(
        approval,
        commentText,
        changeGroup.comments.isEmpty
            ? null
            : changeGroup.comments.last.baseComment ??
                changeGroup.comments.last.id,
        [for (Change result in selected) result.id],
        reviewInfo.review);
    comments
      ..add(comment)
      ..sort();
    _approving = false;
  }

  void tryUpdate() async {
    if (updating) {
      updatePending = true;
    } else {
      updating = true;
      try {
        await update();
      } finally {
        updating = false;
        if (updatePending) {
          updatePending = false;
          tryUpdate(); // Not awaited, tail call.
        }
        // TODO: better change management.
        _applicationRef.tick();
      }
    }
  }

  Future<void> update() async {
    if (review == null) return;
    if (reviewInfo == null || review != reviewInfo.review) {
      reviewInfo = await _tryDataService.fetchReviewInfo(review);
    }
    if (review != cachedReview || patchset != cachedPatchset) {
      changes = await _tryDataService.changes(reviewInfo, patchset);
      comments = await _tryDataService.comments(reviewInfo.review);
      builds = {
        for (final patchset in reviewInfo.patchsets) patchset.number: {}
      };
      for (final build in reviewInfo.builds) {
        builds[build.patchset][build.builder] = build;
      }
      builders = await _tryDataService.builders();
      comments..sort();
      cachedReview = review;
      cachedPatchset = patchset;
      changeGroup =
          ChangeGroup(null, {}, comments, changes, LoadedResultsStatus());
    }
  }

  @override
  void onActivate(_, RouterState current) {
    final changeParam = current.parameters['cl'];
    review = changeParam == null ? null : int.parse(changeParam);
    final patchParam = current.parameters['patch'];
    patchset = patchParam == null ? null : int.parse(patchParam);
    tryUpdate();
  }

  void openNewGithubIssue() {
    window.open(newIssueURL(), '_blank');
  }

  String newIssueURL() => githubNewIssueURL(changeGroup.changes,
      reviewInfo.title, "https://dart-review.googlesource.com/c/sdk/+/$review");
}
