const MAPS_LEAD_COLUMNS = [
  ["name", "Business Name"],
  ["category", "Category"],
  ["location", "Location"],
  ["website", "Website"],
  ["email", "Public Business Email"],
  ["phone", "Phone Number"],
  ["contactForms", "Contact Form URL"],
  ["socialLinks", "Social Links"],
  ["sourceUrl", "Source/Evidence URL"],
  ["validationStatus", "Validation Status"],
  ["contactConfidence", "Contact Confidence Score"],
  ["campaignReady", "Campaign Ready"],
  ["sourceQuery", "Source Query"],
  ["approved", "Approved"],
  ["score", "Quality Score"],
  ["reason", "Qualification Reason"]
];

const BUSINESS_LEAD_COLUMNS = MAPS_LEAD_COLUMNS;

const OWNER_LEAD_COLUMNS = [
  ["name", "Name"],
  ["login", "GitHub Login"],
  ["platformLabel", "Platform"],
  ["repoFullName", "Repository"],
  ["repoStars", "Repo Stars"],
  ["repoLanguage", "Repo Language"],
  ["city", "Owner Location"],
  ["email", "Email"],
  ["phone", "Phone"],
  ["emails", "All Emails"],
  ["phones", "All Phones"],
  ["website", "Website"],
  ["githubUrl", "GitHub URL"],
  ["summary", "Business Summary"],
  ["likelyBusiness", "Likely Business"],
  ["tractionSignal", "Traction Signal"],
  ["angles", "Hunt Angles Tried"],
  ["source", "Discovery Source"],
  ["sourceQuery", "Source Query"],
  ["approved", "Approved"],
  ["score", "Score"],
  ["reason", "Qualification Reason"]
];

const COLUMN_SETS = {
  "lead-scraper": BUSINESS_LEAD_COLUMNS,
  "google-maps": BUSINESS_LEAD_COLUMNS,
  "github-owners": OWNER_LEAD_COLUMNS
};

const DEFAULT_COLUMNS = BUSINESS_LEAD_COLUMNS;

export function exportableLeads(run, { approvedOnly = false, includeExcluded = false } = {}) {
  return (run?.qualifiedLeads || []).filter((lead) => {
    if (!includeExcluded && lead.excluded) return false;
    if (approvedOnly && lead.approved === false) return false;
    return true;
  });
}

export function leadsCsv(run, options = {}) {
  const columns = columnSet(run);
  const rows = [columns.map(([, header]) => header)];
  for (const lead of exportableLeads(run, options)) {
    rows.push(columns.map(([key]) => leadExportValue(lead, key)));
  }
  return `${rows.map((row) => row.map(csvCell).join(",")).join("\n")}\n`;
}

export function leadsJson(run, options = {}) {
  return exportableLeads(run, options).map((lead) => baseLeadJson(lead));
}

export function leadExportFilename(run) {
  const source = run?.input?.source || "google-maps";
  const nichePart = safeFilePart(run?.input?.niche || source);
  const stamp = new Date(run?.updatedAt || Date.now()).toISOString().slice(0, 10);
  return `${source}-${nichePart}-${stamp}-qualified-leads.csv`;
}

export function portfolioReportFilename(run) {
  const source = run?.input?.source || "google-maps";
  const nichePart = safeFilePart(run?.input?.niche || source);
  const stamp = new Date(run?.updatedAt || Date.now()).toISOString().slice(0, 10);
  return `${source}-${nichePart}-${stamp}-client-portfolio.md`;
}

