#!/usr/bin/env node
// Personalization score calculator for linkedin-studio plugin
// Checks 8 asset categories for real user data vs placeholder templates.
// Instance data is read from the EXTERNAL data root (getDataRoot, M0); the plugin
// tree is a back-compat fallback during the migration window (external wins).
// Standalone: outputs SCORE:N|M/8 assets personalized
// Import: export function calculateScore(pluginRoot) => { score, personalized, categories }

import { readFileSync, existsSync, readdirSync } from 'node:fs';
import { join, dirname } from 'node:path';
import { fileURLToPath } from 'node:url';
import { getDataRoot } from './data-root.mjs';
import { MOVE_FILES, COPY_FILES } from './migrate-data.mjs';

const __dirname = dirname(fileURLToPath(import.meta.url));

// Mirror the migration's external dests (single source of truth) so the scorer
// reads exactly where migrate-data.mjs writes — never a drifted path
// (migrate-data.mjs:13-16, STATE.md M0). Keyed by in-plugin source path.
const DEST = Object.fromEntries([...MOVE_FILES, ...COPY_FILES].map(([src, dest]) => [src, dest]));

export function calculateScore(pluginRoot) {
  const dataRoot = getDataRoot();
  let score = 0;
  let personalized = 0;
  const categories = 8;

  // Instance lives in the external root; fall back to the plugin tree for
  // back-compat during the migration window. External wins when present.
  const pick = (dataRel, pluginRel) => {
    const dataPath = join(dataRoot, dataRel);
    return existsSync(dataPath) ? dataPath : join(pluginRoot, pluginRel);
  };

  // --- 1. Voice samples (25 points) ---
  // The shipped file is a PII-free placeholder carrying the VOICE_PLACEHOLDER
  // sentinel. Key detection on the sentinel (deterministic): a populated profile
  // removes it and earns the points; the placeholder (or any file still carrying
  // it) scores 0.
  const voiceFile = pick(
    DEST['assets/voice-samples/authentic-voice-samples.local.md'],
    join('assets', 'voice-samples', 'authentic-voice-samples.md'),
  );
  if (existsSync(voiceFile)) {
    const content = readFileSync(voiceFile, 'utf-8');
    const lineCount = content.split('\n').length;
    if (lineCount > 50 && !content.includes('<!-- VOICE_PLACEHOLDER -->')) {
      score += 25;
      personalized += 1;
    }
  }

  // --- 2. User profile (20 points) ---
  const profileFile = pick(
    DEST['config/user-profile.local.md'],
    join('config', 'user-profile.local.md'),
  );
  if (existsSync(profileFile)) {
    const content = readFileSync(profileFile, 'utf-8');
    const placeholderCount = (content.match(/\[Your /g) || []).length;
    if (placeholderCount < 3) {
      score += 20;
      personalized += 1;
    }
  }

  // --- 3. Case studies (15 points) --- dir; not in the move tables (migrated
  // per-file) → brief-7.1 convention: external dest = in-plugin path minus assets/.
  const caseDir = pick('case-studies', join('assets', 'case-studies'));
  if (existsSync(caseDir)) {
    let realCases = 0;
    try {
      for (const f of readdirSync(caseDir)) {
        if (!f.endsWith('.md')) continue;
        if (f === 'case-study-template.md') continue;
        realCases++;
      }
    } catch { /* ignore */ }
    if (realCases >= 2) { score += 15; personalized += 1; }
    else if (realCases >= 1) { score += 8; }
  }

  // --- 4. Frameworks (10 points) ---
  const fwDir = pick('frameworks', join('assets', 'frameworks'));
  if (existsSync(fwDir)) {
    let realFw = 0;
    try {
      for (const f of readdirSync(fwDir)) {
        if (!f.endsWith('.md')) continue;
        if (f === 'framework-template.md') continue;
        realFw++;
      }
    } catch { /* ignore */ }
    if (realFw >= 2) { score += 10; personalized += 1; }
    else if (realFw >= 1) { score += 5; }
  }

  // --- 5. High-engagement posts (10 points) ---
  const postsFile = pick(
    DEST['assets/examples/high-engagement-posts.md'],
    join('assets', 'examples', 'high-engagement-posts.md'),
  );
  if (existsSync(postsFile)) {
    const content = readFileSync(postsFile, 'utf-8');
    const postCount = (content.match(/^## Post [0-9]/gm) || []).length;
    if (postCount >= 3) { score += 10; personalized += 1; }
    else if (postCount >= 1) { score += 4; }
  }

  // --- 6. Demographics (8 points) ---
  const demoFile = pick(
    DEST['assets/audience-insights/demographics.md'],
    join('assets', 'audience-insights', 'demographics.md'),
  );
  if (existsSync(demoFile)) {
    const content = readFileSync(demoFile, 'utf-8');
    const placeholderCount = (content.match(/\[Industry name\]|\[Function\]|\[Country\]|\[X\]%/g) || []).length;
    if (placeholderCount < 5) {
      score += 8;
      personalized += 1;
    }
  }

  // --- 7. Engagement patterns (7 points) ---
  const patternsFile = pick(
    DEST['assets/audience-insights/engagement-patterns.md'],
    join('assets', 'audience-insights', 'engagement-patterns.md'),
  );
  if (existsSync(patternsFile)) {
    const content = readFileSync(patternsFile, 'utf-8');
    const placeholderCount = (content.match(/\[Day\]|\[Time\]|\[Topic\]|\[Format\]|\[Hook type\]/g) || []).length;
    if (placeholderCount < 5) {
      score += 7;
      personalized += 1;
    }
  }

  // --- 8. Post templates (5 points) ---
  const templatesFile = pick(
    DEST['assets/templates/my-post-templates.md'],
    join('assets', 'templates', 'my-post-templates.md'),
  );
  if (existsSync(templatesFile)) {
    const content = readFileSync(templatesFile, 'utf-8');
    const unfilled = (content.match(/\[Name - e\.g\./g) || []).length;
    const totalTemplates = (content.match(/^## Template [0-9]/gm) || []).length;
    const filled = totalTemplates - unfilled;
    if (filled >= 2) { score += 5; personalized += 1; }
    else if (filled >= 1) { score += 2; }
  }

  return { score, personalized, categories };
}

// Standalone execution (guarded to prevent stdout contamination on import)
if (process.argv[1] === fileURLToPath(import.meta.url)) {
  const pluginRoot = join(__dirname, '..', '..');
  const { score, personalized, categories } = calculateScore(pluginRoot);
  process.stdout.write(`SCORE:${score}|${personalized}/${categories} assets personalized\n`);
}
