/* global React */
(function(){
const { useState, useEffect, useRef, useCallback } = React;

/* =============================================================
   Login.jsx — standalone OTP login flow
   --------------------------------------------------------------
   Scenes: phone → otp → success
   Errors: invalid-phone (inline)  ·  wrong-otp (shake + msg)
           expired-otp (msg + force resend)
   Fallback: after first 60s countdown expires, surface
            "تماس بگیر بهم بزن" so users on flaky SMS get a
            voice-call read-out (POST /auth/otp/request?channel=voice).

   OpenAPI uses a 5-digit code (`^\d{5}$`); we honor that here.
   For demo purposes:
     code "11111" → wrong-otp state
     code "22222" → expired-otp state
     anything else → success
   ============================================================= */

const fmtFa = (n) => String(n).replace(/\d/g, d => "۰۱۲۳۴۵۶۷۸۹"[d]);
const onlyDigits = (s) => s.replace(/[^\d۰-۹]/g, "").replace(/[۰-۹]/g, d => "۰۱۲۳۴۵۶۷۸۹".indexOf(d));
// Accept three entry forms and canonicalize to 09xxxxxxxxx:
//   0912 345 6789   ·   98 912 345 6789   ·   912 345 6789
const normalizeMobile = (digits) => {
  let d = digits;
  if (d.startsWith("0098")) d = d.slice(4);          // 0098…
  else if (d.startsWith("98") && d.length >= 12) d = d.slice(2); // 98…
  if (d.length === 10 && d.startsWith("9")) d = "0" + d;         // 9…
  return d;
};
const formatPhone = (raw) => {
  const d = normalizeMobile(onlyDigits(raw).slice(0, 14));
  if (d.length <= 4) return d;
  if (d.length <= 7) return d.slice(0,4) + " " + d.slice(4);
  return d.slice(0,4) + " " + d.slice(4,7) + " " + d.slice(7, 11);
};
const isValidIranMobile = (digits) => /^09\d{9}$/.test(normalizeMobile(digits));

window.Login = function Login({ onDone, onSwitchToSignup, onClose, defaultPhone = "" }) {
  const [scene, setScene] = useState("phone"); // phone, otp, success
  const [phoneRaw, setPhoneRaw] = useState(defaultPhone);
  const [phoneError, setPhoneError] = useState("");
  const [otp, setOtp] = useState(["", "", "", "", ""]);
  const [otpError, setOtpError] = useState("");   // "" | "wrong" | "expired"
  const [resendIn, setResendIn] = useState(0);
  const [voiceState, setVoiceState] = useState("idle"); // idle | calling | called
  const [shake, setShake] = useState(false);
  const [verifying, setVerifying] = useState(false);
  const phoneInputRef = useRef(null);

  const phoneDigits = normalizeMobile(onlyDigits(phoneRaw));

  // ----- focus management
  useEffect(() => {
    if (scene === "phone") phoneInputRef.current?.focus();
    if (scene === "otp")   document.getElementById("kd-li-otp-0")?.focus();
  }, [scene]);

  // ----- countdown
  useEffect(() => {
    if (resendIn <= 0) return;
    const t = setTimeout(() => setResendIn(s => s - 1), 1000);
    return () => clearTimeout(t);
  }, [resendIn]);

  // ----- handlers
  const submitPhone = () => {
    if (!isValidIranMobile(phoneDigits)) {
      setPhoneError("شماره معتبر نیست. می‌تونی با ۰۹، ۹۸۹ یا ۹ شروع کنی.");
      phoneInputRef.current?.focus();
      return;
    }
    setPhoneError("");
    setScene("otp");
    setResendIn(60);
    setOtp(["", "", "", "", ""]);
    setOtpError("");
    setVoiceState("idle");
  };

  const setOtpDigit = (i, v) => {
    const ch = onlyDigits(v).slice(-1);
    setOtp(o => { const n = [...o]; n[i] = ch; return n; });
    if (ch && i < 4) document.getElementById(`kd-li-otp-${i+1}`)?.focus();
    if (otpError) setOtpError("");
  };

  const handleOtpKey = (i, e) => {
    if (e.key === "Backspace" && !otp[i] && i > 0) {
      document.getElementById(`kd-li-otp-${i-1}`)?.focus();
    }
    if (e.key === "ArrowLeft"  && i < 4) document.getElementById(`kd-li-otp-${i+1}`)?.focus();
    if (e.key === "ArrowRight" && i > 0) document.getElementById(`kd-li-otp-${i-1}`)?.focus();
  };

  const handleOtpPaste = (e) => {
    const txt = onlyDigits(e.clipboardData.getData("text") || "").slice(0, 5);
    if (txt.length < 2) return;
    e.preventDefault();
    const arr = ["", "", "", "", ""];
    for (let i = 0; i < txt.length; i++) arr[i] = txt[i];
    setOtp(arr);
    setOtpError("");
    document.getElementById(`kd-li-otp-${Math.min(txt.length, 4)}`)?.focus();
  };

  const otpFull = otp.every(c => c !== "");
  const otpStr = otp.join("");

  const verifyOtp = () => {
    if (!otpFull || verifying) return;
    setVerifying(true);

    // Simulated verification — POST /auth/otp/verify with {request_id, code}
    setTimeout(() => {
      setVerifying(false);
      if (otpStr === "11111") {
        setOtpError("wrong");
        setShake(true);
        setOtp(["", "", "", "", ""]);
        document.getElementById("kd-li-otp-0")?.focus();
        setTimeout(() => setShake(false), 420);
        return;
      }
      if (otpStr === "22222") {
        setOtpError("expired");
        setShake(true);
        setTimeout(() => setShake(false), 420);
        return;
      }
      setScene("success");
      setTimeout(() => onDone?.(), 1400);
    }, 480);
  };

  const resendSms = () => {
    setResendIn(60);
    setOtp(["", "", "", "", ""]);
    setOtpError("");
    setVoiceState("idle");
    document.getElementById("kd-li-otp-0")?.focus();
  };

  const callMe = () => {
    setVoiceState("calling");
    setOtp(["", "", "", "", ""]);
    setOtpError("");
    setTimeout(() => setVoiceState("called"), 2200);
  };

  // ----- copy
  const formattedPhone = formatPhone(phoneRaw);
  const phonePretty = phoneDigits.length === 11
    ? phoneDigits.slice(0,4) + " " + phoneDigits.slice(4,7) + " " + phoneDigits.slice(7)
    : phoneDigits;

  return (
    <div className="kd-login" data-scene={scene}>
      <div className="kd-login__aurora" aria-hidden="true">
        <i className="kd-login__aurora-1" />
        <i className="kd-login__aurora-2" />
        <i className="kd-login__aurora-3" />
      </div>

      {onClose && (
        <button className="kd-login__close" onClick={onClose} aria-label="بستن">
          <Icon name="close" size={18} stroke={2} />
        </button>
      )}

      <div className="kd-login__inner">
        <div className="kd-login__brand">
          <img src="../../assets/logo-festival.png" alt="کشوردوست" />
        </div>

        {/* ============ SCENE: phone ============ */}
        {scene === "phone" && (
          <div className="kd-login__card kd-glass">
            <h1 className="kd-login__h">خوش برگشتی</h1>
            <p className="kd-login__sub">شماره موبایلتو بزن — یه کد یه‌بارمصرف برات می‌فرستیم.</p>
            <label className={`kd-login__field ${phoneError ? "is-error" : ""}`}>
              <span className="kd-login__field-lbl">شماره موبایل</span>
              <input
                ref={phoneInputRef}
                className="kd-login__phone"
                inputMode="tel"
                type="tel"
                dir="ltr"
                value={formattedPhone}
                placeholder="0912 345 6789"
                autoComplete="tel"
                onChange={e => { setPhoneRaw(e.target.value); if (phoneError) setPhoneError(""); }}
                onKeyDown={e => { if (e.key === "Enter") submitPhone(); }}
              />
              <span className="kd-login__field-flag" aria-hidden="true">+۹۸</span>
            </label>

            {phoneError && (
              <p className="kd-login__err">
                <Icon name="close" size={12} stroke={2.6} />
                {phoneError}
              </p>
            )}

            <button
              className="kd-btn kd-btn--primary kd-btn--lg kd-login__cta"
              disabled={!isValidIranMobile(phoneDigits)}
              onClick={submitPhone}
            >
              ارسال کد <Icon name="back" size={16} stroke={2.4} />
            </button>

            <p className="kd-login__legal">
              با ادامه با <a href="#" tabIndex={-1}>شرایط استفاده</a> و <a href="#" tabIndex={-1}>حریم خصوصی</a> موافقت می‌کنی.
            </p>

            {onSwitchToSignup && (
              <div className="kd-login__alt">
                <span>اولین بارته؟</span>
                <button className="kd-login__alt-btn" onClick={onSwitchToSignup}>حساب نو بساز</button>
              </div>
            )}
          </div>
        )}

        {/* ============ SCENE: otp ============ */}
        {scene === "otp" && (
          <div className="kd-login__card kd-glass">
            <button className="kd-login__back" onClick={() => setScene("phone")}>
              <Icon name="chevron" size={14} stroke={2.4} /> برگرد
            </button>

            <h1 className="kd-login__h">کد رو وارد کن</h1>
            <p className="kd-login__sub">
              کد ۵ رقمی به <b style={{ color: "#fff", direction: "ltr", display: "inline-block", letterSpacing: ".02em" }}>{phonePretty}</b> پیامک شد.
            </p>

            <div className={`kd-login__otp ${shake ? "is-shake" : ""} ${otpError ? "is-error" : ""}`}>
              {otp.map((v, i) => (
                <input
                  key={i}
                  id={`kd-li-otp-${i}`}
                  className="kd-login__otp-box"
                  inputMode="numeric"
                  maxLength={1}
                  value={v}
                  autoComplete={i === 0 ? "one-time-code" : "off"}
                  onChange={e => setOtpDigit(i, e.target.value)}
                  onKeyDown={e => handleOtpKey(i, e)}
                  onPaste={i === 0 ? handleOtpPaste : undefined}
                />
              ))}
            </div>

            {otpError === "wrong" && (
              <p className="kd-login__err">
                <Icon name="close" size={12} stroke={2.6} />
                کد اشتباهه. یه بار دیگه امتحان کن.
              </p>
            )}
            {otpError === "expired" && (
              <p className="kd-login__err">
                <Icon name="close" size={12} stroke={2.6} />
                این کد منقضی شده. یه کد تازه می‌فرستیم.
              </p>
            )}

            <div className="kd-login__resendrow">
              {resendIn > 0 ? (
                <span className="kd-login__resend is-counting">
                  <span className="kd-login__resend-ring" style={{ ['--p']: `${(60 - resendIn) / 60 * 360}deg` }} />
                  ارسال دوباره در <b>{fmtFa(resendIn)}</b> ثانیه
                </span>
              ) : (
                <React.Fragment>
                  <button className="kd-login__resend" onClick={resendSms}>
                    ارسال دوباره
                  </button>
                  <span className="kd-login__sep">·</span>
                  {voiceState === "idle" && (
                    <button className="kd-login__resend kd-login__resend--alt" onClick={callMe}>
                      <Icon name="bell" size={13} stroke={2} /> با تماس بفرست
                    </button>
                  )}
                  {voiceState === "calling" && (
                    <span className="kd-login__resend is-calling">
                      <span className="kd-login__pulse" /> داریم زنگ می‌زنیم…
                    </span>
                  )}
                  {voiceState === "called" && (
                    <span className="kd-login__resend is-called">
                      <Icon name="check" size={13} stroke={2.6} /> کد رو با تماس گفتیم
                    </span>
                  )}
                </React.Fragment>
              )}
            </div>

            <button
              className="kd-btn kd-btn--primary kd-btn--lg kd-login__cta"
              disabled={!otpFull || verifying}
              onClick={verifyOtp}
            >
              {verifying ? "در حال تأیید…" : "تأیید و ورود"}
            </button>

            <button className="kd-login__textbtn" onClick={() => setScene("phone")}>
              شماره اشتباهه؟ تغییرش بده
            </button>
          </div>
        )}

        {/* ============ SCENE: success ============ */}
        {scene === "success" && (
          <div className="kd-login__card kd-glass kd-login__card--success">
            <div className="kd-login__success-ring">
              <Icon name="check" size={44} stroke={3} />
            </div>
            <h1 className="kd-login__h">خوش اومدی!</h1>
            <p className="kd-login__sub">داریم می‌بریمت داخل…</p>
          </div>
        )}

        {/* hint for the design reviewer — only renders in non-prod */}
        <div className="kd-login__demohint" aria-hidden="true">
          <span>برای نمایش حالت‌های خطا:</span>
          <b>۱۱۱۱۱</b> کد اشتباه <span className="kd-login__sep">·</span>
          <b>۲۲۲۲۲</b> منقضی <span className="kd-login__sep">·</span>
          هر کد دیگه‌ای موفق
        </div>
      </div>
    </div>
  );
};
})();
