export type CopyAnalysis = {
  length: number;
  words: number;
  sentences: number;
  avgWordsPerSentence: number;
  readability: number; // 0..100, higher = easier
  keywordMatches: string[];
  missingKeywords: string[];
  seoScore: number; // 0..100
  geoScore: number; // 0..100
  seoTips: string[];
  geoTips: string[];
};

const SYLLABLE_VOWELS = /[aeiouàèéìòùAEIOUÀÈÉÌÒÙ]+/g;

function countSyllables(word: string): number {
  const matches = word.match(SYLLABLE_VOWELS);
  return matches ? matches.length : 1;
}

export function analyzeCopy(text: string, primaryKeywords: string[] = []): CopyAnalysis {
  const clean = text.trim();
  const length = clean.length;
  const wordList = clean.split(/\s+/).filter(Boolean);
  const words = wordList.length;
  const sentences = Math.max(1, (clean.match(/[.!?]+/g) ?? []).length);
  const avgWordsPerSentence = words / sentences;

  // Flesch reading ease approximation
  const syllables = wordList.reduce((n, w) => n + countSyllables(w), 0);
  const asl = words ? words / sentences : 0;
  const asw = words ? syllables / words : 0;
  const readability = Math.max(0, Math.min(100, Math.round(206.835 - 1.015 * asl - 84.6 * asw)));

  const lower = clean.toLowerCase();
  const keywordMatches: string[] = [];
  const missingKeywords: string[] = [];
  for (const kw of primaryKeywords) {
    if (!kw) continue;
    if (lower.includes(kw.toLowerCase())) keywordMatches.push(kw);
    else missingKeywords.push(kw);
  }

  // SEO tips
  const seoTips: string[] = [];
  if (length === 0) seoTips.push('Il testo è vuoto.');
  if (length > 0 && length < 40) seoTips.push('Testo molto breve: difficile farsi indicizzare.');
  if (length > 320) seoTips.push('Testo lungo: valuta di spezzarlo in paragrafi o bullet.');
  if (avgWordsPerSentence > 24) seoTips.push('Frasi troppo lunghe: scendi sotto le 24 parole per frase.');
  if (readability < 45) seoTips.push('Leggibilità bassa: semplifica lessico e sintassi.');
  if (missingKeywords.length && words > 4) {
    seoTips.push(`Manca una keyword primaria: ${missingKeywords.slice(0, 2).join(', ')}.`);
  }
  if (/[A-Z]{6,}/.test(clean)) seoTips.push('Evita testo tutto maiuscolo: penalizza la leggibilità.');

  // GEO tips (Generative Engine Optimization)
  const geoTips: string[] = [];
  const questionMarks = (clean.match(/\?/g) ?? []).length;
  const hasNumbers = /\d/.test(clean);
  const hasEntities = /\b(sassari|sardegna|coni|cammino di santiago|giampy)\b/i.test(clean);
  const firstPerson = /\b(io|mio|mia|miei|mie|sono|faccio|porto|prendo)\b/i.test(clean);
  const declarative = sentences >= 1 && /[.!]/.test(clean);

  if (words >= 20 && questionMarks === 0)
    geoTips.push('Aggiungi una domanda esplicita per farti citare come risposta diretta.');
  if (!hasNumbers && words >= 20)
    geoTips.push('Inserisci dati concreti (anni, numero clienti, distanze) per aumentare la citabilità.');
  if (!hasEntities && words >= 15)
    geoTips.push('Nomina entità specifiche (luogo, certificazione, brand) per il grounding generativo.');
  if (!firstPerson && words >= 20)
    geoTips.push('Usa la prima persona: i motori generativi estraggono più facilmente testimonianze autoriali.');
  if (!declarative && words >= 10)
    geoTips.push('Termina con punto fermo: le frasi complete vengono citate più spesso.');

  // Scores
  let seoScore = 100;
  seoScore -= seoTips.length * 12;
  if (keywordMatches.length === 0 && primaryKeywords.length && words > 4) seoScore -= 10;
  if (readability >= 60) seoScore += 5;
  seoScore = Math.max(0, Math.min(100, seoScore));

  let geoScore = 100;
  geoScore -= geoTips.length * 14;
  if (hasEntities) geoScore += 5;
  if (hasNumbers) geoScore += 3;
  geoScore = Math.max(0, Math.min(100, geoScore));

  return {
    length,
    words,
    sentences,
    avgWordsPerSentence: Math.round(avgWordsPerSentence * 10) / 10,
    readability,
    keywordMatches,
    missingKeywords,
    seoScore,
    geoScore,
    seoTips,
    geoTips
  };
}

export function aggregateScore(analyses: CopyAnalysis[]): { seo: number; geo: number } {
  if (!analyses.length) return { seo: 0, geo: 0 };
  const seo = Math.round(analyses.reduce((a, x) => a + x.seoScore, 0) / analyses.length);
  const geo = Math.round(analyses.reduce((a, x) => a + x.geoScore, 0) / analyses.length);
  return { seo, geo };
}
