const clamp = (value, min, max) => {
  return Math.min(max, Math.max(min, value));
};

const normalizeText = (value) => {
  return String(value || '')
    .toLowerCase()
    .normalize('NFD')
    .replace(/[\u0300-\u036f]/g, '')
    .replace(/\s+/g, ' ')
    .trim();
};

const GERMAN_COMMON_NAME_HINTS = [
  'weihnachtsstern',
  'weinachtsstern',
  'einblatt',
  'fensterblatt',
  'korbmarante',
  'glucksfeder',
  'gluecksfeder',
  'efeutute',
  'drachenbaum',
  'gummibaum',
  'geigenfeige',
  'bogenhanf',
  'yucca palme',
  'gluckskastanie',
  'glueckskastanie',
];

const isLikelyGermanCommonName = (value) => {
  const raw = String(value || '').trim();
  if (!raw) return false;
  if (/[äöüß]/i.test(raw)) return true;

  const normalized = normalizeText(raw).replace(/[^a-z0-9 ]+/g, ' ');
  if (!normalized) return false;
  if (/\b(der|die|das|ein|eine)\b/.test(normalized)) return true;

  return GERMAN_COMMON_NAME_HINTS.some((hint) => normalized.includes(hint));
};

const isLikelyBotanicalName = (value, botanicalName) => {
  const raw = String(value || '').trim();
  const botanicalRaw = String(botanicalName || '').trim();
  if (!raw) return false;

  if (normalizeText(raw) === normalizeText(botanicalRaw)) return true;

  return /^[A-Z][a-z-]+(?:\s[a-z.-]+){1,2}$/.test(raw);
};

const findCatalogMatch = (aiResult, entries) => {
  if (!aiResult || !Array.isArray(entries) || entries.length === 0) return null;
  const aiBotanical = normalizeText(aiResult.botanicalName);
  const aiName = normalizeText(aiResult.name);
  if (!aiBotanical && !aiName) return null;

  const byExactBotanical = entries.find((entry) => normalizeText(entry.botanicalName) === aiBotanical);
  if (byExactBotanical) return byExactBotanical;

  const byExactName = entries.find((entry) => normalizeText(entry.name) === aiName);
  if (byExactName) return byExactName;

  if (aiBotanical) {
    const aiGenus = aiBotanical.split(' ')[0];
    if (aiGenus) {
      const byGenus = entries.find((entry) => normalizeText(entry.botanicalName).startsWith(`${aiGenus} `));
      if (byGenus) return byGenus;
    }
  }

  const byContains = entries.find((entry) => {
    const plantName = normalizeText(entry.name);
    const botanical = normalizeText(entry.botanicalName);
    return (aiName && (plantName.includes(aiName) || aiName.includes(plantName)))
      || (aiBotanical && (botanical.includes(aiBotanical) || aiBotanical.includes(botanical)));
  });
  if (byContains) return byContains;

  return null;
};

const shouldUseCatalogNameOverride = ({ language, aiResult, matchedEntry }) => {
  const catalogName = String(matchedEntry?.name || '').trim();
  if (!catalogName) return false;
  if (language !== 'en') return true;

  if (isLikelyBotanicalName(catalogName, matchedEntry?.botanicalName || aiResult?.botanicalName)) {
    return true;
  }

  if (isLikelyGermanCommonName(catalogName)) {
    return false;
  }

  return true;
};

const applyCatalogGrounding = (aiResult, catalogEntries, language = 'en') => {
  const matchedEntry = findCatalogMatch(aiResult, catalogEntries);
  if (!matchedEntry) {
    return { grounded: false, result: aiResult };
  }

  const useCatalogName = shouldUseCatalogNameOverride({ language, aiResult, matchedEntry });

  return {
    grounded: true,
    result: {
      name: useCatalogName ? matchedEntry.name || aiResult.name : aiResult.name,
      botanicalName: matchedEntry.botanicalName || aiResult.botanicalName,
      confidence: clamp(Math.max(aiResult.confidence || 0.6, 0.78), 0.05, 0.99),
      description: aiResult.description || matchedEntry.description || '',
      careInfo: {
        waterIntervalDays: Math.max(1, Number(matchedEntry.careInfo?.waterIntervalDays) || Number(aiResult.careInfo?.waterIntervalDays) || 7),
        light: matchedEntry.careInfo?.light || aiResult.careInfo?.light || 'Unknown',
        temp: matchedEntry.careInfo?.temp || aiResult.careInfo?.temp || 'Unknown',
      },
    },
  };
};

module.exports = {
  applyCatalogGrounding,
  findCatalogMatch,
  isLikelyGermanCommonName,
  normalizeText,
  shouldUseCatalogNameOverride,
};
