// composer.jsx — 投下カード
// ========= 投下の共通ロジック (Composer / QuickComposer 共用) =========
// 投下→DB保存→AI分類→エコー検出→Echo履歴保存まで

function getEchoLevel(score) {
  if (score >= 80) return 'deja_vu';
  if (score >= 55) return 'echo';
  return 'whisper';
}

function getEchoLevelLabel(level) {
  if (level === 'deja_vu') return 'Déjà vu';
  if (level === 'echo') return 'Echo';
  return 'Whisper';
}

async function postNote({ text, pastNotes = [], onOptimistic, onFinal, onEcho }) {
  const nowTs = Date.now();
  const cal = maybeLinkCalendar(text);

  const optimistic = {
    id: 'n_' + nowTs,
    ts: nowTs,
    text,
    type: 'memo',
    status: 'fresh',
  };

  if (cal) optimistic.cal = cal;

  // 時刻マッチング (Tweakがオンなら)
  try {
    const settings = loadEchoSettings();
    if (settings.timeMatching) {
      const events = await DB.allEvents();
      const overlap = events.find(ev => {
        const end = ev.endTs || ev.ts + 3600000;
        return ev.ts <= nowTs && end >= nowTs;
      });

      if (overlap) {
        optimistic.contextEventId = overlap.id;
        optimistic.contextEventTitle = overlap.title;
      }
    }
  } catch (e) {
    // noop
  }

  // まず即保存。入力体験を止めない。
  await DB.put(optimistic);
  onOptimistic && onOptimistic(optimistic);

  // 分類 + Echo検出を並列実行
  const [type, echoResult] = await Promise.all([
    classifyWithClaude(text),
    findEcho(text, pastNotes),
  ]);

  let finalNote = {
    ...optimistic,
    type,
  };

  let echoPayload = null;

  // Echo検出されたら、双方のnoteとecho_eventsに保存
  if (echoResult && echoResult.note) {
    const level = getEchoLevel(echoResult.score);
    const echoEventId = 'ee_' + nowTs;

    finalNote = {
      ...finalNote,
      echo: {
        eventId: echoEventId,
        matchedNoteId: echoResult.note.id,
        score: echoResult.score,
        rawScore: echoResult.rawScore || null,
        reason: echoResult.reason || '',
        level,
        echoedAt: nowTs,
      },
      echoedSimilarity: echoResult.score / 100,
    };

    const pastNote = {
      ...echoResult.note,
      status: 'echoed',
      echoedAt: nowTs,
      lastEchoedBy: finalNote.id,
      echoedSimilarity: echoResult.score / 100,
    };

    await DB.put(pastNote);

    const echoEvent = {
      id: echoEventId,
      ts: nowTs,
      currentNoteId: finalNote.id,
      matchedNoteId: echoResult.note.id,
      score: echoResult.score,
      rawScore: echoResult.rawScore || null,
      level,
      reason: echoResult.reason || '',
      userAction: null,
      createdAt: nowTs,
    };

    try {
      if (typeof DB.putEchoEvent === 'function') {
        await DB.putEchoEvent(echoEvent);
      }
    } catch (e) {
      console.warn('[echo] putEchoEvent failed:', e);
    }

    echoPayload = {
      ...echoResult,
      eventId: echoEventId,
      currentNoteId: finalNote.id,
      matchedNoteId: echoResult.note.id,
      level,
    };
  }

  // 最終note保存
  await DB.put(finalNote);

  onFinal && onFinal(finalNote);

  if (echoPayload) {
    onEcho && onEcho(echoPayload);
  }

  return finalNote;
}

