// DSAlert.jsx — Meridian alert / disclaimer / crisis components
//
// Three composable pieces, all sharing one tonal system:
//
//   DSAlert             — title + body + optional inline actions, 4 tones
//   DSCrisisCard        — fixed safety crisis-deflection card (§21)
//   DSMedicalDisclaimer — persistent footer, 3 lengths (compact / default / long)
//
// Tones (DSAlert):
//   info     — neutral informational, axisSoft fill / axisDark text
//   success  — positive confirmation, soft-green fill / deep-green text
//   warn     — educational / disclaimer, warningFill / warningInk
//   crisis   — safety / urgency, crisisFill / crisisInk
//
// Compact mode flattens corners + tightens padding/type for sticky bars
// (e.g. above the chat composer).

// ── Tone definitions ─────────────────────────────────────────────
const DSAlert_TONES = {
  info: {
    bg: M.axisSoft,
    border: 'transparent',
    badge: M.axis,
    badgeLabel: 'i',
    title: M.axisDark,
    body: M.axisDark,
  },
  success: {
    bg: '#EBF3EE',
    border: '#C5DCB5',
    badge: M.success,
    badgeLabel: '✓',
    title: '#1E5A41',
    body: '#1E5A41',
  },
  warn: {
    bg: '#FFFBEB',
    border: '#F2DFA4',
    badge: M.warning,
    badgeLabel: 'i',
    title: '#5A4410',
    body: '#5A4410',
  },
  crisis: {
    bg: '#FFF2F2',
    border: 'rgba(180, 42, 42, 0.20)',
    badge: M.crisis,
    badgeLabel: '!',
    title: '#5A1A1A',
    body: '#5A1A1A',
  },
};

// ── DSAlert ──────────────────────────────────────────────────────
function DSAlert({
  tone = 'warn',
  title,
  body,
  actions,        // [{ label, variant?, onClick }] — rendered as inline buttons
  compact = false,
  style,
  children,       // alternative to `body` prop for rich content
}) {
  const t = DSAlert_TONES[tone] || DSAlert_TONES.warn;
  const radius = compact ? 0 : 10;
  const padding = compact ? '8px 14px' : '12px 14px';
  const badgeSize = compact ? 14 : 18;
  const titleSize = compact ? 12 : 14;
  const bodySize = compact ? 11 : 13;

  return (
    <div role="status" style={{
      display: 'flex',
      gap: 10,
      padding,
      background: t.bg,
      border: `1px solid ${t.border}`,
      borderRadius: radius,
      alignItems: 'flex-start',
      ...style,
    }}>
      <div aria-hidden="true" style={{
        width: badgeSize, height: badgeSize,
        flexShrink: 0,
        borderRadius: 999,
        background: t.badge,
        color: '#fff',
        display: 'flex',
        alignItems: 'center',
        justifyContent: 'center',
        font: `600 ${compact ? 9 : 11}px/1 ${M.sans}`,
        marginTop: 2,
      }}>{t.badgeLabel}</div>

      <div style={{ flex: 1, minWidth: 0 }}>
        {title && (
          <div style={{
            font: `500 ${titleSize}px/1.3 ${M.sans}`,
            color: t.title,
            marginBottom: (body || children) ? 4 : 0,
          }}>{title}</div>
        )}
        {body && (
          <div style={{
            font: `400 ${bodySize}px/1.5 ${M.sans}`,
            color: t.body,
            whiteSpace: 'pre-line',
          }}>{body}</div>
        )}
        {children}
        {actions && actions.length > 0 && (
          <div style={{ display: 'flex', gap: 8, marginTop: 10, flexWrap: 'wrap' }}>
            {actions.map((a, i) => (
              <DSButton
                key={i}
                size="sm"
                variant={a.variant || (i === 0 ? 'primary' : 'secondary')}
                onClick={a.onClick}
                style={{ borderRadius: 8, padding: '6px 10px', fontSize: 12 }}
              >{a.label}</DSButton>
            ))}
          </div>
        )}
      </div>
    </div>
  );
}

