// KASHA website — 전화번호 인증 모달 (공용)
// 번호 입력 → SMS 인증번호 → 검증 후 계정에 귀속. 마이페이지·예약 진입 게이트에서 함께 사용해요.
// 애니메이션: 인증번호 단계로 넘어가면 번호 카드가 뒤로 물러나 흐려지고, 인증 카드가 아래에서 스프링으로 올라와요(카드 스택).

// OTP 슬롯 입력 — 투명 input이 슬롯 위에서 키 입력을 받아요(input-otp 스타일, 의존성 없음). 공용 노출.
function KashaOtp({ value, onChange, length, autoFocus, error, onComplete }) {
  length = length || 6;
  const ref = React.useRef(null);
  // 실패(error)가 false→true 로 바뀔 때 딱 한 번 흔들어요(정답 유출 힌트인 자릿수별 초록은 쓰지 않아요).
  const [shake, setShake] = React.useState(false);
  const prevErr = React.useRef(false);
  React.useEffect(() => {
    if (error && !prevErr.current) { setShake(true); prevErr.current = true; const t = setTimeout(() => setShake(false), 420); return () => clearTimeout(t); }
    if (!error) prevErr.current = false;
  }, [error]);
  const active = Math.min(String(value || "").length, length - 1);
  const handle = (e) => {
    const v = e.target.value.replace(/\D/g, "").slice(0, length);   // 붙여넣기 시 숫자만 추출·자름
    onChange(v);
    if (onComplete && v.length === length) onComplete(v);            // 6자리 완성 시 자동 제출(옵션)
  };
  return (
    <div className={"kasha-otp" + (shake ? " shake" : "")} onClick={() => ref.current && ref.current.focus()}>
      <input ref={ref} className="kasha-otp-input" value={value || ""} inputMode="numeric" autoComplete="one-time-code"
        autoFocus={autoFocus} aria-label="인증번호" aria-invalid={error ? "true" : "false"}
        onChange={handle} />
      <div className="kasha-otp-slots" aria-hidden="true">
        {Array.from({ length: length }).map(function (_, i) {
          return <div key={i} className="kasha-otp-slot" data-active={i === active} data-err={error ? "true" : "false"}>{(value || "")[i] || ""}</div>;
        })}
      </div>
    </div>
  );
}
window.KashaOtp = KashaOtp;

// 인증번호 재전송 카운트다운 버튼
function KashaResend({ onResend, seconds }) {
  const [left, setLeft] = React.useState(seconds || 30);
  React.useEffect(function () { const id = setInterval(function () { setLeft(function (p) { return p <= 0 ? 0 : p - 1; }); }, 1000); return function () { clearInterval(id); }; }, []);
  return (
    <button type="button" disabled={left > 0} onClick={function () { if (left <= 0) { onResend(); setLeft(seconds || 30); } }}
      style={{ border: "none", background: "transparent", color: left > 0 ? "var(--text-tertiary)" : "var(--text-link)", fontSize: 13, fontWeight: 600, cursor: left > 0 ? "not-allowed" : "pointer", fontFamily: "var(--font-sans)" }}>
      인증번호 재전송{left > 0 ? " (" + left + ")" : ""}
    </button>
  );
}

