// ============================================
// TransmitView — typewriter + paper + sending
// ============================================

const CHAR_LIMIT = 100;
const BELL_AT = 85;

// Render text with STOP tags highlighted in red
function FormattedText({ text, charClass }) {
  if (!text) return null;
  // split keeping the STOP token
  const parts = text.split(/(\bSTOP\b)/g);
  let charIdx = 0;
  return (
    <>
      {parts.map((part, i) => {
        if (part === 'STOP') {
          return <span key={i} className="stop-tag">STOP</span>;
        }
        return [...part].map((c, j) => {
          const k = charIdx++;
          return (
            <span key={`${i}-${j}`} className={charClass || ''}>
              {c}
            </span>
          );
        });
      })}
    </>
  );
}

function TypewriterImage({ isTyping, isReturning, bellRinging }) {
  return (
    <div className="typewriter-img-wrap">
      <div className="carriage-paper" />
      <div className={`typing-bell ${bellRinging ? 'is-ringing' : ''}`} />
      <img
        src="assets/typewriter.png"
        alt="Olivetti Lettera 32"
        className={`typewriter-img ${isTyping ? 'is-typing' : ''} ${isReturning ? 'is-returning' : ''}`}
      />
    </div>
  );
}

function Paper({ text, setText, onSend, sending, justSent }) {
  const { useRef, useState, useEffect, useCallback } = React;
  const inputRef = useRef(null);
  const stageRef = useRef(null);
  const [isTyping, setIsTyping] = useState(false);
  const [bellRinging, setBellRinging] = useState(false);
  const [lastLen, setLastLen] = useState(text.length);
  const { playKey, playBell, playReturn } = useTypeSound();
  const wiggleTimer = useRef(null);

  // Focus on mount and when clicked anywhere on paper
  useEffect(() => {
    inputRef.current?.focus();
  }, []);

  const handleChange = (e) => {
    const val = e.target.value;
    if (val.length > CHAR_LIMIT) return;

    if (val.length > lastLen) {
      playKey();
      setIsTyping(true);
      if (wiggleTimer.current) clearTimeout(wiggleTimer.current);
      wiggleTimer.current = setTimeout(() => setIsTyping(false), 120);

      // bell at threshold
      if (lastLen < BELL_AT && val.length >= BELL_AT) {
        playBell();
        setBellRinging(true);
        setTimeout(() => setBellRinging(false), 700);
      }
    }
    setLastLen(val.length);
    setText(val);
  };

  const handleKeyDown = (e) => {
    if (e.key === 'Enter' && !e.shiftKey) {
      e.preventDefault();
      onSend();
    }
  };

  const handleStageClick = () => inputRef.current?.focus();

  const charRatio = text.length / CHAR_LIMIT;
  const charClass = charRatio >= 1 ? 'danger' : charRatio >= 0.85 ? 'warn' : '';

  // Generate serial number for telegram (visual flavor)
  const serial = String(450 + (text.length % 999)).padStart(4, '0');

  return (
    <div className="typewriter-stage">
      <TypewriterImage
        isTyping={isTyping}
        isReturning={sending}
        bellRinging={bellRinging}
      />

      <div className="paper-stage" ref={stageRef}>
        <div className="paper" onClick={handleStageClick}>
          <div className="paper-header">
            <div className="paper-header-l">
              <span>No.{serial}</span>
            </div>
            <div className="paper-header-title">Telegram</div>
            <div className="paper-header-r">
              <span className="paper-stamp">PRIORITY</span>
            </div>
          </div>

          <div className="typing-area">
            <textarea
              ref={inputRef}
              className="hidden-input"
              value={text}
              onChange={handleChange}
              onKeyDown={handleKeyDown}
              disabled={sending}
              maxLength={CHAR_LIMIT}
              spellCheck={false}
              autoComplete="off"
              autoCorrect="off"
              autoCapitalize="off"
            />
            <div className="typed-display">
              {text.length === 0 && !sending && (
                <span className="placeholder">타전을 시작하세요…</span>
              )}
              <FormattedText text={text} charClass="ink-char" />
              {!sending && <span className="cursor-bar" />}
            </div>
          </div>

          <div className="paper-footer">
            <div className="char-bar">
              <div
                className={`char-bar-fill ${charClass}`}
                style={{ width: `${charRatio * 100}%` }}
              />
            </div>
            <div className="char-row">
              <span className={`char-count ${charClass}`}>
                {text.length} / {CHAR_LIMIT}
              </span>
              <button
                className="send-btn"
                onClick={onSend}
                disabled={!text.trim() || sending}
              >
                {sending ? '송신중 ···' : '송신 SEND'}
              </button>
            </div>
          </div>
        </div>
      </div>

      {justSent && (
        <div className="sent-stamp">
          <div className="sent-stamp-inner">SENT</div>
        </div>
      )}
    </div>
  );
}

function TransmitView({ state, onSend, onOpenRitual }) {
  const { useState, useEffect } = React;
  const [text, setText] = useState('');
  const [sending, setSending] = useState(false);
  const [justSent, setJustSent] = useState(false);
  const { playReturn } = useTypeSound();

  const myTelegrams = state.telegrams
    .filter((t) => t.from === state.me && t.vol === state.currentVol)
    .slice(0, 3);

  const handleSend = () => {
    if (!text.trim() || sending) return;
    setSending(true);
    playReturn();
    setTimeout(() => {
      onSend(text.trim());
      setText('');
      setSending(false);
      setJustSent(true);
      setTimeout(() => setJustSent(false), 2400);
    }, 700);
  };

  const currentCount = state.telegrams.filter((t) => t.vol === state.currentVol).length;

  return (
    <div className="fade-up">
      <Paper
        text={text}
        setText={setText}
        onSend={handleSend}
        sending={sending}
        justSent={justSent}
      />

      {myTelegrams.length > 0 && (
        <div className="section">
          <div className="section-label">최근 송신 · Recent</div>
          {myTelegrams.map((t) => (
            <div key={t.id} className="card from-me">
              <div className="card-meta">
                <b>→ 송신</b>
                <span>No.{(t.id || '').slice(-4).toUpperCase()}</span>
              </div>
              <div className="card-text">
                <FormattedText text={t.text} />
              </div>
              <div className="card-time">
                {new Date(t.time).toLocaleString('ko-KR', {
                  month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit',
                }).replace(/\./g, '.').trim()}
              </div>
            </div>
          ))}
        </div>
      )}

      <button className="meet-btn" onClick={onOpenRitual} disabled={currentCount === 0}>
        <span className="meet-btn-icon">⏎</span>
        만남 마감 — 이번 권 닫기
        <span className="meet-btn-icon">⏎</span>
      </button>
    </div>
  );
}

window.TransmitView = TransmitView;
window.FormattedText = FormattedText;