// ── DSCrisisCard ─────────────────────────────────────────────────
// The §21 safety crisis-deflection card. Shown when the assistant
// detects acute distress in user input; never auto-dismissed by Axis,
// always requires the user to dismiss (or call the line).
//
// Defaults to the US 988 lifeline; pass `helpline` to localize.
function DSCrisisCard({
  helpline,        // { label, number, url } — overrides the default
  onDismiss,
  dismissLabel = 'Got it',
  callLabel = 'Call',
}) {
  const line = helpline ?? {
    label: 'Suicide & Crisis Lifeline',
    number: '988',
    url: 'https://988lifeline.org',
  };

  return (
    <DSAlert
      tone="crisis"
      title="If you need support right now"
    >
      <div style={{
        font: `400 13px/1.5 ${M.sans}`,
        color: '#5A1A1A',
      }}>
        A trained counsellor is available 24/7. In the US:{' '}
        <a href={`tel:${line.number}`} style={{
          color: M.crisis, fontWeight: 500, textDecoration: 'none',
        }}>{line.number}</a>
        {' · '}
        <a href={line.url} target="_blank" rel="noreferrer noopener" style={{
          color: M.crisis, textDecoration: 'underline', textUnderlineOffset: 2,
        }}>{line.url.replace(/^https?:\/\//, '')}</a>
      </div>
      <div style={{ display: 'flex', gap: 8, marginTop: 12, flexWrap: 'wrap' }}>
        <DSButton
          size="sm"
          variant="danger"
          onClick={() => { window.location.href = `tel:${line.number}`; }}
          style={{ borderRadius: 8, padding: '6px 10px', fontSize: 12 }}
        >{callLabel} {line.number}</DSButton>
        <DSButton
          size="sm"
          variant="secondary"
          onClick={onDismiss}
          style={{ borderRadius: 8, padding: '6px 10px', fontSize: 12 }}
        >{dismissLabel}</DSButton>
      </div>
    </DSAlert>
  );
}

// ── DSMedicalDisclaimer ──────────────────────────────────────────
// Persistent footer used at the bottom of every long-scroll surface
// (Today, Recap detail, Parameter views, Journaling) — and as a
// full-length panel on the dedicated Settings → Legal & disclaimers
// screen. Sits inline at the bottom of the scroll container; never
// a card, never blocking.
//
// Props:
//   length        'short' | 'long'   default 'short'
//     short  — one-line muted footer, every long-scroll surface
//     long   — multi-paragraph panel for Settings → Legal
//   dismissible   boolean            default false
//     true   — render a small × that hides the disclaimer for the
//              current mount only (does NOT persist). Reserved for
//              one-off contexts; the default footer placement does
//              NOT enable this.
//
// Visual contract:
//   - Caption-tier type at M.inkMuted (matches DSAlert info contrast).
//   - Hairline (1px M.rule) separator above the text. No surrounding card.
//   - No icon by default (consumers can override with the same DSAlert
//     'info' badge if a particular surface needs the glyph).
//   - Reduced-motion: nothing animates on appear / disappear regardless.
//
// Legacy:
//   The old API took length: 'compact' | 'default' | 'long'. Those values
//   still work — 'compact' renders the warn-tone sticky bar used above
//   the chat composer; 'default' renders the warn-tone card used inside
//   sheets. They route through DSAlert and are unchanged. The new
//   'short' value is the footer redesign described above.

const DSMedicalDisclaimer_TEXTS = {
  // ── new API ────────────────────────────────────────────────────
  short: 'Axis is not a medical device. Information shown here is not a substitute for professional medical advice.',
  longTitle: 'About this disclaimer',
  longParagraphs: [
    'Axis is not a medical device. Information shown here is not a substitute for professional medical advice, diagnosis, or treatment.',
    'Axis surfaces patterns from the data you choose to share — manual logs, voice notes, connected platforms (Apple Health, Oura), and documents you upload. These signals can be incomplete, miscategorised, or wrong. Treat every insight as a starting point for a conversation, not a conclusion.',
    'Always consult a qualified clinician before changing medication, starting a new treatment, or acting on anything you read here. If a symptom is new, persistent, or worsening, your GP or specialist is the right next step — not Axis.',
    'Axis is not an emergency service. If you are in immediate danger or experiencing a medical emergency, call your local emergency number (911 in the US, 999 in the UK, 112 across the EU). For mental-health crisis support in the US, the 988 Suicide & Crisis Lifeline is available 24/7.',
  ],
  // ── legacy API (kept verbatim) ─────────────────────────────────
  compact: 'Axis is not a medical service. Educational only — consult your clinician.',
  default: 'Axis is not a medical service. Information shown is personal and educational only — always consult a clinician for diagnosis or treatment.',
  long: [
    'Axis is not a medical service. Information shown is personal and educational only — always consult a clinician for diagnosis or treatment.',
    'To surface patterns, Axis processes the entries, voice notes, and documents you share using AI models. Extracted values are stored in your encrypted Profile Graph; raw inputs (audio, document images) are retained for 30 days, then deleted. You can review or delete any extracted entry from Settings → Data.',
    'Axis never sells your data, never shares it with insurers, and never uses it to train third-party models.',
  ].join('\n\n'),
};

function DSMedicalDisclaimer({ length = 'short', dismissible = false, title, style }) {
  const [dismissed, setDismissed] = React.useState(false);

  // ── Legacy passthrough ───────────────────────────────────────
  // 'compact' and 'default' continue to render the warn-tone DSAlert.
  if (length === 'compact' || length === 'default') {
    if (dismissed) return null;
    const isCompact = length === 'compact';
    return (
      <DSAlert
        tone="warn"
        title={title}
        body={DSMedicalDisclaimer_TEXTS[length]}
        compact={isCompact}
        style={style}
      />
    );
  }

  if (dismissed) return null;

  const isLong = length === 'long';

  // ── Shared chrome: hairline + muted type ─────────────────────
  const containerStyle = {
    display: 'flex',
    alignItems: 'flex-start',
    gap: 12,
    padding: isLong ? '20px 0 4px' : '16px 0 4px',
    borderTop: `1px solid ${M.rule}`,
    ...style,
  };

  // Long: multi-paragraph panel, full width, optional heading.
  if (isLong) {
    return (
      <section
        role="region"
        aria-label="Medical disclaimer"
        style={containerStyle}
      >
        <div style={{ flex: 1, minWidth: 0 }}>
          <div style={{
            font: `500 13px/1.3 ${M.sans}`,
            color: M.inkSoft,
            letterSpacing: '-0.005em',
            marginBottom: 10,
          }}>{title || DSMedicalDisclaimer_TEXTS.longTitle}</div>
          <div style={{
            display: 'flex',
            flexDirection: 'column',
            gap: 10,
          }}>
            {DSMedicalDisclaimer_TEXTS.longParagraphs.map((p, i) => (
              <p key={i} style={{
                margin: 0,
                font: `400 13px/1.55 ${M.sans}`,
                color: M.inkMuted,
                textWrap: 'pretty',
              }}>{p}</p>
            ))}
          </div>
        </div>
        {dismissible && (
          <DSMedicalDisclaimer_Dismiss onClick={() => setDismissed(true)} />
        )}
      </section>
    );
  }

  // Short: single muted line, hairline above.
  return (
    <div
      role="note"
      aria-label="Medical disclaimer"
      style={containerStyle}
    >
      <p style={{
        flex: 1, minWidth: 0,
        margin: 0,
        font: `400 12px/1.5 ${M.sans}`,
        color: M.inkMuted,
        textWrap: 'pretty',
      }}>{DSMedicalDisclaimer_TEXTS.short}</p>
      {dismissible && (
        <DSMedicalDisclaimer_Dismiss onClick={() => setDismissed(true)} />
      )}
    </div>
  );
}

// Small × affordance used only when dismissible=true. Matches the
// muted contrast of the disclaimer it sits next to (no high-contrast
// pop, no fill — the dismiss action is incidental, not the point).
function DSMedicalDisclaimer_Dismiss({ onClick }) {
  return (
    <button
      type="button"
      aria-label="Hide disclaimer"
      onClick={onClick}
      style={{
        all: 'unset',
        flexShrink: 0,
        cursor: 'pointer',
        width: 24, height: 24,
        marginTop: -2,
        display: 'inline-flex',
        alignItems: 'center',
        justifyContent: 'center',
        color: M.inkFaint,
        borderRadius: 999,
      }}
      onMouseEnter={(e)=>{ e.currentTarget.style.color = M.inkMuted; }}
      onMouseLeave={(e)=>{ e.currentTarget.style.color = M.inkFaint; }}
    >
      <svg width="14" height="14" viewBox="0 0 24 24" fill="none"
           stroke="currentColor" strokeWidth="2.2"
           strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
        <path d="M6 6l12 12M6 18L18 6" />
      </svg>
    </button>
  );
}

Object.assign(window, {
  DSAlert, DSCrisisCard, DSMedicalDisclaimer,
  DSAlert_TONES, DSMedicalDisclaimer_TEXTS,
});
