/**
 * Migration: normalize legacy dosage unit values to current DosageUnit enum.
 *
 * Known renames:
 *   pill  → tablet
 *   pills → tablet
 *
 * Collections updated:
 *   medicineproducts   packageUnit
 *   cabinetitems       unit
 *   regimens           medications[].dosageUnit
 *   refillists         items[].unit
 */
import mongoose from 'mongoose';

const MONGODB_URI =
  process.env.SEED_MONGODB_URI ||
  process.env.MONGODB_URI ||
  'mongodb://meshitrack:devpassword@localhost:27017/meshitrack?authSource=admin&replicaSet=rs0';

const UNIT_MAP: Record<string, string> = {
  pill: 'tablet',
  pills: 'tablet',
};

async function migrate() {
  console.log('Connecting...');
  await mongoose.connect(MONGODB_URI);
  const db = mongoose.connection.db!;

  let total = 0;

  // --- medicineproducts.packageUnit ---
  for (const [old, next] of Object.entries(UNIT_MAP)) {
    const result = await db
      .collection('medicineproducts')
      .updateMany({ packageUnit: old }, { $set: { packageUnit: next } });
    if (result.modifiedCount > 0) {
      console.log(`medicineproducts.packageUnit: ${old} → ${next}  (${result.modifiedCount})`);
      total += result.modifiedCount;
    }
  }

  // --- cabinetitems.unit ---
  for (const [old, next] of Object.entries(UNIT_MAP)) {
    const result = await db
      .collection('cabinetitems')
      .updateMany({ unit: old }, { $set: { unit: next } });
    if (result.modifiedCount > 0) {
      console.log(`cabinetitems.unit: ${old} → ${next}  (${result.modifiedCount})`);
      total += result.modifiedCount;
    }
  }

  // --- regimens: medications[].dosageUnit ---
  // MongoDB cannot target a specific array element value with updateMany + $set on nested
  // fields matching a condition, so we load and rewrite affected documents.
  const regimens = await db.collection('regimens').find({}).toArray();
  for (const regimen of regimens) {
    const medications: Array<Record<string, unknown>> = regimen.medications ?? [];
    let dirty = false;
    for (const med of medications) {
      const mapped = UNIT_MAP[med.dosageUnit as string];
      if (mapped) {
        med.dosageUnit = mapped;
        dirty = true;
      }
    }
    if (dirty) {
      await db.collection('regimens').updateOne({ _id: regimen._id }, { $set: { medications } });
      console.log(`regimens: updated medications in regimen ${regimen._id}`);
      total++;
    }
  }

  // --- refillists: items[].unit ---
  const refillLists = await db.collection('refillists').find({}).toArray();
  for (const list of refillLists) {
    const items: Array<Record<string, unknown>> = list.items ?? [];
    let dirty = false;
    for (const item of items) {
      const mapped = UNIT_MAP[item.unit as string];
      if (mapped) {
        item.unit = mapped;
        dirty = true;
      }
    }
    if (dirty) {
      await db.collection('refillists').updateOne({ _id: list._id }, { $set: { items } });
      console.log(`refillists: updated items in list ${list._id}`);
      total++;
    }
  }

  console.log('');
  console.log(`Migration complete. ${total} document(s) updated.`);
  await mongoose.disconnect();
}

migrate().catch((err) => {
  console.error('Migration failed:', err);
  process.exit(1);
});
