const baseURL = "{site_url}",
  accessToken = "{token}",
  sheetTab = "{sheet_tab}";

function RunSSGSW() {
  if (SpreadsheetApp.getActiveSheet().getSheetName() !== sheetTab) return;
  ssgsw_add_menus();
  ssgsw_apply_styles();
}

function onOpen() {
  RunSSGSW();
}

function onEdit() {
  if (SpreadsheetApp.getActiveSheet().getSheetName() !== sheetTab) return;

  if (ssgsw_current_row() == 1) return;

  const currentRow = ssgsw_current_column();
  if (["ID", "type", "sales", "category"].includes(currentRow)) return;

  let data = ssgsw_get_edited_data();

  Logger.log(data);
  ssgsw_sync_data(data);
}

function ssgsw_add_menus() {
  SpreadsheetApp.getUi()
    .createMenu("Stock Sync")
    .addItem("⟱ Fetch from WooCommerce", "ssgsw_fetch_from_WordPress")
    .addItem("⟰ Sync on WooCommerce", "ssgsw_sync_all")
    .addSeparator()
    .addItem(" Format Styles", "ssgsw_apply_styles")
    .addItem(" About Stock Sync", "ssgsw_about_us")
    .addToUi();
}

function ssgsw_apply_styles() {
  const Columns = ssgsw_column_char(ssgsw_max_column());
  const Headers = "A1:" + Columns + 1;
  const StaticColumns = ssgsw_column_index(["ID", "type", "category", "sales"])
    .filter((index) => index >= 0)
    .map(ssgsw_column_char);
  const StockColumn = ssgsw_column_index(["stock"]).map((index) =>
    ssgsw_column_char(index)
  )[0];

  const StaticColumnHeaders = StaticColumns.map((column) => column + 1);
  const StaticColumnValues = StaticColumns.map(
    (column) => column + 2 + ":" + column
  );

  const StockColumnValues = StockColumn + 2 + ":" + StockColumn;
  const CenterableColumns = ssgsw_column_index([
    "stock",
    "regularPrice",
    "salePrice",
    "sales",
  ])
    .filter((index) => index >= 0)
    .map((char) => ssgsw_column_char(char) + "1:" + ssgsw_column_char(char));

  const Color = {
    primary: "#686de0",
    white: "white",
    black: "black",
    grey: "#dedede",
    success: "green",
    error: "indianred",
    info: "purple",
    warning: "orange",
  };
  Logger.log(CenterableColumns);

  const CurrentSheet = SpreadsheetApp.getActive().getSheetByName(sheetTab);

  CurrentSheet.getRange("A1:J1")
    .setFontWeight("normal")
    .setBackground(Color.white)
    .setFontColor(Color.black);
  CurrentSheet.getRange(Headers)
    .setFontWeight("bold")
    .setBackground(Color.primary)
    .setFontColor(Color.white);
  CurrentSheet.getRangeList(StaticColumnHeaders).setBackground(Color.error);
  CurrentSheet.getRangeList(StaticColumnValues)
    .setBackground(Color.grey)
    .setFontColor(Color.black);
  CurrentSheet.getRangeList(CenterableColumns).setHorizontalAlignment("center");

  let rule1 = SpreadsheetApp.newConditionalFormatRule()
    .whenTextEqualTo("In Stock")
    .setBackground("#f7fff9")
    .setFontColor("green")
    .setRanges([SpreadsheetApp.getActiveSheet().getRange(StockColumnValues)])
    .build();

  let rule2 = SpreadsheetApp.newConditionalFormatRule()
    .whenTextEqualTo("Out of Stock")
    .setBackground("#fff8f7")
    .setFontColor("indianred")
    .setRanges([SpreadsheetApp.getActiveSheet().getRange(StockColumnValues)])
    .build();

  let rule3 = SpreadsheetApp.newConditionalFormatRule()
    .whenTextEqualTo("On Backorder")
    .setBackground("#fffdf7")
    .setFontColor("orange")
    .setRanges([SpreadsheetApp.getActiveSheet().getRange(StockColumnValues)])
    .build();

  let rule4 = SpreadsheetApp.newConditionalFormatRule()
    .whenNumberGreaterThan(0)
    .setBackground("#f7fff9")
    .setFontColor("green")
    .setRanges([SpreadsheetApp.getActiveSheet().getRange(StockColumnValues)])
    .build();

  let rule5 = SpreadsheetApp.newConditionalFormatRule()
    .whenNumberLessThan(1)
    .setBackground("#fff8f7")
    .setFontColor("indianred")
    .setRanges([SpreadsheetApp.getActiveSheet().getRange(StockColumnValues)])
    .build();

  CurrentSheet.setConditionalFormatRules([rule1, rule2, rule3, rule4, rule5]);
}

function ssgsw_about_us() {
  let htmlOutput = HtmlService.createHtmlOutput(
    `<h3>Stock Sync with Google Sheet for WooCommerce</h3>
        <p>Sync your WooCommerce product stock with Google Sheets.</p>
        <p><a href="https://wordpress.org/plugins/stock-sync-with-google-sheet-for-woocommerce/" target="_blank">Download Free</a> version from WordPress.org</p>
        <p><a href="http://wppool.dev/stock-sync-for-woocommerce-with-google-sheet" target="_blank">Get Ultimate</a> version to enjoy all premium features and official updates.</p>
        `
  )
    .setWidth(550)
    .setHeight(200);
  SpreadsheetApp.getUi().showModalDialog(
    htmlOutput,
    "Stock Sync with Google Sheet for WooCommerce"
  );
}

