/***************
 * CONFIG
 ***************/
const CONFIG = {
  SPREADSHEET_ID: "17II0V8EsTL-9nHq2HgqhHcay-t-hhOaY5wNEzXHEsAM",
  SOURCE_SHEET_NAME: "WSMinMCA.csv",       // tab name inside the spreadsheet
  EMAIL_COLUMN_INDEX_1BASED: 3,            // Column C = 3 (1-based)
  SENDER: "nrasmussen@gainsight.com",
  SUBJECT: "DATA REQUEST",
  PROCESSED_LABEL: "DATA_REQUEST_PROCESSED",
  TEMP_SHEET_PREFIX: "DATA_REQUEST_",      // new tab prefix
  MAX_THREADS_PER_RUN: 10                  // safety throttle
};

/**
 * Run once to create the time-driven trigger.
 * (There is no true "email received" trigger for Gmail in Apps Script.)
 */
function setupTrigger() {
  // Optional: delete existing triggers for this function to avoid duplicates
  ScriptApp.getProjectTriggers()
    .filter(t => t.getHandlerFunction() === "processDataRequests")
    .forEach(t => ScriptApp.deleteTrigger(t));

  // Create a trigger every 5 minutes (adjust as desired)
  ScriptApp.newTrigger("processDataRequests")
    .timeBased()
    .everyMinutes(5)
    .create();
}

/**
 * Main worker: finds unread "DATA REQUEST" messages from aubrey@ws.com,
 * extracts target email from body, filters rows, creates new tab, CSVs it,
 * replies with attachment, and labels thread as processed.
 */
function processDataRequests() {
  // const label = GmailApp.getUserLabelByName(CONFIG.PROCESSED_LABEL) || GmailApp.createLabel(CONFIG.PROCESSED_LABEL);

  // // Search unread matching threads that are not already labeled processed
  // const query = [
  //   `from:${CONFIG.SENDER}`,
  //   `subject:"${CONFIG.SUBJECT}"`,
  //   "is:unread",
  //   `-label:${CONFIG.PROCESSED_LABEL}`
  // ].join(" ");

  const threads = GmailApp.search(query, 0, CONFIG.MAX_THREADS_PER_RUN);
  Logger.log(threads);
  // if (!threads.length) return;

  const ss = SpreadsheetApp.openById(CONFIG.SPREADSHEET_ID);
  const sourceSheet = ss.getSheetByName(CONFIG.SOURCE_SHEET_NAME);
  if (!sourceSheet) throw new Error(`Sheet tab not found: ${CONFIG.SOURCE_SHEET_NAME}`);

  // Read all data once for efficiency
  const sourceValues = sourceSheet.getDataRange().getValues();
  if (sourceValues.length < 1) throw new Error(`No data found in ${CONFIG.SOURCE_SHEET_NAME}`);

  const header = sourceValues[0];
  const emailColIdx0 = CONFIG.EMAIL_COLUMN_INDEX_1BASED - 1;

  threads.forEach(thread => {
    const messages = thread.getMessages();

    // Process only unread messages in the thread (usually just the newest)
    messages.forEach(message => {
      if (!message.isUnread()) return;

      try {
        const plainBody = message.getPlainBody() || "";
        const targetEmail = extractFirstNonSenderEmail_(plainBody, CONFIG.SENDER);

        if (!targetEmail) {
          message.reply(
            `I received your DATA REQUEST, but I couldn't find a target email address in the message body.\n\n` +
            `Please include an email like "someone@company.com" in the body and resend.`
          );
          message.markRead();
          return;
        }

        const targetLower = targetEmail.toLowerCase();

        // Filter rows where Column C exactly matches the extracted email (case-insensitive)
        const matches = sourceValues
          .slice(1) // skip header
          .filter(row => String(row[emailColIdx0] || "").trim().toLowerCase() === targetLower);

        // Create a new tab with results
        const newSheetName = makeSafeSheetName_(
          `${CONFIG.TEMP_SHEET_PREFIX}${targetLower}_${Utilities.formatDate(new Date(), Session.getScriptTimeZone(), "yyyyMMdd_HHmmss")}`
        );

        const resultSheet = ss.insertSheet(newSheetName);
        resultSheet.getRange(1, 1, 1, header.length).setValues([header]);

        if (matches.length) {
          resultSheet.getRange(2, 1, matches.length, header.length).setValues(matches);
        }

        // Convert result tab to CSV
        const csv = valuesToCsv_(resultSheet.getDataRange().getValues());
        const blob = Utilities.newBlob(csv, "text/csv", `${targetLower}.csv`);

        // Reply with CSV attached (keeps threading)
        const body =
          `Attached is the CSV export for ${targetEmail}.\n\n` +
          `Rows matched (excluding header): ${matches.length}\n` +
          `Source tab: ${CONFIG.SOURCE_SHEET_NAME}\n` +
          `Result tab: ${newSheetName}\n`;

        message.reply(body, { attachments: [blob] });

        // Mark processed
        message.markRead();
        thread.addLabel(label);

        // Optional cleanup: uncomment if you do NOT want to keep the result tab
        // ss.deleteSheet(resultSheet);

      } catch (err) {
        // Fail gracefully: reply with error so the sender knows it didn't work
        message.reply(
          `I attempted to process this DATA REQUEST but hit an error:\n\n${err && err.stack ? err.stack : err}`
        );
        message.markRead();
      }
    });
  });
}