function Composer({ onPosted, pastNotes }) {
  const t = useT();
  const [draft, setDraft] = React.useState('');
  const [pending, setPending] = React.useState(false);
  const [flash, setFlash] = React.useState(null);
  const [echo, setEcho] = React.useState(null);
  const textareaRef = React.useRef(null);
  const echoTimerRef = React.useRef(null);

  React.useEffect(() => {
    return () => {
      if (echoTimerRef.current) clearTimeout(echoTimerRef.current);
    };
  }, []);

  const submit = async () => {
    const text = draft.trim();
    if (!text || pending) return;

    setPending(true);
    setFlash('Echoが整理中…');

    try {
      await postNote({
        text,
        pastNotes,
        onOptimistic: (n) => {
          setDraft('');
          onPosted && onPosted(n);
        },
        onFinal: (n) => {
          onPosted && onPosted(n);

          const typeLabel =
            n.type === 'task' ? '一歩' :
            n.type === 'idea' ? '着想' :
            n.type === 'output' ? '形になったもの' :
            n.type === 'outcome' ? '成果' :
            '断片';

          setFlash(`投下完了。${typeLabel}として置いた。`);
          setTimeout(() => setFlash(null), 2200);
          setPending(false);
        },
        onEcho: (echoResult) => {
          setEcho(echoResult);

          if (echoTimerRef.current) clearTimeout(echoTimerRef.current);
          echoTimerRef.current = setTimeout(() => {
            setEcho(null);
          }, 14000);
        },
      });
    } catch (e) {
      console.error('[echo] post failed:', e);
      setFlash('投下できなかった。もう一度。');
      setPending(false);
    }
  };

  const onKey = (e) => {
    // デスクトップのみ: Cmd/Ctrl + Enter で送信
    // モバイルは改行が普通に使えるようボタンで送信
    if (e.key === 'Enter' && (e.metaKey || e.ctrlKey)) {
      e.preventDefault();
      submit();
    }
  };

  const isMobile = typeof window !== 'undefined' &&
    window.matchMedia('(max-width: 640px)').matches;

  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
      <div style={{
        background: t.bgCard,
        border: `1.5px solid ${t.primary}`,
        borderRadius: 16,
        padding: 16,
        boxShadow: `0 4px 20px ${t.primary}14`,
      }}>
        <div style={{
          display: 'flex',
          alignItems: 'center',
          gap: 8,
          marginBottom: 10,
        }}>
          <span style={{
            width: 6,
            height: 6,
            borderRadius: '50%',
            background: t.primary,
            display: 'inline-block',
            boxShadow: `0 0 8px ${t.primary}`,
          }}/>

          <span style={{
            fontSize: 10,
            fontWeight: 700,
            letterSpacing: '0.1em',
            color: t.primary,
            fontFamily: APP_FONT,
          }}>
            NOW · 投げるだけ。整理はEchoがやる。
          </span>

          {flash && (
            <span style={{
              marginLeft: 'auto',
              fontSize: 11,
              color: t.ink4,
              fontFamily: APP_FONT,
            }}>
              {flash}
            </span>
          )}
        </div>

        <textarea
          ref={textareaRef}
          value={draft}
          onChange={(e) => setDraft(e.target.value)}
          onKeyDown={onKey}
          placeholder="今、頭にあることをそのまま投げる。"
          rows={3}
          autoCapitalize="sentences"
          autoCorrect="on"
          autoComplete="off"
          spellCheck="true"
          enterKeyHint="enter"
          style={{
            width: '100%',
            border: 'none',
            outline: 'none',
            resize: 'none',
            minHeight: 64,
            fontFamily: APP_FONT,
            fontSize: 16,
            lineHeight: 1.6,
            color: t.ink,
            background: 'transparent',
            padding: 0,
            boxSizing: 'border-box',
            WebkitAppearance: 'none',
          }}
        />

        <div style={{
          display: 'flex',
          alignItems: 'center',
          justifyContent: 'space-between',
          paddingTop: 10,
          borderTop: `1px solid ${t.line}`,
          gap: 10,
        }}>
          <div style={{
            fontSize: 11,
            color: t.ink4,
            fontFamily: APP_FONT,
            display: 'flex',
            gap: 10,
            alignItems: 'center',
            flexWrap: 'wrap',
          }}>
            {!isMobile && (
              <>
                <span>⌘ + Enter で投下</span>
                <span style={{ color: t.ink4 }}>·</span>
              </>
            )}
            <span>分類しなくていい</span>
          </div>

          <button
            onClick={submit}
            disabled={!draft.trim() || pending}
            style={{
              padding: '10px 20px',
              borderRadius: 10,
              border: 'none',
              background: draft.trim() && !pending ? t.primary : t.line,
              color: draft.trim() && !pending ? '#fff' : t.ink4,
              fontFamily: APP_FONT,
              fontSize: 14,
              fontWeight: 700,
              cursor: draft.trim() && !pending ? 'pointer' : 'not-allowed',
              letterSpacing: '-0.01em',
              display: 'inline-flex',
              alignItems: 'center',
              gap: 6,
              minHeight: 40,
              WebkitTapHighlightColor: 'transparent',
              touchAction: 'manipulation',
              flexShrink: 0,
            }}
          >
            {Icons.plus(14)} 投下
          </button>
        </div>
      </div>

      {echo && (
        <EchoBanner
          echo={echo}
          onClose={() => setEcho(null)}
        />
      )}
    </div>
  );
}

