const URGENT_KEYS = ['blood', 'blackOrDarkRed', 'severePain', 'vomiting', 'fever', 'cannotPassGas'];
const URGENT_MESSAGE = 'These reported symptoms can need prompt medical care. Contact a clinician or urgent service now; call emergency services for heavy or nonstop bleeding, fainting, or severe worsening symptoms.';
const URGENT_TEXT_PATTERNS = Object.freeze([
  ['blood', /\b(?:rectal bleeding|bleeding from (?:the )?(?:rectum|bottom)|blood(?:y)? (?:in|on|with) (?:my |the )?(?:stool|poop|bowel movement)|(?:stool|poop) (?:has|contains|with) blood)\b/i],
  ['blackOrDarkRed', /\b(?:(?:black|dark[- ]?red) (?:stool|poop|bowel movement)|(?:stool|poop|bowel movement) (?:is|looks?) (?:black|dark[- ]?red))s?\b/i],
  ['severePain', /\b(?:severe|constant|unrelenting) (?:abdominal|stomach|belly) pain\b/i],
  ['vomiting', /\b(?:vomit(?:ing|ed)?|throwing up)\b/i],
  ['fever', /\bfever(?:ish)?\b/i],
  ['cannotPassGas', /\b(?:cannot|can['’]?t|cant|unable to|not able to) pass gas\b/i],
]);

export function bucketForBristolType(type) {
  const value = Number(type);
  if (value === 1 || value === 2) return 'constipation';
  if (value === 3 || value === 4) return 'typical';
  if (value >= 5 && value <= 7) return 'loose';
  return 'unknown';
}

export function detectUrgentFlags(symptoms = {}) {
  const flags = URGENT_KEYS.filter((key) => symptoms[key] === true);
  return {
    urgent: flags.length > 0,
    flags,
    message: flags.length
      ? URGENT_MESSAGE
      : 'No urgent symptom was selected. This tracker is not a diagnosis; seek care whenever you are worried or symptoms persist.',
  };
}

export function detectUrgentText(text = '') {
  const flags = URGENT_TEXT_PATTERNS.filter(([, pattern]) => pattern.test(String(text))).map(([key]) => key);
  return { urgent: flags.length > 0, flags, message: flags.length ? URGENT_MESSAGE : '' };
}

export function hasUrgentLedgerContext(entries = []) {
  return Array.isArray(entries) && entries.some(entry => detectUrgentFlags(entry?.symptoms).urgent || detectUrgentText(entry?.note).urgent);
}

export const urgentChatMessage = `Pause and get medical help. ${URGENT_MESSAGE}`;

export function buildTimmySummary(entries = []) {
  if (!entries.length) return 'No logs yet. Add one when you are ready and I’ll summarize the pattern—not diagnose it.';
  const counts = entries.reduce((acc, entry) => {
    const bucket = bucketForBristolType(entry.bristolType);
    acc[bucket] = (acc[bucket] || 0) + 1;
    return acc;
  }, {});
  const pieces = [`${entries.length} ${entries.length === 1 ? 'log' : 'logs'}`];
  if (counts.typical) pieces.push(`${counts.typical} typical`);
  if (counts.constipation) pieces.push(`${counts.constipation} on the firm side`);
  if (counts.loose) pieces.push(`${counts.loose} on the loose side`);
  return `${pieces.join(' · ')}. Patterns matter more than one entry. You choose what to eat; I only help you notice changes.`;
}

export function sanitizeEntry(input = {}) {
  const symptoms = {};
  for (const key of URGENT_KEYS) symptoms[key] = input.symptoms?.[key] === true;
  const bristolType = Math.min(7, Math.max(1, Number(input.bristolType) || 4));
  return {
    id: String(input.id || globalThis.crypto?.randomUUID?.() || `${Date.now()}-${Math.random()}`),
    occurredAt: new Date(input.occurredAt || Date.now()).toISOString(),
    bristolType,
    color: ['brown', 'green', 'yellow', 'pale', 'red', 'black'].includes(input.color) ? input.color : 'brown',
    urgency: Math.min(4, Math.max(0, Number(input.urgency) || 0)),
    discomfort: Math.min(4, Math.max(0, Number(input.discomfort) || 0)),
    note: String(input.note || '').trim().slice(0, 500),
    photoDataUrl: typeof input.photoDataUrl === 'string' && input.photoDataUrl.startsWith('data:image/') ? input.photoDataUrl : '',
    symptoms,
  };
}

export function photoQualityMessage({ width = 0, height = 0, brightness = 0.5 } = {}) {
  if (width < 640 || height < 480) return 'Move a little closer or use a higher-resolution photo. The image stays on this device.';
  if (brightness < 0.12) return 'Add more light before saving. Timmy only checks whether the photo is usable.';
  if (brightness > 0.95) return 'Reduce glare before saving. Timmy only checks whether the photo is usable.';
  return 'Ready for your review. Choose the matching Bristol form yourself; Timmy does not interpret the picture.';
}

export function exportLedger(entries, exportedAt = new Date().toISOString()) {
  return JSON.stringify({
    product: 'Timmy the Talking Turd',
    schemaVersion: 1,
    exportedAt,
    entries: Array.isArray(entries) ? entries : [],
  }, null, 2);
}

export function importLedger(text) {
  const parsed = JSON.parse(text);
  if (parsed?.schemaVersion !== 1 || !Array.isArray(parsed.entries)) throw new Error('This is not a supported Timmy export.');
  return parsed.entries.map(sanitizeEntry);
}

export const urgentSymptomKeys = Object.freeze([...URGENT_KEYS]);
