var remark = require("remark");
var tocGenerator = require("mdast-util-toc");
var replaceSection = require("mdast-util-heading-range");

var unist = require("../unistHelpers");

const contentsHeading = "Contents";
const minHeadingsForToc = 8;
const maxTocHeadingDepth = 3;

module.exports = {
    "initPhase": initPhase,
    "readPhase": readPhase,
    "aggPhase": aggPhase,
    "updatePhase": updatePhase
}

function initPhase(aggData) {}
function readPhase(tree, pathname, aggData) {}
function aggPhase(aggData) {}


// Find an existing Contents section or add a new empty one if needed.
// Returns true if section is present/needed, false if not needed.
function establishContentsSection(mdTree) {
    var firstL2HeadingPos = -1;
    var numTocHeadings = 0;
    var foundContentsHeading = false;

    for (var i = 0; i < mdTree.children.length; i++) {
        var child = mdTree.children[i];
        
        // Look through all headings.
        if (child.type === "heading") {

            if ((child.depth > 1) && (child.depth <= maxTocHeadingDepth)) {
                numTocHeadings++;
            }

            if (child.depth === 2) {
                // Note where the first L2 heading is.
                if (firstL2HeadingPos === -1) {
                    firstL2HeadingPos = i;
                }

                // If it is also a Contents heading then we're done. We don't include the
                // Contents heading itself within the ToC, so decrement the count for that.
                if ((child.children[0].value === contentsHeading) && !foundContentsHeading) {
                    foundContentsHeading = true;
                    numTocHeadings--;
                }
            }
        }
    }

    // If we get here then a level 2 Contents heading was not found.
    // If there are enough headings for a ToC to be necessary then
    // add one in the right place.
    if (!foundContentsHeading) {
        var newContsHeading = unist.makeHeading(unist.makeText(contentsHeading), 2);

        // If we found another L2 heading then add the Contents in just before it.
        if (firstL2HeadingPos != -1) {
            mdTree.children.splice(firstL2HeadingPos, 0, newContsHeading);
        } else {
            // Otherwise, the unlikely situation where a ToC is required but there
            // are no L2 headings! Add it as the second element in the document.
            mdTree.children.splice(1, 0, newContsHeading);
        }
    }

    return numTocHeadings;
}

function updatePhase(tree, pathname, aggData) {
// If we need a contents section then add one or update the existing one.
    var numTocHeadings = establishContentsSection(tree);

    if (numTocHeadings >= minHeadingsForToc) {
        var newToc = tocGenerator(tree, {heading: contentsHeading, maxDepth: 3});

        replaceSection(tree, contentsHeading, function(before, oldSection, after) {
            return [before, newToc.map, after];
        });
    } else {
        // Otherwise, we don't need one, so remove any existing one.
        replaceSection(tree, contentsHeading, function(before, oldSection, after) {
            return [after];
        });
    }

    return true;
}