// Copyright (c) 2020, 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:async';
import 'dart:js_interop';

import 'package:markdown/markdown.dart' as md;
import 'package:web/web.dart';

import 'highlight.dart';

final markdownInput =
    document.querySelector('#markdown') as HTMLTextAreaElement;
final htmlDiv = document.querySelector('#html') as HTMLDivElement;
final versionSpan = document.querySelector('.version') as HTMLSpanElement;

const typing = Duration(milliseconds: 150);
const introText = '''Markdown is the **best**!

* It has lists.
* It has [links](https://dart.dev).
* It has...
  ```dart
  void sourceCode() {}
  ```
* ...and _so much more_...''';

// Flavor support.
final basicRadio = document.querySelector('#basic-radio') as HTMLElement;
final commonmarkRadio =
    document.querySelector('#commonmark-radio') as HTMLElement;
final gfmRadio = document.querySelector('#gfm-radio') as HTMLElement;
md.ExtensionSet? extensionSet;

final extensionSets = {
  'basic-radio': md.ExtensionSet.none,
  'commonmark-radio': md.ExtensionSet.commonMark,
  'gfm-radio': md.ExtensionSet.gitHubWeb,
};

void main() {
  versionSpan.textContent = 'v${md.version}';
  markdownInput.onKeyUp.listen(_renderMarkdown);

  final savedMarkdown = window.localStorage.getItem('markdown');

  if (savedMarkdown != null &&
      savedMarkdown.isNotEmpty &&
      savedMarkdown != introText) {
    markdownInput.value = savedMarkdown;
    markdownInput.focus();
    _renderMarkdown();
  } else {
    _typeItOut(introText, 82);
  }

  // GitHub is the default extension set.
  gfmRadio.attributes.getNamedItem('checked')?.value = '';
  gfmRadio.querySelector('.glyph')!.textContent = 'radio_button_checked';
  extensionSet = extensionSets[gfmRadio.id];
  _renderMarkdown();

  basicRadio.onClick.listen(_switchFlavor);
  commonmarkRadio.onClick.listen(_switchFlavor);
  gfmRadio.onClick.listen(_switchFlavor);
}

void _renderMarkdown([Event? event]) {
  final markdown = markdownInput.value;

  htmlDiv.innerHtml = md.markdownToHtml(markdown, extensionSet: extensionSet);

  for (final block in htmlDiv.querySelectorAll('pre code').items) {
    try {
      highlightElement(block);
    } catch (e) {
      console.error('Error highlighting markdown:'.toJS);
      console.error(e.toString().toJS);
    }
  }

  if (event != null) {
    // Not simulated typing. Store it.
    window.localStorage.setItem('markdown', markdown);
  }
}

void _typeItOut(String msg, int pos) {
  late Timer timer;
  markdownInput.onKeyUp.listen((_) {
    timer.cancel();
  });
  void addCharacter() {
    if (pos > msg.length) {
      return;
    }
    markdownInput.value = msg.substring(0, pos);
    markdownInput.focus();
    _renderMarkdown();
    pos++;
    timer = Timer(typing, addCharacter);
  }

  timer = Timer(typing, addCharacter);
}

void _switchFlavor(Event e) {
  final target = e.currentTarget as HTMLElement;
  if (target.attributes.getNamedItem('checked') == null) {
    if (basicRadio != target) {
      basicRadio.attributes.safeRemove('checked');
      basicRadio.querySelector('.glyph')!.textContent =
          'radio_button_unchecked';
    }
    if (commonmarkRadio != target) {
      commonmarkRadio.attributes.safeRemove('checked');
      commonmarkRadio.querySelector('.glyph')!.textContent =
          'radio_button_unchecked';
    }
    if (gfmRadio != target) {
      gfmRadio.attributes.safeRemove('checked');
      gfmRadio.querySelector('.glyph')!.textContent = 'radio_button_unchecked';
    }

    target.attributes.getNamedItem('checked')?.value = '';
    target.querySelector('.glyph')!.textContent = 'radio_button_checked';
    extensionSet = extensionSets[target.id];
    _renderMarkdown();
  }
}

extension on NodeList {
  List<Node> get items => [for (var i = 0; i < length; i++) item(i)!];
}

extension on NamedNodeMap {
  void safeRemove(String qualifiedName) {
    if (getNamedItem(qualifiedName) != null) removeNamedItem(qualifiedName);
  }
}

extension on HTMLDivElement {
  // The default implementation allows `JSAny` to support trusted types. We only
  // use `String`s, so prefer this to avoid manual conversions.
  @JS('innerHTML')
  external set innerHtml(String value);
}
