/* ============================================================================
 * 서명전에 — 계약서 텍스트 붙여넣기 (paste) 스크린
 * 카메라·파일 업로드 외의 3번째 입력 경로. AppsInToss 환경에서는 getClipboardText
 * 로 클립보드를 자동으로 읽어 textarea 를 선채우고, 웹(브라우저)에서는 사용자
 * 제스처로 붙여넣기를 유도한다.
 *
 * 호출 규약:
 *   onBack()                   — 취소/뒤로가기
 *   onSubmit(text: string)     — "분석하기" 확정. 부모가 /analyze-text 로 POST.
 * ========================================================================== */

function PasteScreen({ onBack, onSubmit }) {
  const [text, setText] = useState("");
  const [busy, setBusy] = useState(false);
  /* 클립보드 자동 로딩 상태:
   *   "idle"       → 아직 시도 안 함
   *   "loading"    → 읽는 중 (깜빡임 방지용)
   *   "loaded"     → 성공 (textarea 에 붙음)
   *   "empty"      → 성공했지만 클립보드가 비어 있음
   *   "denied"     → 권한 거부 → 직접 붙여넣기 안내
   *   "unsupported"→ 어댑터가 readText 를 지원하지 않음 (웹 폴백 필요)
   */
  const [clipState, setClipState] = useState("idle");
  const textareaRef = useRef(null);
  const didAutoLoadRef = useRef(false);

  // 어댑터 레이어 참조. 없으면 웹 브라우저 폴백으로만 동작.
  const adapter = (typeof window !== "undefined" && window.TossAdapter) || null;
  const isInToss = !!adapter?.isInAppsInToss?.();

  /* 클립보드에서 텍스트 읽기. 성공 시 textarea 에 넣고, 실패 사유별로 상태를
   * 분기해서 안내 문구를 결정한다.
   *
   *  - 앱인토스 네이티브: getClipboardText 호출 (사용자 제스처 불필요)
   *  - 웹 브라우저: navigator.clipboard.readText 호출 (사용자 제스처 필요;
   *    제스처 없이 호출하면 NotAllowedError → "denied" 로 분기)
   */
  const loadFromClipboard = async () => {
    if (!adapter?.clipboard?.readText) {
      setClipState("unsupported");
      return;
    }
    setClipState("loading");
    try {
      const clip = await adapter.clipboard.readText();
      const got = (clip || "").toString();
      if (got.trim().length === 0) {
        setClipState("empty");
        return;
      }
      setText(got);
      setClipState("loaded");
      // 다음 틱에 focus — 즉시 focus 하면 일부 브라우저에서 커서가 맨 앞으로 튐
      setTimeout(() => {
        if (textareaRef.current) {
          try {
            textareaRef.current.focus();
            const len = textareaRef.current.value.length;
            textareaRef.current.setSelectionRange(len, len);
          } catch (_) { /* 무시 */ }
        }
      }, 0);
    } catch (err) {
      // TossPermissionError / NotAllowedError 계열
      const name = err?.name || err?.constructor?.name || "";
      if (
        (adapter.TossPermissionError && err instanceof adapter.TossPermissionError) ||
        name === "NotAllowedError" ||
        /denied|permission/i.test(err?.message || "")
      ) {
        setClipState("denied");
      } else if (adapter.TossNotSupportedError && err instanceof adapter.TossNotSupportedError) {
        setClipState("unsupported");
      } else {
        // 기타 오류는 조용히 denied 로 취급 (사용자가 직접 붙여넣기 하면 됨)
        setClipState("denied");
      }
    }
  };

  /* 스크린 첫 진입 시 한 번만 자동 로딩.
   * 앱인토스 환경에서는 제스처 없이도 읽을 수 있으므로 자동으로 수행.
   * 브라우저에서는 사용자 제스처가 필요하므로 자동 로딩을 건너뛰고, 화면의
   * "클립보드에서 붙여넣기" 버튼을 누를 때만 시도한다. */
  useEffect(() => {
    if (didAutoLoadRef.current) return;
    didAutoLoadRef.current = true;
    if (isInToss) {
      loadFromClipboard();
    }
  }, []); // eslint-disable-line

  const charCount = text.length;
  // 너무 짧은 텍스트는 분석해도 결과가 의미없음. 50자 이하면 경고.
  const tooShort = charCount > 0 && charCount < 50;
  // 너무 긴 텍스트는 서버 비용/타임아웃 위험. 100k 초과 시 경고.
  const tooLong = charCount > 100000;
  const canSubmit = !busy && charCount >= 50 && !tooLong;

  const handleSubmit = async () => {
    if (!canSubmit) return;
    setBusy(true);
    try {
      await onSubmit(text.trim());
    } catch (err) {
      // 에러는 부모에서 alert 처리. 여기서는 busy 만 풀어준다.
      console.warn("[paste] onSubmit failed:", err);
    } finally {
      setBusy(false);
    }
  };

  // 상태별 안내 배너 내용
  const banner = (() => {
    if (clipState === "loading") {
      return { tone: "info", text: "클립보드를 읽는 중이에요…" };
    }
    if (clipState === "loaded" && charCount > 0) {
      return { tone: "ok", text: "클립보드에 있던 내용을 붙여넣었어요. 필요하면 고쳐 주세요." };
    }
    if (clipState === "empty") {
      return { tone: "info", text: "클립보드가 비어 있어요. 계약서 본문을 복사한 뒤 다시 눌러 주세요." };
    }
    if (clipState === "denied") {
      return {
        tone: "warn",
        text: "클립보드 읽기 권한이 없어요. 아래 입력창을 길게 눌러 '붙여넣기' 하거나 ⌘V / Ctrl+V 로 붙여 주세요.",
      };
    }
    if (clipState === "unsupported" && !isInToss) {
      return {
        tone: "info",
        text: "브라우저에서는 입력창에 직접 붙여넣어 주세요. 길게 누르기 또는 ⌘V / Ctrl+V 로 붙일 수 있어요.",
      };
    }
    return null;
  })();

  const bannerStyle = (tone) => ({
    padding: "10px 14px",
    borderRadius: 12,
    fontSize: 13.5,
    lineHeight: 1.45,
    margin: "0 16px 10px",
    background:
      tone === "ok"   ? "var(--safe-soft)" :
      tone === "warn" ? "var(--warn-soft)" :
                        "var(--fill-4, rgba(120,120,128,0.08))",
    color:
      tone === "ok"   ? "var(--safe-ink)" :
      tone === "warn" ? "var(--warn-ink)" :
                        "var(--label, #111)",
    border:
      tone === "ok"   ? "0.5px solid color-mix(in srgb, var(--safe) 35%, transparent)" :
      tone === "warn" ? "0.5px solid color-mix(in srgb, var(--warn) 35%, transparent)" :
                        "0.5px solid var(--separator, rgba(60,60,67,0.12))",
  });

  return (
    <div
      className="paste"
      style={{
        position: "absolute",
        inset: 0,
        background: "var(--bg)",
        display: "flex",
        flexDirection: "column",
        zIndex: 30,
      }}
    >
      {/* 상단 내비 */}
      <div className="navbar">
        <button className="navbar__btn" style={{ marginLeft: 6 }} onClick={onBack} disabled={busy}>
          닫기
        </button>
        <div className="navbar__title">텍스트 붙여넣기</div>
        <button
          className="navbar__btn navbar__btn--primary"
          style={{ marginRight: 6, opacity: canSubmit ? 1 : 0.35, pointerEvents: canSubmit ? "auto" : "none" }}
          onClick={handleSubmit}
          aria-busy={busy ? "true" : "false"}
        >
          {busy ? "분석 중…" : "분석하기"}
        </button>
      </div>

      {/* 본문 스크롤 영역 */}
      <div style={{ flex: 1, overflowY: "auto", paddingBottom: 8 }}>
        <div className="largetitle" style={{ paddingBottom: 8 }}>
          <div className="largetitle__eyebrow">텍스트로 분석하기</div>
          <h1 className="largetitle__text">
            계약서 본문을<br/>그대로 붙여 넣어 주세요
          </h1>
        </div>

        {/* 안내 배너 */}
        {banner && (
          <div style={bannerStyle(banner.tone)} role="status" aria-live="polite">
            {banner.text}
          </div>
        )}

        {/* 클립보드에서 다시 읽기 / 붙여넣기 트리거 버튼 */}
        <div style={{ margin: "0 16px 10px", display: "flex", gap: 8, flexWrap: "wrap" }}>
          <button
            className="btn btn--tinted"
            style={{ flex: "1 1 auto", minHeight: 40 }}
            onClick={loadFromClipboard}
            disabled={busy}
            type="button"
          >
            {clipState === "loaded" ? "클립보드에서 다시 가져오기" : "클립보드에서 붙여넣기"}
          </button>
          {charCount > 0 && (
            <button
              className="btn btn--gray"
              style={{ minHeight: 40 }}
              onClick={() => {
                setText("");
                setClipState("idle");
                if (textareaRef.current) textareaRef.current.focus();
              }}
              disabled={busy}
              type="button"
            >
              지우기
            </button>
          )}
        </div>

        {/* 텍스트 입력창 */}
        <div style={{ padding: "0 16px" }}>
          <textarea
            ref={textareaRef}
            value={text}
            onChange={(e) => {
              setText(e.target.value);
              // 사용자가 직접 입력하면 clipState 를 중립으로 되돌려 배너 감춤.
              if (clipState !== "idle") setClipState("idle");
            }}
            placeholder={
              "여기에 계약서 본문을 붙여 주세요.\n\n" +
              "· 스캔한 계약서 이미지 대신 메모장에 옮겨 둔 텍스트가 있다면 여기에 붙이면 돼요.\n" +
              "· 조항 번호나 공백, 줄바꿈이 섞여 있어도 괜찮아요.\n" +
              "· 개인정보(주민번호·연락처 등)는 지우고 올리는 걸 추천드려요."
            }
            rows={14}
            style={{
              width: "100%",
              minHeight: 260,
              padding: "14px 16px",
              fontSize: 15,
              lineHeight: 1.55,
              fontFamily: "var(--font)",
              color: "var(--label)",
              background: "var(--bg-2, #ffffff)",
              border: "0.5px solid var(--separator, rgba(60,60,67,0.18))",
              borderRadius: 14,
              outline: "none",
              resize: "vertical",
              boxSizing: "border-box",
              WebkitAppearance: "none",
            }}
            spellCheck={false}
            autoCorrect="off"
            autoCapitalize="off"
            aria-label="계약서 본문"
            disabled={busy}
          />
          {/* 글자수 + 경고 */}
          <div
            style={{
              display: "flex",
              justifyContent: "space-between",
              alignItems: "center",
              marginTop: 6,
              padding: "0 2px",
              fontSize: 12.5,
              color: "var(--label-secondary, #4e5968)",
            }}
          >
            <span>
              {tooShort ? (
                <span style={{ color: "var(--warn-ink)" }}>
                  조금 더 붙여 주세요. 50자 이상이어야 분석할 수 있어요.
                </span>
              ) : tooLong ? (
                <span style={{ color: "var(--alert-ink)" }}>
                  너무 길어요. 10만 자 이하로 잘라서 올려 주세요.
                </span>
              ) : (
                <span>계약서 본문을 그대로 붙이면 돼요. 50자 이상부터 분석할 수 있어요.</span>
              )}
            </span>
            <span className="tnum" aria-label="글자 수">
              {charCount.toLocaleString()}자
            </span>
          </div>
        </div>

        {/* 팁 카드 */}
        <div
          style={{
            margin: "16px 16px 24px",
            padding: "12px 14px",
            borderRadius: 12,
            background: "var(--bg-2, #ffffff)",
            border: "0.5px solid var(--separator, rgba(60,60,67,0.12))",
            color: "var(--label-secondary, #4e5968)",
            fontSize: 12.5,
            lineHeight: 1.55,
          }}
        >
          <div style={{ fontWeight: 600, color: "var(--label, #111)", marginBottom: 4 }}>
            이런 때 유용해요
          </div>
          <div>· 공인중개사가 카톡·문자로 보낸 계약서 문구를 바로 검토하고 싶을 때</div>
          <div>· 이미지 OCR이 잘 안 된 조항을 눈으로 확인해 옮겨 적었을 때</div>
          <div>· 특약만 따로 뽑아서 빠르게 위험도를 보고 싶을 때</div>
        </div>
      </div>

      {/* 하단 고정 분석 버튼 (모바일 가독성) */}
      <div
        className="picker__bottom"
        style={{
          padding: "10px 16px 16px",
          background: "var(--bg)",
          borderTop: "0.5px solid var(--separator, rgba(60,60,67,0.12))",
        }}
      >
        <button
          className="btn btn--filled"
          disabled={!canSubmit}
          onClick={handleSubmit}
          style={{ width: "100%", minHeight: 48 }}
          aria-busy={busy ? "true" : "false"}
        >
          {busy
            ? "분석 중…"
            : charCount === 0
              ? "먼저 계약서를 붙여 주세요"
              : tooShort
                ? "50자 이상이어야 분석할 수 있어요"
                : tooLong
                  ? "10만 자 이하로 잘라서 올려 주세요"
                  : "붙여 넣은 내용 분석하기"}
        </button>
      </div>
    </div>
  );
}

window.PasteScreen = PasteScreen;
Object.assign(window, { PasteScreen });