export function portfolioMarkdown(run) {
  const leads = exportableLeads(run, { approvedOnly: true });
  const campaignReadyCount = leads.filter((lead) => campaignReady(lead)).length;
  const lines = [
    "# Hermes Business Contact Portfolio",
    "",
    `Run ID: ${run?.id || ""}`,
    `Source: ${run?.input?.source || "google-maps"}`,
    `Niche: ${run?.input?.niche || ""}`,
    `Status: ${run?.status || ""}`,
    `Updated: ${run?.updatedAt || ""}`,
    "",
    "## Client Summary",
    "",
    "Hermes collects public business contact information and keeps source evidence with each exported lead.",
    "",
    `Qualified leads: ${leads.length}`,
    `Campaign-ready leads: ${campaignReadyCount}`,
    `Website enrichments: ${run?.counters?.enriched || 0}`,
    `Rejected rows: ${run?.counters?.rejected || 0}`,
    `MiniMax calls: ${run?.counters?.llmCalls || 0}`,
    `MiniMax fallbacks: ${run?.counters?.llmFallbacks || 0}`,
    `MiniMax timeouts: ${run?.counters?.llmTimeouts || 0}`,
    `Internal watchdog checks: ${run?.flowWatchdog?.checks || 0}`,
    `Internal watchdog repairs suggested: ${run?.flowWatchdog?.repairs?.length || 0}`,
    "",
    "## Validation Rules",
    "",
    "- Every exported lead includes a business name and at least one public contact or website surface.",
    "- Email format, domain, duplicates, bad rows, and location mismatch are checked before export.",
    "- Source/evidence URLs and search queries are retained for auditability.",
    "- Campaign readiness is based on public contact evidence and usable campaign fields.",
    "",
    "## Lead Portfolio",
    ""
  ];

  leads.forEach((lead, index) => {
    lines.push(
      `### ${index + 1}. ${lead.name || "Unnamed business"}`,
      "",
      `Business: ${[lead.category, lead.city].filter(Boolean).join(" | ") || "Not available"}`,
      `Address: ${lead.address || "Not available"}`,
      `Website: ${lead.website || "Not available"}`,
      `Business contact: ${[lead.email || lead.businessEmail, lead.phone || lead.businessPhone].filter(Boolean).join(" | ") || "Not available"}`,
      `Contact forms: ${arrayText(lead.contactForms) || "Not available"}`,
      `Social links: ${arrayText(lead.socialLinks) || "Not available"}`,
      `Source evidence: ${sourceEvidenceUrl(lead) || "Not available"}`,
      `Validation: ${validationStatus(lead)}`,
      `Contact confidence: ${contactConfidenceLabel(lead)}`,
      `Campaign ready: ${campaignReady(lead) ? "Yes" : "No"}`,
      `Certification: ${certificationStatus(lead)}`,
      `Evidence summary: ${evidenceSummary(lead) || "Not available"}`,
      `Notes: ${certificationNotes(lead) || "Not available"}`,
      ""
    );
  });

  if (run?.flowWatchdog?.repairs?.length) {
    lines.push("## Internal Watchdog Repairs", "");
    for (const repair of run.flowWatchdog.repairs.slice(0, 10)) {
      lines.push(`- ${repair.action} Reason: ${repair.reason}`);
    }
    lines.push("");
  }

  return `${lines.join("\n")}\n`;
}

function columnSet(run) {
  const source = run?.input?.source || "google-maps";
  return COLUMN_SETS[source] || DEFAULT_COLUMNS;
}

function baseLeadJson(lead) {
  if (lead.source === "github-owners") {
    return {
      name: lead.name || "",
      login: lead.login || "",
      platform: lead.platformLabel || lead.platform || "",
      repo: lead.repoFullName || "",
      repoStars: lead.repoStars || 0,
      repoLanguage: lead.repoLanguage || "",
      location: lead.city || "",
      email: lead.email || "",
      phone: lead.phone || "",
      emails: lead.emails || [],
      phones: lead.phones || [],
      website: lead.website || "",
      githubUrl: lead.githubUrl || "",
      summary: lead.summary || "",
      likelyBusiness: lead.likelyBusiness || "",
      tractionSignal: lead.tractionSignal || "",
      angles: lead.angles || [],
      discoverySource: "legacy-owner-source",
      approved: lead.approved !== false,
      score: lead.quality?.score ?? "",
      reason: lead.quality?.reason || ""
    };
  }
  return {
    name: lead.name || "",
    category: lead.category || "",
    city: lead.city || "",
    address: lead.address || "",
    location: locationText(lead),
    email: lead.email || lead.businessEmail || "",
    phone: lead.phone || lead.businessPhone || "",
    contactForms: lead.contactForms || [],
    socialLinks: lead.socialLinks || [],
    website: lead.website || "",
    sourceUrl: sourceEvidenceUrl(lead),
    validationStatus: validationStatus(lead),
    contactConfidence: contactConfidence(lead),
    contactConfidenceLabel: contactConfidenceLabel(lead),
    campaignReady: campaignReady(lead),
    certificationStatus: certificationStatus(lead),
    certificationNotes: certificationNotes(lead),
    evidenceSummary: evidenceSummary(lead),
    sourceQuery: lead.sourceQuery || "",
    discoverySource: lead.source || "lead-scraper",
    approved: lead.approved !== false,
    score: lead.quality?.score ?? "",
    reason: lead.quality?.reason || ""
  };
}