function modifiedProcessDataRequests() {
  const ss = SpreadsheetApp.openById(CONFIG.SPREADSHEET_ID);
  const sourceSheet = ss.getSheetByName(CONFIG.SOURCE_SHEET_NAME);
  if (!sourceSheet) throw new Error(`Sheet tab not found: ${CONFIG.SOURCE_SHEET_NAME}`);
  const targetEmail = "khodge2@wsgc.com";
  const targetLower = targetEmail.toLowerCase();

  // Read all data once for efficiency
  const sourceValues = sourceSheet.getDataRange().getValues();
  if (sourceValues.length < 1) throw new Error(`No data found in ${CONFIG.SOURCE_SHEET_NAME}`);

  const header = sourceValues[0];
  Logger.log(header);
  const emailColIdx0 = CONFIG.EMAIL_COLUMN_INDEX_1BASED - 1;
  Logger.log(emailColIdx0);

  // Filter rows where Column C exactly matches the extracted email (case-insensitive)
  const matches = sourceValues
    .slice(1) // skip header
    .filter(row => String(row[emailColIdx0] || "").trim().toLowerCase() === targetLower);

  // Create a new tab with results
  const newSheetName = makeSafeSheetName_(
    `${CONFIG.TEMP_SHEET_PREFIX}${targetLower}_${Utilities.formatDate(new Date(), Session.getScriptTimeZone(), "yyyyMMdd_HHmmss")}`
  );

  const resultSheet = ss.insertSheet(newSheetName);
  resultSheet.getRange(1, 1, 1, header.length).setValues([header]);

  if (matches.length) {
    resultSheet.getRange(2, 1, matches.length, header.length).setValues(matches);
  }

  // Convert result tab to CSV
  const csv = valuesToCsv_(resultSheet.getDataRange().getValues());
  const blob = Utilities.newBlob(csv, "text/csv", `${targetLower}.csv`);

  // Reply with CSV attached (keeps threading)
  const body =
    `Attached is the CSV export for ${targetEmail}.\n\n` +
    `Rows matched (excluding header): ${matches.length}\n` +
    `Source tab: ${CONFIG.SOURCE_SHEET_NAME}\n` +
    `Result tab: ${newSheetName}\n`;

  Logger.log(body);

  // Optional cleanup: uncomment if you do NOT want to keep the result tab
  // ss.deleteSheet(resultSheet);
}

/****************
 * HELPERS
 ****************/

/**
 * Extracts the first email address found in the text that is NOT the sender email.
 */
function extractFirstNonSenderEmail_(text, senderEmail) {
  const re = /[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}/ig;
  const found = text.match(re) || [];
  const senderLower = (senderEmail || "").toLowerCase();
  const first = found
    .map(e => e.trim())
    .find(e => e.toLowerCase() !== senderLower);
  return first || null;
}

/**
 * Converts a 2D array of values to RFC-ish CSV:
 * - Wrap fields in quotes if they contain comma, quote, or newline
 * - Double internal quotes
 */
function valuesToCsv_(values) {
  return values.map(row => row.map(cell => {
    let s = cell === null || cell === undefined ? "" : String(cell);
    // Normalize line endings inside cells
    s = s.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
    const needsQuotes = /[",\n]/.test(s);
    if (needsQuotes) s = `"${s.replace(/"/g, '""')}"`;
    return s;
  }).join(",")).join("\r\n");
}

/**
 * Google Sheets tab names have limits; keep it safe.
 */
function makeSafeSheetName_(name) {
  // Remove characters Sheets doesn't like: [ ] : * ? / \
  let safe = name.replace(/[\[\]:*?/\\]/g, " ");
  safe = safe.replace(/\s+/g, " ").trim();
  // Max length 100
  if (safe.length > 100) safe = safe.slice(0, 100);
  return safe || "DATA_REQUEST_RESULT";
}
