import { sanitize } from "./scripts.js";
import { storeData, clearData, retrieveData } from "./storage.js";

function parseFormOnSubmit(returnJSON = false, parseOnly = false) {
    //event.preventDefault;
  
    let dataArray = [];
  
    if (parseOnly) {
      let lT = activeState.loadedTemplate;
      dataArray = retrieveData("userInputForce", lT);

      if (dataArray == null) {
        let wrapper = document.createElement("div");
        wrapper.innerHTML = mainFormPlaceholder("Error: file empty");
        let div = wrapper.firstChild;
        return div;
      }

      if (dataArray.length <= 0) {
        let wrapper = document.createElement("div");
        wrapper.innerHTML = mainFormPlaceholder("File empty");
        let div = wrapper.firstChild;
        return div;
      }

    } else {
      let x = document.getElementById("mainFormObj");
      
      if (x != null) {
        for (let i = 0; i < x.length; i++) {
          dataArray.push({
            value: x.elements[i].value,
            name: x.elements[i].name,
          });
        }
      }

      //set filename to active state according to userFileName field from loadTemplate
      let userFileNameField = document.getElementById("userFileName");
      let userFileName = sanitize(userFileNameField.value);
      let userFileNamePH = userFileNameField.getAttribute("placeholder");
      if (userFileName.length != 0) {
        activeState.fileName = userFileName;
      } else if (userFileNamePH != null) {
        activeState.fileName = userFileNamePH;
      } 
    }

  
    //get original objects from sessionstorage gen from loadTemplate
    let objects = activeState.templateObjects;

    //get the complete unparsed template string from sessionstorage from loadTemplate
    let fullString = activeState.fullString;
  
    //define output buffer
    let b = "";
  
    if (objects == null) {
      return;
    }

    //iterate through templateObjects and look for according formdata
    for (let obj of objects) {
      //compaire each obj with elements from mainFormObj
      for (let data of dataArray) {

        //convert conList Master name to default name as set flag for appending connected list fields cl-name
        let conListFlag = false;
        //if obj is the connected list main selector
        if (data.name.split("-")[0] == "clM") {
          //if connected list main matches current object
          if (data.name.substring(4) === obj.word.replace(/ /g, "_") ) {
            //set flag for next iteration of loop
            conListFlag = true;
            data.name = data.name.substring(4);
            
            //selection is not added to buffer
            if (data.value == "!none") {
              obj.result = "";
              continue;
            }
            if (data.value == "!selected") {
              data.value = obj[0];
              obj.result = "";
            }
          }
        }

        //if field matches current object
        if (obj.word.replace(/ /g, "_") == data.name) {
          let value = parseDataForResult(obj, data.value);
          if (value == "!none") value = "";
          obj.result = value;

        }

        //handle conlist elements for parsing each element
        if (conListFlag && obj.type == "conList") {
          let value = parseConListForResult(obj, data, dataArray);
          if (value == "!none") value = "";
          obj.result = value;
          continue;
        }
      }
    }

    b = fullString.substring(0, objects[0].spos);
    for (let i = 0; i < objects.length; i++) {
      let j = i + 1;
      if (objects[j] === undefined) {
        b +=
          objects[i].result +
          fullString.substring(objects[i].epos, fullString.length);
      } else {
        b +=
          objects[i].result +
          fullString.substring(objects[i].epos, objects[j].spos);
      }
    }
  
    let bHtml = b.replace(/(?:\r\n|\r|\n)/g, "<br>");
    bHtml = bHtml.replace(/!l /g, " •   ");
    bHtml = bHtml.replace(/!ls /g, "     ○   ");
    bHtml = bHtml.replace(/ /g, "&nbsp;");
  
    let divContent = document.createElement("div");
    divContent.style.fontFamily = activeState.settings.font + ", Helvetica, sans-serif";
    divContent.style.fontSize = activeState.settings.fontSize;
    divContent.innerHTML = bHtml;

    let div = document.createElement("div");
    div.classList.add("w3-code", "notranslate", "w3-border-white");
    div.id = "fileDisplay";
    div.appendChild(divContent);
  
    if (parseOnly) {
      return div;
    }
  
    storeData("userInput", dataArray);
    clearData("userInput");
  
    if (returnJSON) {
      return dataArray;
    } else {
      copyToClipBoard(bHtml);
    }
  }

  function parseDataForResult(obj, value) {
    //handle placeholders like title, link, italic
    if (obj.hasOwnProperty("placeholder") && value !== "") {
      //console.log(obj.placeholder);
      //check for markups
      if (activeState.markups.includes(obj.placeholder)) {
        value = parseMarkupmarkups(value, obj.placeholder);
      } else {
        value = obj.placeholder + "\n" + value;
      }
    }

    //Plugin TextBlock Insertion according to file _textblocks.txt
    value = parseTextBlocks(value);


    //handle placeholders like !l or !n and set it to final interpreted string for object
    value = parseTextMarkups(value);

    //parse global linebreak after marked text was already fixed
    value = parseGlobalLineBreak(value);

    return value;
  }

  function parseConListForResult(obj, data, dataArray) {
    //check for button if only one item exists and search conlist item
    if (obj.listCount == 0) {
      for (let d of dataArray) {
        if (d.name.split(":!")[1] !== undefined) d.placeholder = "!"+d.name.split(":!")[1];
        d.name = d.name.split(":!")[0];
        if ("cl-"+obj[0].replace(/ /g, "_") == d.name && d.value != "") {
          //console.log(d, obj[0], data);
          if (data.value.replace(/ /g, "_")  == d.name.substring(3)) {
            if (d.hasOwnProperty("placeholder")) d.value = d.placeholder + "\n" + d.value;
            let value = parseDataForResult(obj, d.value);
            return obj.result + "\n" + value;
          }
        }
      }             
    } else {
      //loop through dataArray and look for coresponding conlist items
      for (let i = 0; i <= obj.listCount; i++) {
        for (let d of dataArray) {
          if (d.name.split(":!")[1] !== undefined) d.placeholder = "!"+d.name.split(":!")[1];
          d.name = d.name.split(":!")[0];
          if ("cl-"+obj[i].replace(/ /g, "_") == d.name && d.value != "") {
            if (data.value.replace(/ /g, "_")  == d.name.substring(3)) {
              if (d.hasOwnProperty("placeholder")) d.value = d.placeholder + "\n" + d.value;
              let value = parseDataForResult(obj, d.value);
              return obj.result + "\n" + value;
            }
          }
        }
      }
    }
    return ""
  }

  export function parseTextMarkups(data) {
    let dataArray = data.split("\n");
    let listFlag = false;
    let listSubFlag = false;
    let boldFlag = false;
    let listNumberFlag = false;
    let listNumberFlagNum = 1;
    for (let i = 0; i < dataArray.length; i++) {
      if (dataArray[i] == "") continue;
      switch (dataArray[i]) {
        case "!l":
          listFlag = true;
          dataArray.splice(i, 1);
          i = i - 1;
          break;
        case "!ls":
          listSubFlag = true;
          dataArray.splice(i, 1);
          i = i - 1;
          break;
        case "!n":
          listNumberFlag = true;
          dataArray.splice(i, 1);
          i = i - 1;
          break;
        case "!b":
          boldFlag = true;
          dataArray.splice(i, 1);
          i = i - 1;
          break;
        case "!e":
          listFlag = false;
          listNumberFlag = false;
          dataArray.splice(i, 1);
          i = i - 1;
          break;
        case "!es":
          listSubFlag = false;
          dataArray.splice(i, 1);
          i = i - 1;
          break;
        default:

          if (boldFlag) {
            dataArray[i] = "<b>" + dataArray[i] + "</b>";
            boldFlag = false;
            continue;
          }

          //check if list indicator has been set and adjust userInput accordingly
          let listIndicator = "";

          if (listNumberFlag) {
            listIndicator = "  " + listNumberFlagNum + ".  ";
            listNumberFlagNum++;
          }

          if (listSubFlag && listIndicator == "") listIndicator = "     ○   ";
          
          if (listFlag && listIndicator == "") listIndicator = " •   ";
          
          //handle global linebreak and fit according to indicator according to list indicator

          if (listIndicator != "") dataArray[i] = parseLineBreak(listIndicator + dataArray[i], listIndicator.length);
          
      }
    }
    return dataArray.join("\n");
  }
  
  function parseMarkupmarkups(value, markup) {
    switch (markup) {
      case "title":
        return "<b>" + value + "</b>";
        break;
      case "italic":
        return "<i>" + value + "</i>";
        break;
    }
  }
  
  function parseTextBlocks(data) {
    let textBlocks = loadTextBlocks();
    let textBlockIds = Object.keys(textBlocks);
    for (let i = 0; i < textBlockIds.length; i++) {
      let id = textBlockIds[i];
      if (data.indexOf("!" + id) !== -1) {
        //console.log("found: "+id);
        let sPos = data.indexOf("!" + id);
        let ePos = sPos + id.length + 1;
        data =
          data.substring(0, sPos) +
          textBlocks[id] +
          data.substring(ePos, data.length);
      }
    }
    return data;
  }

  function parseGlobalLineBreak(data) {
    //parse each line of input with parseLineBreak return condensed string with newlines
    let parsedData = '';
    for (let line of data.split('\n')) {
      let parsedLine = parseLineBreak(line, 0, activeState.settings.lineBreak);
      if (parsedData != '') {
        parsedData = parsedData + '\n' + parsedLine;
      } else {
        parsedData = parsedLine;
      }
    }
    return parsedData
  }

  function parseLineBreak(line, intendation = 0, lineBreak = activeState.settings.lineBreak - 5) {
    //add 5 chars buffer to fix list intendation issue
    //each input field gets parsed line by line twice once for list inputs and a second time for each input
    let lines;

    if (line.length > lineBreak) {
      //create linebreak in between second to last word
      let correctedLineBreak;
      let newLineStart;
      let cLBt = lineBreak-(intendation*2)
      //find last space before linebreak
      correctedLineBreak = line.substring(0, cLBt).lastIndexOf(" ");
      //and fix the next lines start
      newLineStart = correctedLineBreak+1;
      //add to parsed output
      lines = line.substring(0, correctedLineBreak);
      //delete first parsed output from inputstring
      line = line.substring(newLineStart);

      let intendationSpaces = '';
      //check if an intendation is given if so convert it to correct spaces
      if (intendation != 0) intendationSpaces = ' '.repeat(intendation);

      //start loop to parse rest of the string
      while(line.length > lineBreak) {
        let cLBt = lineBreak-(intendation*2)
        correctedLineBreak = line.substring(0, cLBt).lastIndexOf(" ");
        newLineStart = correctedLineBreak+1;
        //add to output with intendation if given
        lines += "\n" + intendationSpaces + line.substring(0, correctedLineBreak);
        //delete from input 
        line = line.substring(newLineStart);
      }
      //process rest of the string with correct intendation
      lines += "\n" + intendationSpaces + line;
    } else {
      //if string is within lineBreak just forward input to output
      lines = line;
    }
    return lines;
  }


