!7

concept AIList {
  S name;
  S text;
  long modified;
}

p {
  dbIndexing(AIList, 'name);
}

html {
  if (!webAuthed(params)) ret redirectToWebAuth();
  
  new Matches m;
  
  // API
  if (startsWith(uri, "/list-text/", m)) {
    S name = urldecode(m.get(0));
    AIList l = conceptWhere(AIList, +name);
    ret serveText(jsonEncode(l == null ? litmap("Error", ll("List not found", name)) : litmap("Name" := l.name, "Text" :=l.text)));
  }
  
  if (eq(uri, "/list-names"))
    ret serveText(jsonEncode(sortedIC(collect(list(AIList), 'name))));

  // Show list
  if (startsWith(uri, "/list/", m)) {
    AIList l = conceptWhere(AIList, name := urldecode(m.get(0)));
    if (l == null) ret "List not found";
    
    // Update text
    S text = params.get("human");
    if (text != null && neq(text, l.text)) {
      logStructure("versions.log", litmap(id := l.id, +text, date := now()));
      cset(l, +text, modified := now());
      ret hrefresh(rawLink(uri));
    }
    
    ret nav() + htitle_h2(htmlencode(l.name))
      + hpostform(h3("Contents (human-edited)")
      + p(hsubmit("Save"))
      + htextarea(l.text, name := 'human, cols := 80, rows := 30));
  }
  
  // New list
  S newList = params.get('newList);
  if (nempty(newList)) {
    AIList l = uniq(AIList, name := newList);
    ret hrefresh(rawLink("/list/" + urlencode(l.name)));
  }
  
  // Overview
  bool alphabetical = eq(uri, "/alphabetical");
  
  L<AIList> list = alphabetical
    ? sortedByFieldIC('name, list(AIList))
    : sortedByFieldDesc('modified, list(AIList));
  
  ret hmobilefix () + htitle_h3("mech.tinybrain.de")
    + hBoolSelector("/", "By date", "/alphabetical", "Alphabetical")
    + ul(map(list, func(AIList l) -> S {
      int n = countLines(l.text);
      ret ahref(rawLink("/list/" + urlencode(l.name)),
        htmlencode(l.name)) + (n == 0 ? "" : " (" + n2(n, "line") + ")");
    }))
    + h3("New list")
    + hpostform("Name: " + htextinput('newList) + " " + hsubmit("Create list"));
}

sS nav() {
  ret hmobilefix() + p(ahref(rawLink(), "&lt;&lt; back"));
}