function EchoBanner({ echo, onClose }) {
  const t = useT();
  const [detailOpen, setDetailOpen] = React.useState(false);
  const [acted, setActed] = React.useState(null);

  const level = echo.level || getEchoLevel(echo.score || 0);
  const levelLabel = getEchoLevelLabel(level);

  const logAction = async (action) => {
    setActed(action);

    try {
      if (echo.eventId && typeof DB.updateEchoEvent === 'function') {
        await DB.updateEchoEvent(echo.eventId, {
          userAction: action,
          actionAt: Date.now(),
        });
      }
    } catch (e) {
      console.warn('[echo] updateEchoEvent failed:', e);
    }
  };

  const handleView = async () => {
    await logAction('view');
    setDetailOpen(true);
  };

  const handleConnect = async () => {
    await logAction('connect');
    setTimeout(() => onClose && onClose(), 500);
  };

  const handleGrowLater = async () => {
    await logAction('grow_later');

    try {
      if (echo.note) {
        await DB.put({
          ...echo.note,
          status: 'ripening',
          ripenedAt: Date.now(),
        });
      }
    } catch (e) {
      console.warn('[echo] grow_later update failed:', e);
    }

    setTimeout(() => onClose && onClose(), 500);
  };

  const handleClose = async () => {
    await logAction('close');
    onClose && onClose();
  };

  const actionLabel = (() => {
    if (acted === 'view') return '開いた';
    if (acted === 'connect') return '重ねた';
    if (acted === 'grow_later') return 'あとで育てる';
    if (acted === 'close') return '閉じた';
    return null;
  })();

  return (
    <>
      <div style={{
        padding: '16px 18px',
        background: `linear-gradient(180deg, ${t.primarySoft} 0%, ${t.bgCard} 100%)`,
        border: `1px solid ${t.primary}44`,
        borderRadius: 14,
        display: 'flex',
        flexDirection: 'column',
        gap: 12,
        animation: 'echoSlide 0.4s ease-out',
        fontFamily: APP_FONT,
        boxShadow: t.shadow,
      }}>
        <style>{`
          @keyframes echoSlide {
            from { transform: translateY(-6px); opacity: 0; }
            to { transform: translateY(0); opacity: 1; }
          }
        `}</style>

        <div style={{
          display: 'flex',
          alignItems: 'flex-start',
          gap: 14,
        }}>
          <div style={{
            width: 48,
            height: 48,
            borderRadius: '50%',
            background: t.primary,
            color: '#fff',
            display: 'flex',
            alignItems: 'center',
            justifyContent: 'center',
            flexDirection: 'column',
            flexShrink: 0,
            fontFamily: APP_FONT,
            boxShadow: `0 0 20px ${t.primary}55`,
          }}>
            <div style={{
              fontSize: 14,
              fontWeight: 800,
              letterSpacing: '-0.02em',
              lineHeight: 1,
            }}>
              {Math.round(echo.score || 0)}%
            </div>
            <div style={{
              fontSize: 7,
              fontWeight: 700,
              opacity: 0.9,
              marginTop: 3,
              letterSpacing: '0.08em',
              textTransform: 'uppercase',
            }}>
              {levelLabel}
            </div>
          </div>

          <div style={{ flex: 1, minWidth: 0 }}>
            <div style={{
              fontSize: 10,
              fontWeight: 800,
              color: t.primary,
              letterSpacing: '0.14em',
              marginBottom: 5,
              fontFamily: APP_FONT,
              textTransform: 'uppercase',
            }}>
              ECHO · 過去の自分が近いことを書いていた
            </div>

            <div style={{
              fontSize: 15,
              fontWeight: 800,
              color: t.ink,
              letterSpacing: '-0.03em',
              lineHeight: 1.35,
              marginBottom: 6,
            }}>
              この思考、前にも現れてる。
            </div>

            {echo.reason && (
              <div style={{
                fontSize: 11,
                color: t.ink4,
                marginBottom: 8,
                lineHeight: 1.5,
              }}>
                つながり: {echo.reason}
              </div>
            )}

            <div style={{
              fontSize: 13,
              color: t.ink2,
              lineHeight: 1.55,
              textWrap: 'pretty',
              overflow: 'hidden',
              textOverflow: 'ellipsis',
              display: '-webkit-box',
              WebkitLineClamp: 3,
              WebkitBoxOrient: 'vertical',
              whiteSpace: 'pre-wrap',
            }}>
              {echo.note ? echo.note.text : ''}
            </div>

            {echo.note && (
              <div style={{
                fontSize: 11,
                color: t.ink4,
                marginTop: 6,
              }}>
                {relTime(echo.note.ts)} の断片
              </div>
            )}
          </div>

          <IconBtn onClick={handleClose} title="今は閉じる">
            {Icons.close(14)}
          </IconBtn>
        </div>

        <div style={{
          display: 'flex',
          gap: 8,
          flexWrap: 'wrap',
          paddingTop: 4,
        }}>
          <button onClick={handleView} style={echoActionBtnStyle(t, 'primary')}>
            見る
          </button>

          <button onClick={handleConnect} style={echoActionBtnStyle(t, 'ghost')}>
            重ねる
          </button>

          <button onClick={handleGrowLater} style={echoActionBtnStyle(t, 'ghost')}>
            あとで育てる
          </button>

          <button onClick={handleClose} style={echoActionBtnStyle(t, 'quiet')}>
            今は閉じる
          </button>

          {actionLabel && (
            <span style={{
              marginLeft: 'auto',
              fontSize: 11,
              color: t.ink4,
              display: 'inline-flex',
              alignItems: 'center',
            }}>
              {actionLabel}
            </span>
          )}
        </div>
      </div>

      {echo.note && typeof NoteDetailModal === 'function' && (
        <NoteDetailModal
          note={echo.note}
          open={detailOpen}
          onClose={() => setDetailOpen(false)}
          onUpdate={async (n) => {
            await DB.put(n);
          }}
          onDelete={async (id) => {
            await DB.remove(id);
            setDetailOpen(false);
          }}
        />
      )}
    </>
  );
}

function echoActionBtnStyle(t, variant) {
  const base = {
    padding: '8px 12px',
    borderRadius: 9,
    fontFamily: APP_FONT,
    fontSize: 12,
    fontWeight: 700,
    letterSpacing: '-0.01em',
    cursor: 'pointer',
    minHeight: 36,
    WebkitTapHighlightColor: 'transparent',
    touchAction: 'manipulation',
  };

  if (variant === 'primary') {
    return {
      ...base,
      background: t.primary,
      color: '#fff',
      border: 'none',
    };
  }

  if (variant === 'quiet') {
    return {
      ...base,
      background: 'transparent',
      color: t.ink4,
      border: 'none',
    };
  }

  return {
    ...base,
    background: t.bgCard,
    color: t.ink2,
    border: `1px solid ${t.line}`,
  };
}

Object.assign(window, {
  Composer,
  EchoBanner,
  postNote,
  getEchoLevel,
  getEchoLevelLabel,
});