function leadExportValue(lead, key) {
  if (key === "score") return lead?.quality?.score ?? "";
  if (key === "reason") return lead?.quality?.reason || "";
  if (key === "approved") return lead?.approved === false ? "No" : "Yes";
  if (key === "email") return lead?.email || lead?.businessEmail || "";
  if (key === "phone") return lead?.phone || lead?.businessPhone || "";
  if (key === "ownerEmail") return leadContactEmail(lead);
  if (key === "ownerPhone") return leadContactPhone(lead);
  if (key === "emails" || key === "phones" || key === "angles" || key === "ownerEmails" || key === "ownerPhones") {
    const value = lead?.[key];
    if (Array.isArray(value)) return value.join("; ");
    return value || "";
  }
  if (key === "ownerSocialProfiles") {
    const value = lead?.[key];
    if (Array.isArray(value)) return value.join("; ");
    return value || "";
  }
  if (key === "contactForms" || key === "socialLinks") {
    const value = lead?.[key] || [];
    return Array.isArray(value) ? value.join("; ") : value || "";
  }
  if (key === "rabbitHoleSearchQueries") {
    const value = lead?.rabbitHoleStrategy?.searchQueries;
    if (Array.isArray(value)) return value.join("; ");
    return value || "";
  }
  if (key === "ownerAgentSwarm") return ownerAgentSwarmSummary(lead);
  if (key === "profileToolAttempts") return profileToolAttemptSummary(lead);
  if (key === "ownerContactEvidence") return ownerContactEvidenceSummary(lead);
  if (key === "location") return locationText(lead);
  if (key === "sourceUrl") return sourceEvidenceUrl(lead);
  if (key === "validationStatus") return validationStatus(lead);
  if (key === "campaignReady") return campaignReady(lead) ? "Yes" : "No";
  if (key === "contactConfidence") return contactConfidence(lead);
  if (key === "contactConfidenceLabel") return contactConfidenceLabel(lead);
  if (key === "ownerDirect") return contactConfidence(lead) === "owner-direct" ? "Yes" : "No";
  if (key === "ownerAssociated") return contactConfidence(lead) === "owner-associated" ? "Yes" : "No";
  if (key === "ownerEvidenceGraph") return ownerEvidenceGraphSummary(lead);
  if (key === "certificationStatus") return certificationStatus(lead);
  if (key === "certificationNotes") return certificationNotes(lead);
  if (key === "evidenceSummary") return evidenceSummary(lead);
  if (key === "repoStars") return lead?.repoStars ?? "";
  return lead?.[key] ?? "";
}

function ownerAgentSwarmSummary(lead) {
  const swarm = lead?.ownerAgentSwarm;
  if (!swarm) return "";
  const traces = Array.isArray(swarm.traces) ? swarm.traces : [];
  const roleSummary = traces
    .map((trace) => `${trace.role}:${trace.searchHits || 0} hits/${trace.pagesFetched || 0} pages`)
    .slice(0, 12)
    .join("; ");
  return [
    `requested ${swarm.requestedPerPass || swarm.requested || traces.length} per pass`,
    `deployed ${swarm.deployedTotal || swarm.deployed || traces.length} total`,
    roleSummary
  ].filter(Boolean).join("; ");
}

function profileToolAttemptSummary(lead) {
  const attempts = (lead?.socialEvidence || [])
    .flatMap((entry) => Array.isArray(entry.toolAttempts) ? entry.toolAttempts : []);
  if (!attempts.length) return "";
  return attempts
    .map((attempt) => `${attempt.tool}: ${attempt.status}`)
    .filter(Boolean)
    .join("; ");
}

