#!/usr/bin/env node
import fs from "node:fs";
import path from "node:path";
import xlsx from "xlsx";

function usage() {
  console.error("Usage: node scripts/import-sentiment-activity.mjs <xlsxPath> [dbPath]");
}

function token(value) {
  return String(value ?? "")
    .trim()
    .toLowerCase()
    .replace(/[^a-z0-9]+/g, "");
}

function classify(value) {
  const raw = String(value ?? "").trim().toLowerCase();
  if (!raw) return null;
  if (raw.includes("_no") || /\b(no|thumbs?down|down|negative|dislike)\b/.test(raw)) return "down";
  if (raw.includes("_yes") || /\b(yes|thumbs?up|up|positive|like)\b/.test(raw)) return "up";
  return null;
}

const excelPath = process.argv[2];
const dbPath = process.argv[3] ?? path.join(process.cwd(), "data", "local-db.json");

if (!excelPath) {
  usage();
  process.exit(1);
}

if (!fs.existsSync(excelPath)) {
  console.error(`File not found: ${excelPath}`);
  process.exit(1);
}

if (!fs.existsSync(dbPath)) {
  console.error(`DB not found: ${dbPath}`);
  process.exit(1);
}

const workbook = xlsx.readFile(excelPath);
if (workbook.SheetNames.length === 0) {
  console.error("Workbook has no sheets.");
  process.exit(1);
}

const rows = xlsx.utils.sheet_to_json(workbook.Sheets[workbook.SheetNames[0]], {
  header: 1,
  raw: false,
  defval: "",
});

if (rows.length < 2) {
  console.error("Workbook has no data rows.");
  process.exit(1);
}

const header = rows[0];
const sentEmailIndex = header.findIndex((h) => token(h) === "sentemailname");
const activityIndex = header.findIndex((h) =>
  new Set([
    "multichannelactivitytype",
    "activitytype",
    "multichanneltype",
    "approvedemailaction",
    "otapprovedemailaction",
  ]).has(token(h)),
);

if (sentEmailIndex < 0 || activityIndex < 0) {
  console.error("Required headers not found. Need Sent Email Name + Multichannel Activity Type/Activity Type.");
  process.exit(1);
}

const sentimentMap = new Map();

for (let i = 1; i < rows.length; i += 1) {
  const row = rows[i] ?? [];
  const sentEmailName = String(row[sentEmailIndex] ?? "").trim();
  const activity = row[activityIndex] ?? "";
  if (!sentEmailName) continue;
  const direction = classify(activity);
  if (!direction) continue;

  const current = sentimentMap.get(sentEmailName) ?? { thumbs_up: 0, thumbs_down: 0 };
  if (direction === "up") current.thumbs_up += 1;
  else current.thumbs_down += 1;
  sentimentMap.set(sentEmailName, current);
}

const db = JSON.parse(fs.readFileSync(dbPath, "utf8"));
const existing = Array.isArray(db.email_sentiment) ? db.email_sentiment : [];
const byName = new Map(existing.map((item) => [String(item.sent_email_name ?? "").trim(), item]));
const now = new Date().toISOString();
let inserted = 0;
let updated = 0;

for (const [sentEmailName, counts] of sentimentMap.entries()) {
  const row = byName.get(sentEmailName);
  if (row) {
    row.thumbs_up = counts.thumbs_up;
    row.thumbs_down = counts.thumbs_down;
    row.updated_at = now;
    updated += 1;
  } else {
    existing.push({
      sent_email_name: sentEmailName,
      thumbs_up: counts.thumbs_up,
      thumbs_down: counts.thumbs_down,
      updated_at: now,
    });
    inserted += 1;
  }
}

db.email_sentiment = existing;
fs.writeFileSync(dbPath, JSON.stringify(db, null, 2));

const totals = db.email_sentiment.reduce(
  (acc, item) => {
    acc.up += Number(item.thumbs_up ?? 0);
    acc.down += Number(item.thumbs_down ?? 0);
    return acc;
  },
  { up: 0, down: 0 },
);

console.log(`Processed source rows: ${rows.length - 1}`);
console.log(`Distinct sentiment emails in file: ${sentimentMap.size}`);
console.log(`Inserted: ${inserted}, Updated: ${updated}`);
console.log(`DB email_sentiment rows: ${db.email_sentiment.length}`);
console.log(`DB totals => thumbs_up: ${totals.up}, thumbs_down: ${totals.down}`);