function ssgsw_headers() {
  let header = SpreadsheetApp.getActive()
    .getSheetByName(sheetTab)
    .getRange("A1:I1")
    .getValues();
  header = header[0].filter((column) => column.length);
  Logger.log(header);
  return header;
}

function ssgsw_columns() {
  let columns = {
    ID: "ID",
    Type: "type",
    Name: "name",
    Stock: "stock",
    "Regular Price": "regularPrice",
    "Sale Price": "salePrice",
    "Short Description": "excerpt",
    Category: "category",
    Sales: "sales",
  };

  return columns;
}

function ssgsw_available_columns() {
  let columns = ssgsw_columns();
  let headers = ssgsw_headers();
  let keys = {};

  headers.forEach((header) => {
    if (Object.keys(columns).includes(header)) {
      keys[header] = columns[header];
    }
  });

  Logger.log(JSON.stringify(keys));
  return keys;
}

function ssgsw_max_column() {
  let maxColumn = SpreadsheetApp.getActive()
    .getSheetByName(sheetTab)
    .getLastColumn();
  return maxColumn;
}

function ssgsw_column_char(index = 0) {
  const alphabet = "abcdefghijklmnopqrstuvwxyz".toUpperCase().split("");
  return alphabet[index - 1] || null;
}

function ssgsw_current_row() {
  let currentCell = SpreadsheetApp.getActive()
    .getSheetByName(sheetTab)
    .getCurrentCell()
    .getA1Notation();
  let row = currentCell.replace(/[^0-9]/g, "");

  return row;
}

function ssgsw_current_column() {
  let currentCell = SpreadsheetApp.getActive()
    .getSheetByName(sheetTab)
    .getCurrentCell()
    .getA1Notation();
  let rowNotation = currentCell.replace(/[0-9]/g, "");
  rowNotation = "abcdefghijklmnopqrstuvwxyz"
    .toUpperCase()
    .split("")
    .indexOf(rowNotation);

  let column = Object.values(ssgsw_available_columns())[rowNotation];

  return column;
}

function ssgsw_column_index(columns) {
  let indexes = [];
  let available_columns = ssgsw_available_columns();

  columns.forEach((column) => {
    let index = Object.values(available_columns).indexOf(column);
    if (index >= 0) index++;
    indexes.push(index);
  });

  Logger.log(indexes);
  return indexes;
}

function ssgsw_format(data) {
  const deletables = ["type", "sales", "category"];
  const keys = ssgsw_ordered_keys();
  data = data
    .map((row) => {
      return Object.assign.apply(
        {},
        keys.map((v, i) => ({ [v]: row[i] }))
      );
    })
    .map((row) => {
      deletables.forEach((key) => {
        if (key in row) delete row[key];
      });

      return row;
    });
  return data;
}

function ssgsw_get_all_data() {
  var values = SpreadsheetApp.getActive()
    .getSheetByName(sheetTab)
    .getDataRange()
    .getValues();
  values.shift();
  return ssgsw_format(values);
}

function ssgsw_get_edited_data() {
  let row = SpreadsheetApp.getActive()
    .getSheetByName(sheetTab)
    .getCurrentCell()
    .getRow();

  Logger.log(row);

  let values = SpreadsheetApp.getActive()
    .getSheetByName(sheetTab)
    .getRange(
      row,
      1,
      1,
      SpreadsheetApp.getActive().getSheetByName(sheetTab).getLastColumn()
    )
    .getValues();
  values = values[0];
  values.map((col, index) => {
    if (index === 0) return parseInt(col);
    return col;
  });
  return ssgsw_format([values]);
}

function ssgsw_ordered_keys() {
  let orderedKeys = [];
  ssgsw_headers().forEach((header) => {
    orderedKeys.push(ssgsw_available_columns()[header]);
  });
  return orderedKeys;
}

function ssgsw_sync_all() {
  let data = ssgsw_get_all_data();
  ssgsw_sync_data(data);
}

function ssgsw_sync_data(data) {
  data = data.filter((row) => {
    return row[2] !== "" && row[0] !== "ID";
  });

  if (!data.length) return;

  let response = UrlFetchApp.fetch(baseURL + "/wp-json/ssgsw/v1/update", {
    method: "POST",
    payload: JSON.stringify({ products: data }),
    contentType: "application/json",
    muteHttpExceptions: true,
    headers: {
      Authorization: "Bearer " + accessToken,
    },
  });

  response = JSON.parse(response.getContentText());
  Logger.log(response);

  if (response.message) {
    SpreadsheetApp.getActiveSpreadsheet().toast(response.message);
  }
}

function ssgsw_fetch_from_WordPress() {
  let response = UrlFetchApp.fetch(
    baseURL + "/wp-json/ssgsw/v1/action/?action=sync",
    {
      method: "GET",
      contentType: "application/json",
      muteHttpExceptions: true,
      headers: {
        Authorization: "Bearer " + accessToken,
      },
    }
  );

  response = JSON.parse(response.getContentText());
  Logger.log(response);
  if (response.message) {
    SpreadsheetApp.getActiveSpreadsheet().toast(response.message);
  }
}