function csvCell(value) {
  const text = String(value ?? "");
  if (!/[",\n\r]/.test(text)) return text;
  return `"${text.replace(/"/g, '""')}"`;
}

function certificationStatus(lead) {
  if (lead?.source === "github-owners") return lead.email || lead.phone ? "Certified owner contact" : "Needs contact review";
  if (lead?.contactTarget === "business" || lead?.source !== "github-owners") return campaignReady(lead) ? "Campaign ready" : "Needs business contact review";
  if (lead?.ownerName && hasOwnerContact(lead) && hasOwnerContactProof(lead)) return "Certified owner contact";
  if (contactConfidence(lead) === "owner-associated") return "Owner reachable";
  if (lead?.ownerName && hasOwnerContact(lead)) return "Owner contact needs evidence review";
  if (lead?.ownerName) return "Owner identified, contact missing";
  return "Needs owner review";
}

function contactConfidence(lead) {
  if (lead?.source === "github-owners") return lead.email || lead.phone ? "owner-direct" : "no-contact";
  if (["business-direct", "contact-form", "website-only", "no-contact"].includes(lead?.contactConfidence)) return lead.contactConfidence;
  if (lead?.contactTarget === "business" || lead?.source !== "github-owners") {
    if (lead?.email || lead?.businessEmail || lead?.phone || lead?.businessPhone) return "business-direct";
    if (lead?.contactForms?.length || lead?.socialLinks?.length) return "contact-form";
    if (lead?.website) return "website-only";
    return "no-contact";
  }
  if (["owner-direct", "owner-associated", "business-only", "no-contact"].includes(lead?.contactConfidence)) return lead.contactConfidence;
  if (lead?.ownerName && hasOwnerContact(lead) && hasOwnerContactProof(lead)) return "owner-direct";
  if (lead?.ownerName && (lead?.businessEmail || lead?.businessPhone)) return "owner-associated";
  if (lead?.businessEmail || lead?.businessPhone || lead?.email || lead?.phone) return "business-only";
  return "no-contact";
}

function contactConfidenceLabel(lead) {
  return ({
    "business-direct": "Direct business contact",
    "contact-form": "Public form or social contact",
    "website-only": "Website available",
    "owner-direct": "Owner reachable",
    "owner-associated": "Owner reachable",
    "business-only": "Direct business contact",
    "no-contact": "No public contact"
  })[contactConfidence(lead)] || "No public contact";
}

function certificationNotes(lead) {
  if (lead?.source === "github-owners") return lead.summary || lead.quality?.reason || "";
  if (lead?.contactTarget === "business" || lead?.source !== "github-owners") {
    const parts = [];
    if (lead.email || lead.businessEmail) parts.push("public business email present");
    if (lead.phone || lead.businessPhone) parts.push("public phone present");
    if (lead.contactForms?.length) parts.push("contact form present");
    if (lead.socialLinks?.length) parts.push("social link present");
    if (sourceEvidenceUrl(lead)) parts.push("source evidence recorded");
    return parts.join("; ") || lead.quality?.reason || "";
  }
  const parts = [];
  if (lead.ownerName) parts.push(`Owner identified as ${lead.ownerName}`);
  if (lead.ownerEmail || lead.email) parts.push("owner email present");
  if (lead.ownerPhone || lead.phone) parts.push("owner phone present");
  if (hasOwnerContactProof(lead)) parts.push("owner contact evidence recorded");
  if (contactConfidence(lead) === "owner-associated") parts.push("owner can be reached through the listed channel");
  if (lead.ownerLinkedIn) parts.push("LinkedIn/profile evidence present");
  return parts.join("; ") || lead.quality?.reason || "";
}

function evidenceSummary(lead) {
  if (lead?.source === "github-owners") return [lead.repoFullName, lead.website].filter(Boolean).join("; ");
  if (lead?.contactTarget === "business" || lead?.source !== "github-owners") {
    return [
      sourceEvidenceUrl(lead),
      arrayText(lead.contactForms),
      arrayText(lead.socialLinks),
      lead.enrichmentMode ? `enrichment:${lead.enrichmentMode}` : ""
    ].filter(Boolean).join("; ");
  }
  return [
    lead.ownerEvidenceUrl,
    ownerContactEvidenceSummary(lead),
    arrayText(lead.ownerSocialProfiles),
    lead.rabbitHoleStatus,
    lead.rabbitHoleStrategy?.strategyReason
  ].filter(Boolean).join("; ");
}

function ownerContactEvidenceSummary(lead) {
  const evidence = Array.isArray(lead?.ownerContactEvidence) ? lead.ownerContactEvidence : [];
  return evidence
    .map((entry) => `${entry.type || "contact"} ${entry.value || ""} via ${entry.url || entry.source || "unknown source"}`)
    .filter(Boolean)
    .join("; ");
}

function ownerEvidenceGraphSummary(lead) {
  const graph = lead?.ownerEvidenceGraph || {};
  if (!Object.keys(graph).length) return "";
  return JSON.stringify({
    strategyVersion: graph.strategyVersion || "",
    owner: graph.owner || {},
    contactConfidence: graph.contactConfidence || contactConfidence(lead),
    ownerIdentityProven: Boolean(graph.ownerIdentityProven),
    ownerDirectContactProven: Boolean(graph.ownerDirectContactProven),
    ownerAssociatedContactProven: Boolean(graph.ownerAssociatedContactProven),
    qualityRedFlags: Array.isArray(graph.qualityRedFlags) ? graph.qualityRedFlags.slice(0, 8) : [],
    proofUrls: Array.isArray(graph.proofUrls) ? graph.proofUrls.slice(0, 8) : [],
    profileLinks: Array.isArray(graph.profileLinks) ? graph.profileLinks.slice(0, 8) : [],
    contactEvidence: Array.isArray(graph.contactEvidence) ? graph.contactEvidence.slice(0, 8) : []
  });
}

function hasOwnerContact(lead) {
  return Boolean(lead?.ownerEmail || lead?.ownerPhone || lead?.email || lead?.phone);
}

function hasOwnerContactProof(lead) {
  const evidence = Array.isArray(lead?.ownerContactEvidence) ? lead.ownerContactEvidence : [];
  const contacts = new Set([
    lead?.ownerEmail,
    lead?.ownerPhone,
    lead?.email,
    lead?.phone
  ].filter(Boolean).map((value) => String(value).toLowerCase()));
  return evidence.some((entry) => contacts.has(String(entry?.value || "").toLowerCase()) && (entry.url || entry.source));
}

function leadContactEmail(lead) {
  return lead?.ownerEmail || lead?.email || (contactConfidence(lead) === "owner-associated" ? lead?.businessEmail : "") || "";
}

function leadContactPhone(lead) {
  return lead?.ownerPhone || lead?.phone || (contactConfidence(lead) === "owner-associated" ? lead?.businessPhone : "") || "";
}

function arrayText(value) {
  return Array.isArray(value) ? value.filter(Boolean).join("; ") : String(value || "");
}

function locationText(lead = {}) {
  return [lead.address, lead.city, lead.country].filter(Boolean).join(", ");
}

function sourceEvidenceUrl(lead = {}) {
  return lead.sourceUrl || lead.evidenceUrl || lead.website || lead.placeUrl || lead.googleMapsUrl || lead.url || "";
}

function validationStatus(lead = {}) {
  if (lead.validationStatus) return lead.validationStatus;
  if (lead.excluded) return "excluded";
  if (lead.quality?.qualified === false) return "rejected";
  if (lead.quality?.qualified === true || businessContactPresent(lead)) return "validated";
  return "needs-review";
}

function campaignReady(lead = {}) {
  return lead.approved !== false && validationStatus(lead) === "validated" && businessContactPresent(lead);
}

function businessContactPresent(lead = {}) {
  return Boolean(lead.email || lead.businessEmail || lead.phone || lead.businessPhone || lead.contactForms?.length || lead.socialLinks?.length || lead.website);
}

function safeFilePart(value) {
  return String(value || "")
    .trim()
    .toLowerCase()
    .replace(/[^a-z0-9]+/g, "-")
    .replace(/^-|-$/g, "")
    .slice(0, 80) || "leads";
}
