import React, { useEffect, useRef, useState } from 'react';
import { useInbox } from '../store.js';
import { inboxApi } from '../api.js';
import { Banner } from './Banner.js';

export function RecallBanner(): React.ReactElement | null {
  const candidate = useInbox((s) => s.recallCandidate);
  const snoozeUntilMs = useInbox((s) => s.recallSnoozeUntilMs);
  const openRecall = useInbox((s) => s.openRecall);
  const dismissRecallNote = useInbox((s) => s.dismissRecallNote);
  const snoozeRecall = useInbox((s) => s.snoozeRecall);

  // i1 fix — shownIds 를 useRef 로 관리해 race 차단 (setState 트리거 X)
  // 같은 RecallBanner 컴포넌트 인스턴스 동안 per-noteId 1회 emit 보장.
  // 컴포넌트 언마운트/리마운트 시 reset (session-local 의도).
  const shownIdsRef = useRef<Set<string>>(new Set());

  // ExpiryBanner 패턴 — snoozeUntilMs 만료 시 force re-render
  const [, setTick] = useState(0);
  useEffect(() => {
    if (snoozeUntilMs === null) return;
    const remaining = snoozeUntilMs - Date.now();
    if (remaining <= 0) return;
    const t = setTimeout(() => setTick((n) => n + 1), remaining);
    return () => clearTimeout(t);
  }, [snoozeUntilMs]);

  // first-render emit recall_shown (per-banner-lifetime 1회 per note)
  useEffect(() => {
    if (!candidate) return;
    if (snoozeUntilMs !== null && Date.now() < snoozeUntilMs) return;
    if (shownIdsRef.current.has(candidate.id)) return;
    void inboxApi.emitRecallShown(candidate.id);
    shownIdsRef.current.add(candidate.id);
  }, [candidate, snoozeUntilMs]);

  if (candidate === null) return null;
  if (snoozeUntilMs !== null && Date.now() < snoozeUntilMs) return null;

  const ageDays = computeAgeDays(candidate.lastRecalledAt ?? candidate.createdAt);
  // m4 fix — rawText 와 aiTitle 모두 비었을 때 빈 제목 방지
  const title = candidate.aiTitle?.trim() || candidate.rawText.trim().slice(0, 60) || '(제목 없음)';

  function onOpen() {
    void openRecall(candidate!.id);
    const el = document.getElementById(`note-${candidate!.id}`);
    if (el) el.scrollIntoView({ behavior: 'smooth', block: 'center' });
  }

  return (
    <Banner severity="info">
      <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
        <span>💭 <b>오늘 회상해볼 노트</b></span>
        <span style={{ flex: 1, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap', color: '#234' }}>
          {title}
        </span>
        <span style={{ color: '#6a7e9a', fontSize: 12 }}>{ageDays}일 전</span>
      </div>
      <div style={{ display: 'flex', gap: 6, marginTop: 8 }}>
        <button
          onClick={onOpen}
          style={{
            background: '#4a7ec0', color: '#fff',
            border: 'none', borderRadius: 4,
            padding: '4px 12px', fontSize: 12, cursor: 'pointer'
          }}
        >
          열어보기
        </button>
        <button
          onClick={() => void snoozeRecall()}
          style={{
            background: 'transparent', color: '#4a7ec0',
            border: '1px solid #4a7ec0', borderRadius: 4,
            padding: '4px 12px', fontSize: 12, cursor: 'pointer'
          }}
        >
          다음에
        </button>
        <button
          onClick={() => void dismissRecallNote(candidate.id)}
          style={{
            marginLeft: 'auto',
            background: 'transparent', color: '#888',
            border: 'none', fontSize: 12, cursor: 'pointer'
          }}
        >
          더 이상
        </button>
      </div>
    </Banner>
  );
}

function computeAgeDays(refIso: string): number {
  const refMs = new Date(refIso).getTime();
  return Math.max(0, Math.floor((Date.now() - refMs) / 86_400_000));
}