function PhoneVerifyModal({ open, onClose, onVerified, dismissible }) {
  const { Dialog, Button, Input, Icon } = window.DS;
  const canDismiss = dismissible !== false; // 기본 true — 예약 게이트에서는 false 로 닫기 차단
  const [step, setStep] = React.useState("phone");   // "phone" | "code"
  const [phone, setPhone] = React.useState("");
  const [code, setCode] = React.useState("");
  const [busy, setBusy] = React.useState(false);
  const [err, setErr] = React.useState("");
  const [hint, setHint] = React.useState("");          // 개발(로컬) 환경 devCode 안내

  React.useEffect(() => { if (open) { setStep("phone"); setPhone(""); setCode(""); setBusy(false); setErr(""); setHint(""); } }, [open]);
  if (!open) return <Dialog open={false} onClose={onClose} />;

  const fmtPhone = (v) => { const d = v.replace(/\D/g, "").slice(0, 11); if (d.length < 4) return d; if (d.length < 8) return d.slice(0, 3) + "-" + d.slice(3); return d.slice(0, 3) + "-" + d.slice(3, 7) + "-" + d.slice(7); };
  const digits = phone.replace(/\D/g, "");
  const reqMsg = { BAD_PHONE: "휴대폰 번호 형식을 확인해 주세요.", PHONE_IN_USE: "이미 다른 계정에 등록된 번호예요.", RATE_LIMITED: "잠시 후 다시 시도해 주세요.", SMS_FAILED: "문자 발송에 실패했어요. 잠시 후 다시 시도해 주세요.", NO_BACKEND: "지금은 인증을 사용할 수 없어요.", AUTH_REQUIRED: "다시 로그인해 주세요." };
  const verMsg = { BAD_CODE: "인증번호가 일치하지 않아요.", CODE_EXPIRED: "인증번호가 만료됐어요. 다시 받아 주세요.", TOO_MANY_TRIES: "시도 횟수를 초과했어요. 다시 받아 주세요.", NO_PENDING: "먼저 인증번호를 받아 주세요.", PHONE_IN_USE: "이미 다른 계정에 등록된 번호예요." };

  const sendCode = async () => {
    setErr("");
    if (digits.length < 10 || !/^01[0-9]/.test(digits)) { setErr("휴대폰 번호 형식을 확인해 주세요."); return; }
    setBusy(true);
    const r = await window.KASHADB.requestPhoneCode(digits);
    setBusy(false);
    if (r.ok) { setStep("code"); setCode(""); setErr(""); setHint(r.devCode ? "개발 환경: 인증번호 " + r.devCode : ""); return; }
    setErr(reqMsg[r.error] || "인증번호 발송에 실패했어요.");
  };
  const verify = async () => {
    setErr("");
    if (code.replace(/\D/g, "").length < 6) { setErr("6자리 인증번호를 입력해 주세요."); return; }
    setBusy(true);
    const r = await window.KASHADB.verifyPhoneCode(digits, code.replace(/\D/g, ""));
    setBusy(false);
    if (r.ok) { onVerified && onVerified(); return; }
    setErr(verMsg[r.error] || "인증에 실패했어요.");
  };

  const verifying = step === "code";
  const PhoneIcon = <span style={{ width: 44, height: 44, borderRadius: 12, background: "var(--blue-50)", display: "flex", alignItems: "center", justifyContent: "center" }}><Icon name="phone" size={20} color="var(--blue-500)" /></span>;

  return (
    <Dialog open onClose={canDismiss ? onClose : () => {}} style={{ maxWidth: 420, textAlign: "left" }}>
      <div className={"kasha-authstack" + (verifying ? " is-verifying" : "")} style={{ textAlign: "left", minHeight: 296 }}>
        {/* 하위 카드 — 번호 입력 (인증 단계에선 뒤로 물러나 흐려짐) */}
        <div className="kasha-authstack-base">
          {PhoneIcon}
          <h3 style={{ fontSize: 19, letterSpacing: "var(--tracking-title)", marginTop: 14 }}>전화번호 등록</h3>
          <p style={{ marginTop: 6, color: "var(--text-secondary)", fontSize: 14, lineHeight: 1.5 }}>예약 안내와 본인 확인을 위해 전화번호를 인증해 주세요.</p>
          <div style={{ display: "flex", flexDirection: "column", gap: 12, marginTop: 18 }}>
            <Input label="휴대폰 번호" value={phone} onChange={(e) => setPhone(fmtPhone(e.target.value))} placeholder="010-0000-0000" inputMode="numeric" />
            {!verifying && err && <div style={{ color: "var(--red-500)", fontSize: 13 }}>{err}</div>}
            <Button variant="primary" size="lg" fullWidth disabled={busy || verifying} onClick={sendCode}>{busy && !verifying ? "보내는 중…" : "인증번호 받기"}</Button>
          </div>
          {canDismiss && <button onClick={onClose} style={{ marginTop: 14, width: "100%", border: "none", background: "transparent", color: "var(--text-tertiary)", fontSize: 13, cursor: "pointer", fontFamily: "var(--font-sans)" }}>나중에 하기</button>}
        </div>

        {/* 인증 카드 — 아래에서 스프링으로 올라옴 */}
        {verifying && (
          <div className="kasha-authstack-over stacked">
            {PhoneIcon}
            <h3 style={{ fontSize: 19, letterSpacing: "var(--tracking-title)", marginTop: 14 }}>인증번호 입력</h3>
            <p style={{ marginTop: 6, color: "var(--text-secondary)", fontSize: 14, lineHeight: 1.5 }}>{phone} 로 보낸 인증번호 6자리를 입력해 주세요.</p>
            <div style={{ marginTop: 20 }}><window.KashaOtp value={code} onChange={(v) => { setCode(v); if (err) setErr(""); }} length={6} autoFocus error={!!err} /></div>
            {hint && <div style={{ color: "var(--blue-700)", fontSize: 12.5, background: "var(--blue-50)", borderRadius: "var(--radius-sm)", padding: "8px 12px", marginTop: 14, textAlign: "center" }}>{hint}</div>}
            {err && <div style={{ color: "var(--red-500)", fontSize: 13, marginTop: 12, textAlign: "center" }}>{err}</div>}
            <div style={{ marginTop: 16 }}><Button variant="primary" size="lg" fullWidth disabled={busy} onClick={verify}>{busy ? "확인 중…" : "인증 완료"}</Button></div>
            <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginTop: 12 }}>
              <button onClick={() => { setStep("phone"); setCode(""); setErr(""); setHint(""); }} style={{ border: "none", background: "transparent", color: "var(--text-tertiary)", fontSize: 13, fontWeight: 600, cursor: "pointer", fontFamily: "var(--font-sans)" }}>번호 다시 입력</button>
              <window.KashaResend onResend={sendCode} seconds={30} />
            </div>
          </div>
        )}
      </div>
    </Dialog>
  );
}
window.PhoneVerifyModal = PhoneVerifyModal;