function loadTextBlocks() {
    let textBlocks = document.getElementById("textBlocks").innerText;
    let textBlocksObject = {};
    if (textBlocks.indexOf("\r\n") !== -1) {
      var wordArrayByLine = textBlocks.split("\r\n");
    } else {
      var wordArrayByLine = textBlocks.split("\n");
    }
  
    for (let i = 0; i < wordArrayByLine.length; i++) {
      let textBlockId = wordArrayByLine[i].split(":")[0];
      let textBlockText = wordArrayByLine[i].substring(
        textBlockId.length + 2,
        wordArrayByLine[i].length
      );
      if (textBlockId.length < 1) {
        continue;
      }
      textBlocksObject[textBlockId.replace(/\s/g, "")] = textBlockText;
    }
    return textBlocksObject;
  }

  function copyToClipBoard(html) {
    // Create an iframe (isolated container) for the HTML
    var container = document.createElement("div");
    container.innerHTML = html;
  
    // Hide element
    container.style.position = "fixed";
    container.style.pointerEvents = "none";
    container.style.opacity = 0;
  
    // Detect all style sheets of the page
    var activeSheets = Array.prototype.slice
      .call(document.styleSheets)
      .filter(function (sheet) {
        return !sheet.disabled;
      });
  
    // Mount the iframe to the DOM to make `contentWindow` available
    document.body.appendChild(container);
  
    // Copy to clipboard
    window.getSelection().removeAllRanges();
  
    var range = document.createRange();
    range.selectNode(container);
    window.getSelection().addRange(range);
  
    document.execCommand("copy");
    for (var i = 0; i < activeSheets.length; i++) activeSheets[i].disabled = true;
    document.execCommand("copy");
    for (var i = 0; i < activeSheets.length; i++)
      activeSheets[i].disabled = false;
  
    // Remove the iframe
    document.body.removeChild(container);
  }

  function mainFormPlaceholder(msg) {
    return "<div class='w3-row-padding w3-padding-24 w3-container w3-flat-clouds'><div class='w3-code notranslate w3-border-white' style='font-family: Arial, Helvetica, sans-serif;'><p>" + msg + "</p><br><br><br><br><br><br><br><br><br><br><br></div></div>";
  }

  export default parseFormOnSubmit;