/**
 * Pure utility functions for consolidating multiple Ivanti queue items
 * into a single Jira ticket's summary, description, CVE, and vendor fields.
 */

/**
 * Generate a consolidated summary for a multi-item Jira ticket.
 * Format: "[N findings] vendor - first_finding_title", truncated to 255 chars.
 *
 * @param {Array} items - Array of queue item objects
 * @returns {string} Generated summary, at most 255 characters
 */
export function generateConsolidatedSummary(items) {
  const count = items.length;
  const vendors = [...new Set(items.map(i => i.vendor).filter(Boolean))];
  const vendorLabel = vendors.length === 1 ? vendors[0] : 'Multiple Vendors';
  const firstTitle = items[0]?.finding_title || 'Untitled';
  const raw = `[${count} findings] ${vendorLabel} - ${firstTitle}`;
  return raw.slice(0, 255);
}

/**
 * Generate a structured description grouped by vendor for a consolidated Jira ticket.
 *
 * @param {Array} items - Array of queue item objects
 * @returns {string} Structured description with header and vendor-grouped items
 */
export function generateConsolidatedDescription(items) {
  const header = `Consolidated Jira ticket covering ${items.length} Ivanti queue findings.\n\n`;

  // Group by vendor
  const grouped = {};
  for (const item of items) {
    const vendor = item.vendor || 'Unknown Vendor';
    if (!grouped[vendor]) grouped[vendor] = [];
    grouped[vendor].push(item);
  }

  let body = '';
  for (const [vendor, vendorItems] of Object.entries(grouped)) {
    body += `== ${vendor} ==\n`;
    for (const item of vendorItems) {
      let cves = 'None';
      if (item.cves_json) {
        try {
          const parsed = JSON.parse(item.cves_json);
          if (Array.isArray(parsed) && parsed.length > 0) {
            cves = parsed.join(', ');
          }
        } catch (e) {
          cves = 'None';
        }
      }
      body += `- ${item.finding_title}\n`;
      body += `  CVEs: ${cves}\n`;
      body += `  Host: ${item.hostname || 'N/A'} (${item.ip_address || 'N/A'})\n\n`;
    }
  }

  return header + body;
}

/**
 * Extract the first CVE from the first item that has a non-empty cves_json array.
 *
 * @param {Array} items - Array of queue item objects
 * @returns {string} First CVE ID found, or empty string if none
 */
export function extractFirstCve(items) {
  for (const item of items) {
    if (item.cves_json) {
      try {
        const cves = JSON.parse(item.cves_json);
        if (Array.isArray(cves) && cves.length > 0) return cves[0];
      } catch (e) {
        // Skip items with invalid JSON
      }
    }
  }
  return '';
}

/**
 * Extract the common vendor if all items share the same vendor.
 *
 * @param {Array} items - Array of queue item objects
 * @returns {string} Common vendor name if all items share it, empty string otherwise
 */
export function extractCommonVendor(items) {
  const vendors = [...new Set(items.map(i => i.vendor).filter(Boolean))];
  return vendors.length === 1 ? vendors[0] : '';
}

/**
 * Append remediation notes to a Jira ticket description.
 * Only appends if notesMap contains notes for at least one item.
 *
 * @param {string} baseDescription - The standard consolidated description
 * @param {Object} notesMap - { [queue_item_id]: Array<{username, note_text, created_at}> }
 * @returns {string} Description with remediation notes appended (or unchanged)
 */
export function appendRemediationNotes(baseDescription, notesMap) {
  if (!notesMap || typeof notesMap !== 'object') return baseDescription;

  // Collect all notes from all items, sorted chronologically (oldest first)
  const allNotes = [];
  for (const [_itemId, notes] of Object.entries(notesMap)) {
    if (!Array.isArray(notes)) continue;
    for (const note of notes) {
      if (note && note.note_text) {
        allNotes.push(note);
      }
    }
  }

  if (allNotes.length === 0) return baseDescription;

  // Sort chronologically (oldest first)
  allNotes.sort((a, b) => new Date(a.created_at) - new Date(b.created_at));

  let section = '\n== Remediation Notes ==\n';
  for (const note of allNotes) {
    const date = formatNoteDate(note.created_at);
    section += `[${date}] ${note.username}: ${note.note_text}\n`;
  }

  return baseDescription + section;
}

/**
 * Format a date string as YYYY-MM-DD for note display.
 * @param {string} dateStr - ISO date string
 * @returns {string} Formatted date
 */
function formatNoteDate(dateStr) {
  try {
    const d = new Date(dateStr);
    return d.toISOString().slice(0, 10);
  } catch {
    return 'Unknown';
  }
}
