/**
 * F-136 — Brand names Title Case + SEO title backfill.
 *
 * Brands imported from OpenCart in F-114 are ALL-CAPS (e.g. "A.VOGEL",
 * "BIOCOP", "COMPLEMENTOS Y NUTRICIÓN") and have `seo_title IS NULL`. The
 * admin form auto-fills `seo_title` from `name` on create, but existing
 * rows need to be normalized.
 *
 * This migration:
 *  - Title-cases ALL-CAPS brand names ("A.VOGEL" → "A.Vogel",
 *    "COMPLEMENTOS Y NUTRICIÓN" → "Complementos y Nutrición").
 *  - Backfills `seo_title` from the (now Title-Cased) name where the
 *    column is NULL or empty.
 *  - Does NOT touch slugs (they are already lowercase, derived via
 *    `slugify()` from the original ALL-CAPS name).
 *  - Does NOT touch mixed-case names like "BioSana" (idempotency).
 *
 * Idempotency:
 *  - Re-running on an already-Title-Cased row is a no-op because
 *    `toTitleCase()` returns the input unchanged when it is not all-caps.
 *  - We only issue an UPDATE if either the name actually changes or the
 *    `seo_title` was empty, so `updated_at` is not bumped unnecessarily.
 *
 * Note: the `toTitleCase` logic is inlined here (rather than imported
 * from `src/shared/text.ts`) so the migration is self-contained and does
 * not require `npm run build` to run first. The shared helper is the
 * single source of truth for the future; this inline copy is kept in
 * sync via the vitest unit tests in `src/shared/tests/text.test.ts`.
 *
 * @param {import('node-pg-migrate').MigrationBuilder} pgm
 */

/**
 * Mirror of `toTitleCase` in `project/src/shared/text.ts`.
 *
 * Convert an ALL-CAPS brand/category name to Title Case. Splits on word
 * boundaries (space, hyphen, dot, ampersand, slash), capitalizes the
 * first letter of each word, lowercases the rest. Preserves Spanish
 * single-letter conjunctions (y/e/o/u) in lowercase when they are not
 * the first word. Returns mixed-case strings unchanged.
 *
 * Keep this in sync with `src/shared/text.ts` — the vitest tests cover
 * the behaviour and would catch any drift.
 */
function toTitleCase(input) {
  if (!input) return input;
  if (input !== input.toUpperCase() || input === input.toLowerCase()) {
    return input;
  }
  const LOWERCASE_WORDS = new Set(['y', 'e', 'o', 'u']);
  const parts = input.split(/([\s.\-/&]+)/g);
  let isFirstWord = true;
  return parts
    .map((part) => {
      if (/^[\s.\-/&]+$/.test(part)) return part;
      if (part.length === 0) return part;
      const lower = part.toLocaleLowerCase('es-ES');
      if (!isFirstWord && LOWERCASE_WORDS.has(lower)) return lower;
      isFirstWord = false;
      return (
        part.charAt(0).toLocaleUpperCase('es-ES') +
        part.slice(1).toLocaleLowerCase('es-ES')
      );
    })
    .join('');
}

/** True iff `value` is null, undefined, or empty string. */
function isBlank(value) {
  return value === null || value === undefined || value === '';
}

export const up = async (pgm) => {
  const rows = await pgm.db.select(
    'SELECT id, name, seo_title FROM brands_brands',
  );

  let updated = 0;
  for (const row of rows) {
    const titleCased = toTitleCase(row.name);
    const newSeoTitle = isBlank(row.seo_title) ? titleCased : row.seo_title;
    const nameChanged = titleCased !== row.name;
    const seoChanged = newSeoTitle !== row.seo_title;
    if (!nameChanged && !seoChanged) continue;
    await pgm.db.query(
      `UPDATE brands_brands
         SET name = $1,
             seo_title = $2,
             updated_at = NOW()
       WHERE id = $3`,
      [titleCased, newSeoTitle, row.id],
    );
    updated += 1;
  }
  console.log(`F-136: updated ${updated} brand row(s) (of ${rows.length} total)`);
};

export const down = async () => {
  // Destructive data migration — no automatic rollback. The previous
  // names (ALL CAPS) are not recoverable from this migration alone.
};
