/* MBEX — app shell for the new Mini App route */

const { useEffect, useMemo, useState } = React;

const SUB_TITLES = {
  create: "Создание заявки",
  status: "Статус заявки",
  referral: "Реферальная программа",
  loyalty: "Лояльность",
  wallets: "Кошельки",
  couriers: "Получатели",
  support: "Поддержка",
  offices: "Офисы MBEX",
  aml: "AML / KYC / KYT",
};

function MbexLogo({ className = "" }) {
  return (
    <svg
      aria-label="MBEX"
      className={className}
      role="img"
      viewBox="0 0 1079 326"
      xmlns="http://www.w3.org/2000/svg"
    >
      <path
        d="M 10 11 L 11 314 L 77 312 L 78 108 L 137 314 L 199 314 L 258 104 L 260 314 L 481 313 L 550 278 L 552 314 L 782 314 L 782 254 L 624 254 L 623 192 L 869 191 L 789 314 L 860 314 L 925 216 L 990 314 L 1068 315 L 963 160 L 1064 10 L 987 10 L 928 100 L 868 10 L 791 10 L 873 132 L 624 134 L 623 71 L 782 70 L 782 10 L 551 10 L 550 53 L 519 25 L 476 11 L 225 10 L 169 210 L 110 11 Z M 325 181 L 326 180 L 459 180 L 460 181 L 468 182 L 481 188 L 485 191 L 491 198 L 496 213 L 495 228 L 489 240 L 482 247 L 474 252 L 464 255 L 460 255 L 459 256 L 327 256 L 325 254 Z M 550 120 L 551 121 L 551 172 L 550 173 L 546 169 L 545 169 L 542 166 L 541 166 L 539 164 L 538 164 L 536 162 L 535 162 L 533 160 L 532 160 L 531 159 L 530 159 L 529 158 L 528 158 L 527 157 L 526 157 L 524 155 L 523 155 L 522 154 L 521 154 L 520 153 L 518 153 L 517 152 L 516 152 L 515 151 L 514 151 L 513 150 L 512 150 L 511 149 L 510 149 L 509 148 L 510 147 L 511 147 L 512 146 L 513 146 L 514 145 L 515 145 L 516 144 L 517 144 L 518 143 L 519 143 L 520 142 L 521 142 L 522 141 L 523 141 L 525 139 L 526 139 L 528 137 L 529 137 L 530 136 L 531 136 L 533 134 L 534 134 L 537 131 L 538 131 L 542 127 L 543 127 Z M 325 69 L 326 68 L 454 68 L 455 69 L 459 69 L 472 75 L 480 84 L 484 94 L 484 108 L 482 114 L 479 119 L 471 127 L 465 130 L 459 132 L 454 132 L 453 133 L 326 133 L 325 132 Z"
        fill="currentColor"
        fillRule="evenodd"
      />
    </svg>
  );
}

function MbexHeaderLogo() {
  const legacyLogoPath = "M703 276H772.5L829 190H830L886.324 276H956.5V275L865 136V135L953.808 0H883L830 81H829L776 0H705.5L776 107.5H556.5V52.5H703V0H486.5V34L481.5 26L476.5 20.5L470 14L466 11L460 7L454 4L444 0H193L144 182.5L94.7868 0H0V276H61V79H62L115 276H172.5L175.5 267L180 252.5L185.5 232L190.5 214L196 193.5L201.5 174.5L205.5 160.5L209 148.5L216 122.5L219 110L224.5 88L226 79V276.5H419L430 275.5L442 273L454 269.5L466 264L473 259.5L481 253L486 248H487V276H703ZM699 273L772.5 161H553.5V215H699V273ZM483 97V141L473.5 133L464.5 127.5L456 124L451.5 122.5V120.5L460 117L469 112L475.5 106L479 102L483 97ZM286 48H400L411.5 53.5L417.86 58.0299L421.668 63.0448L425 69.7313V82.2687L422.144 89.791L419.764 93.1343L415.955 96.8955L412.623 98.9851L406.911 101.493L398.342 104H286V48ZM286 151H394.5L403 152L408.5 153L417 157L424 162.5L428.5 169L430 172L432 177V192L431 195.5L429 201L426.5 205L422.5 209.5L419 212L413 215L404 218H286V151Z";

  return (
    <div className="header-logo-lockup" aria-label="MBEX Crypto Exchange" role="img">
      <svg aria-hidden="true" className="header-logo-mark" viewBox="0 0 957 277" xmlns="http://www.w3.org/2000/svg">
        <path className="header-logo-fill" d={legacyLogoPath} />
      </svg>
      <span className="header-logo-caption">Crypto Exchange</span>
    </div>
  );
}

function TabBar({ tab, setTab }) {
  const tabs = [
    { id: "home", label: "Главная", icon: Icons.home },
    { id: "history", label: "История", icon: Icons.history },
    { id: "profile", label: "Профиль", icon: Icons.user },
  ];

  return (
    <div className="tabbar">
      {tabs.map((item) => {
        const Icon = item.icon;
        const active = tab === item.id;
        return (
          <div key={item.id} className={`tab ${active ? "active" : ""}`} onClick={() => setTab(item.id)}>
            <Icon size={24} sw={active ? 2.1 : 1.8} />
            <span>{item.label}</span>
          </div>
        );
      })}
    </div>
  );
}

function AuthOverlay({ app }) {
  const [login, setLogin] = useState("");
  const [password, setPassword] = useState("");
  const [mode, setMode] = useState("login");
  const [registerMethod, setRegisterMethod] = useState("telegram");
  const [email, setEmail] = useState("");
  const [registerLogin, setRegisterLogin] = useState("");
  const [registerPassword, setRegisterPassword] = useState("");
  const [emailCode, setEmailCode] = useState("");
  const [emailCodeSent, setEmailCodeSent] = useState(false);
  const [localStatus, setLocalStatus] = useState(null);

  if (!app.authState.requiresLogin) {
    return null;
  }

  function showLocalStatus(text, tone) {
    setLocalStatus({ text, tone: tone || "info" });
  }

  function switchMode(nextMode) {
    setMode(nextMode);
    setLocalStatus(null);
  }

  function switchRegisterMethod(nextMethod) {
    setRegisterMethod(nextMethod);
    setLocalStatus(null);
  }

  async function handleLogin() {
    if (!login.trim() || !password.trim()) {
      app.pushToast("Введите логин и пароль", "error");
      showLocalStatus("Введите логин и пароль", "error");
      return;
    }
    try {
      await app.login(login.trim(), password);
    } catch (error) {
      // handled by bridge
    }
  }

  async function handleTelegram() {
    try {
      await app.startTelegramLogin();
      showLocalStatus("Подтвердите вход в Telegram-боте и вернитесь на эту страницу", "ok");
    } catch (error) {
      // handled by bridge
    }
  }

  async function handleEmailStart() {
    const emailValue = email.trim().toLowerCase();
    const loginValue = registerLogin.trim().toLowerCase();
    if (!emailValue || !loginValue || !registerPassword) {
      showLocalStatus("Заполните почту, логин и пароль", "error");
      return;
    }
    if (!/^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(emailValue)) {
      showLocalStatus("Введите корректную почту", "error");
      return;
    }
    if (!/^[a-z0-9_.-]{3,64}$/.test(loginValue)) {
      showLocalStatus("Логин: латиница, цифры, точка, дефис или подчёркивание", "error");
      return;
    }
    if (registerPassword.length < 8) {
      showLocalStatus("Пароль должен быть минимум 8 символов", "error");
      return;
    }
    try {
      await app.startEmailRegistration(emailValue, loginValue, registerPassword);
      setEmailCodeSent(true);
      showLocalStatus("Код отправлен на почту", "ok");
    } catch (error) {
      // handled by bridge
    }
  }

  async function handleEmailConfirm() {
    const emailValue = email.trim().toLowerCase();
    const codeValue = emailCode.trim().replace(/\s/g, "");
    if (!emailValue || !codeValue) {
      showLocalStatus("Введите код из письма", "error");
      return;
    }
    try {
      await app.confirmEmailRegistration(emailValue, codeValue);
    } catch (error) {
      // handled by bridge
    }
  }

  const status = localStatus || (app.authState.lastError ? { text: app.authState.lastError, tone: "error" } : null);
  const pending = app.authState.pending;

  return (
    <div className="auth-overlay">
      <div className="auth-sheet">
        <div className="auth-logo">
          <MbexLogo className="auth-logo-img" />
        </div>
        <div className="auth-subtitle">
          Быстрый обмен USDT с фиксацией курса и статусом заявки внутри Mini App.
        </div>
        <div className="auth-tabs">
          <button type="button" className={mode === "login" ? "is-active" : ""} onClick={() => switchMode("login")}>
            Вход
          </button>
          <button type="button" className={mode === "register" ? "is-active" : ""} onClick={() => switchMode("register")}>
            Регистрация
          </button>
        </div>

        {mode === "login" ? (
          <div className="auth-panel">
            <label className="auth-field">
              <span>Логин</span>
              <input
                className="field"
                placeholder="login"
                autoComplete="username"
                value={login}
                onChange={(event) => setLogin(event.target.value)}
              />
            </label>
            <label className="auth-field">
              <span>Пароль</span>
              <input
                className="field"
                type="password"
                placeholder="минимум 6 символов"
                autoComplete="current-password"
                value={password}
                onChange={(event) => setPassword(event.target.value)}
              />
            </label>
            <button className="btn btn-primary" disabled={pending} onClick={handleLogin}>
              {pending ? "Проверяем..." : "Войти"}
            </button>
            <button className="btn btn-ghost" disabled={pending} onClick={() => switchMode("register")}>
              Создать web-доступ
            </button>
          </div>
        ) : (
          <div className="auth-panel">
            <div className="auth-methods">
              <button
                type="button"
                className={registerMethod === "telegram" ? "is-active" : ""}
                onClick={() => switchRegisterMethod("telegram")}
              >
                Telegram
              </button>
              <button
                type="button"
                className={registerMethod === "email" ? "is-active" : ""}
                onClick={() => switchRegisterMethod("email")}
              >
                Email
              </button>
            </div>

            {registerMethod === "telegram" ? (
              <div className="auth-register-card">
                <div className="auth-register-icon">
                  <svg width="23" height="23" viewBox="0 0 24 24" fill="none" aria-hidden="true">
                    <path d="M21 4L3 11l5 2 2 6 3-4 4 3 4-14z" fill="#28A8E8" />
                  </svg>
                </div>
                <strong>Регистрация через Telegram</strong>
                <span>Откроем бота MBEX. После подтверждения web-сессия появится автоматически.</span>
                <button className="btn btn-primary auth-telegram-btn" disabled={pending} onClick={handleTelegram}>
                  {pending ? "Открываем..." : "Открыть Telegram"}
                </button>
              </div>
            ) : (
              <div className="auth-email-form">
                <label className="auth-field">
                  <span>Почта</span>
                  <input
                    className="field"
                    type="email"
                    inputMode="email"
                    placeholder="email@example.com"
                    autoComplete="email"
                    value={email}
                    onChange={(event) => setEmail(event.target.value)}
                  />
                </label>
                <label className="auth-field">
                  <span>Логин</span>
                  <input
                    className="field"
                    placeholder="latin_login"
                    autoComplete="username"
                    value={registerLogin}
                    onChange={(event) => setRegisterLogin(event.target.value)}
                  />
                </label>
                <label className="auth-field">
                  <span>Пароль</span>
                  <input
                    className="field"
                    type="password"
                    placeholder="минимум 8 символов"
                    autoComplete="new-password"
                    value={registerPassword}
                    onChange={(event) => setRegisterPassword(event.target.value)}
                  />
                </label>
                <button className="btn btn-ghost" disabled={pending} onClick={handleEmailStart}>
                  {emailCodeSent ? "Отправить код ещё раз" : "Получить код"}
                </button>
                {emailCodeSent ? (
                  <label className="auth-field auth-code-field">
                    <span>Код из письма</span>
                    <input
                      className="field"
                      inputMode="numeric"
                      placeholder="000000"
                      autoComplete="one-time-code"
                      value={emailCode}
                      onChange={(event) => setEmailCode(event.target.value)}
                    />
                  </label>
                ) : null}
                {emailCodeSent ? (
                  <button className="btn btn-primary" disabled={pending} onClick={handleEmailConfirm}>
                    {pending ? "Проверяем..." : "Подтвердить"}
                  </button>
                ) : null}
              </div>
            )}
          </div>
        )}
        {app.authState.telegramWaiting ? (
          <div className="auth-note">
            Подтвердите вход в боте и вернитесь в окно. После подтверждения приложение само подтянет web-сессию.
          </div>
        ) : null}
        {status ? (
          <div className={`auth-status ${status.tone ? `is-${status.tone}` : ""}`}>{status.text}</div>
        ) : null}
        <div className="auth-note">
          В Telegram Mini App вход идёт через Telegram. Web-версия использует отдельную клиентскую сессию.
        </div>
      </div>
    </div>
  );
}

function AppToast({ toast }) {
  if (!toast || !toast.message) {
    return null;
  }
  return (
    <div className={`toast is-visible ${toast.tone ? `is-${toast.tone}` : ""}`}>
      {toast.message}
    </div>
  );
}

function App() {
  const app = window.useMBEXApp();
  const [tab, setTabState] = useState("home");
  const [stack, setStack] = useState([]);
  const [viewMotion, setViewMotion] = useState({ phase: "idle", direction: "forward" });
  const [draft, setDraft] = useState(null);
  const [currentOrderId, setCurrentOrderId] = useState(null);
  const [dir, setDir] = useState("buy");
  const [payInput, setPayInput] = useState("");
  const transitionBusyRef = React.useRef(false);
  const transitionTimersRef = React.useRef([]);

  const currentOrder = useMemo(
    () => (app.privateState.orders || []).find((item) => item.id === currentOrderId) || null,
    [app.privateState.orders, currentOrderId],
  );

  function toggleTheme() {
    app.setTheme(app.theme === "dark" ? "light" : "dark");
  }

  function clearTransitionTimers() {
    transitionTimersRef.current.forEach((timer) => window.clearTimeout(timer));
    transitionTimersRef.current = [];
  }

  function transitionTo(direction, updateView) {
    const reduceMotion = window.matchMedia
      && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
    if (reduceMotion) {
      updateView();
      return;
    }
    if (transitionBusyRef.current) {
      return;
    }

    transitionBusyRef.current = true;
    setViewMotion({ phase: "leaving", direction });

    const leaveTimer = window.setTimeout(() => {
      const enterView = () => {
        updateView();
        setViewMotion({ phase: "entering", direction });
      };
      if (ReactDOM.flushSync) {
        ReactDOM.flushSync(enterView);
      } else {
        enterView();
      }

      const enterTimer = window.setTimeout(() => {
        setViewMotion({ phase: "idle", direction });
        transitionBusyRef.current = false;
        transitionTimersRef.current = [];
      }, 280);
      transitionTimersRef.current = [enterTimer];
    }, 110);
    transitionTimersRef.current = [leaveTimer];
  }

  function push(screenId) {
    transitionTo("forward", () => {
      setStack((prev) => [...prev, screenId]);
    });
  }

  function pop() {
    transitionTo("back", () => {
      setStack((prev) => prev.slice(0, -1));
    });
  }

  function closeWebApp() {
    try {
      if (window.Telegram && Telegram.WebApp && Telegram.WebApp.close) {
        Telegram.WebApp.close();
      }
    } catch (error) {
      // ignore
    }
  }

  function handleBackClose() {
    if (stack.length) {
      pop();
      return;
    }
    closeWebApp();
  }

  function setTab(nextTab) {
    if (nextTab === tab) {
      return;
    }
    const tabs = ["home", "history", "profile"];
    const direction = tabs.indexOf(nextTab) > tabs.indexOf(tab) ? "forward" : "back";
    transitionTo(direction, () => {
      setStack([]);
      setTabState(nextTab);
    });
  }

  function openOrder(orderId) {
    transitionTo("forward", () => {
      setCurrentOrderId(orderId);
      setStack(["status"]);
    });
  }

  function openCreate(nextDraft) {
    transitionTo("forward", () => {
      setDraft(nextDraft);
      setStack((prev) => [...prev, "create"]);
    });
  }

  async function submitCreate(payload) {
    if (!draft) {
      return;
    }
    try {
      let order = null;
      if (draft.dir === "buy") {
        order = await app.createBuyOrder({
          sumRub: payload.sumRub ?? draft.inputValue,
          fio: payload.fio,
          wallet: payload.wallet,
          delivery: payload.delivery,
          courierFio: payload.courierFio,
        });
      } else if (draft.dir === "sell") {
        order = await app.createSellOrder({
          fio: payload.fio,
          delivery: payload.delivery,
          courierFio: payload.courierFio,
          sumUsdt: payload.sumUsdt,
        });
      } else {
        return;
      }
      transitionTo("forward", () => {
        setCurrentOrderId(order.id);
        setStack(["status"]);
      });
    } catch (error) {
      // toast handled in bridge
    }
  }

  async function cancelCurrentOrder() {
    if (!currentOrder) {
      return;
    }
    try {
      await app.cancelOrder(currentOrder.id);
    } catch (error) {
      // toast handled in bridge
    }
  }

  function repeatCurrentOrder() {
    if (!currentOrder) {
      return;
    }
    if (currentOrder.typeKey === "transfer") {
      return;
    }
    const nextDir = currentOrder.typeKey === "sell" ? "sell" : "buy";
    const nextInput = nextDir === "sell"
      ? Number(currentOrder.sumUsdt || currentOrder.depositAmountReceived || 0)
      : Number(currentOrder.sumRub || 0);
    transitionTo("forward", () => {
      setDir(nextDir);
      setPayInput(nextInput > 0 ? String(nextInput) : "");
      setDraft({
        dir: nextDir,
        inputValue: nextInput,
        rate: Number(currentOrder.rate || (nextDir === "sell" ? app.publicState.rates.sell : app.publicState.rates.buy) || 0),
      });
      setStack(["create"]);
    });
  }

  const top = stack[stack.length - 1];
  const view = top || tab;
  const onTabRoot = ["home", "history", "profile"].includes(view);
  const headerTitle = onTabRoot
    ? null
    : (view === "status" && currentOrder
      ? `Заявка · ${window.MBEX.orderDisplayCode(currentOrder)}`
      : SUB_TITLES[view]);

  React.useLayoutEffect(() => {
    window.scrollTo(0, 0);
    const scroller = document.querySelector(".app-scroll");
    if (scroller) {
      scroller.scrollTo({ top: 0, left: 0, behavior: "auto" });
    }
  }, [view, currentOrderId]);

  useEffect(() => () => {
    clearTransitionTimers();
    transitionBusyRef.current = false;
  }, []);

  useEffect(() => {
    let backButton = null;
    let handleNativeBack = null;
    try {
      if (window.Telegram && Telegram.WebApp && Telegram.WebApp.BackButton) {
        backButton = Telegram.WebApp.BackButton;
        handleNativeBack = handleBackClose;
        backButton.onClick(handleNativeBack);
        if (stack.length) {
          backButton.show();
        } else if (backButton.hide) {
          backButton.hide();
        }
      }
    } catch (error) {
      backButton = null;
      handleNativeBack = null;
    }
    return () => {
      if (!backButton || !handleNativeBack) {
        return;
      }
      try {
        if (backButton.offClick) {
          backButton.offClick(handleNativeBack);
        }
        if (backButton.hide) {
          backButton.hide();
        }
      } catch (error) {
        // ignore
      }
    };
  }, [stack.length, tab]);

  let content = null;
  if (view === "home") {
    content = (
      <HomeScreen
        dir={dir}
        setDir={setDir}
        payInput={payInput}
        setPayInput={setPayInput}
        app={app}
        onCreate={openCreate}
        onOpenOrder={openOrder}
        nav={push}
      />
    );
  } else if (view === "history") {
    content = <HistoryScreen app={app} onOpenOrder={openOrder} />;
  } else if (view === "profile") {
    content = <ProfileScreen app={app} nav={push} />;
  } else if (view === "create") {
    content = draft ? <CreateOrderScreen draft={draft} app={app} onConfirm={submitCreate} nav={push} /> : null;
  } else if (view === "status") {
    content = <OrderStatusScreen order={currentOrder} app={app} onCancel={cancelCurrentOrder} onRepeat={repeatCurrentOrder} />;
  } else if (view === "referral") {
    content = <ReferralScreen app={app} nav={push} />;
  } else if (view === "loyalty") {
    content = <LoyaltyScreen app={app} />;
  } else if (view === "wallets") {
    content = <WalletsScreen app={app} />;
  } else if (view === "couriers") {
    content = <CouriersScreen app={app} />;
  } else if (view === "support") {
    content = <SupportScreen app={app} />;
  } else if (view === "offices") {
    content = <OfficesScreen app={app} />;
  } else if (view === "aml") {
    content = <AmlScreen app={app} />;
  }

  return (
    <div className="stage">
      <div className="device">
        <div className="screen">
          <div className="island" />
          <div className="statusbar">
            <span className="time num">21:03</span>
            <span className="glyphs">
              <svg width="18" height="11" viewBox="0 0 18 11" fill="currentColor"><rect x="0" y="7" width="3" height="4" rx=".5" /><rect x="4.5" y="5" width="3" height="6" rx=".5" /><rect x="9" y="2.5" width="3" height="8.5" rx=".5" /><rect x="13.5" y="0" width="3" height="11" rx=".5" /></svg>
              <svg width="22" height="11" viewBox="0 0 24 12" fill="none" stroke="currentColor"><rect x="1" y="1" width="19" height="10" rx="3" strokeWidth="1.2" opacity=".5" /><rect x="2.5" y="2.5" width="15" height="7" rx="1.5" fill="currentColor" /><rect x="21" y="4" width="2" height="4" rx="1" fill="currentColor" opacity=".5" /></svg>
            </span>
          </div>

          <div className={onTabRoot ? "app-scroll has-tabbar" : "app-scroll"}>
            <div
              key={`${view}:${view === "status" ? currentOrderId || "" : ""}`}
              className={`app-view is-${viewMotion.phase} is-${viewMotion.direction}`}
            >
              <div className="tg-header">
                {onTabRoot ? (
                  view === "profile" ? (
                    <div className="tg-title profile-root-title">Профиль</div>
                  ) : (
                    <div className="tg-brand">
                      <MbexHeaderLogo />
                    </div>
                  )
                ) : (
                  <>
                    <div className="tg-back" onClick={handleBackClose}><Icons.back size={22} sw={2.2} /></div>
                    <div className="tg-title" style={{ fontSize: 15, flex: 1, minWidth: 0, overflow: "hidden", textOverflow: "ellipsis" }}>
                      {headerTitle}
                    </div>
                  </>
                )}
                <div className="tg-actions">
                  <div className="tg-iconbtn" onClick={toggleTheme}>
                    {app.theme === "dark" ? <Icons.sun size={19} /> : <Icons.moon size={19} />}
                  </div>
                </div>
              </div>
              {content}
            </div>
          </div>

          {onTabRoot ? <TabBar tab={tab} setTab={setTab} /> : null}

          <div className="tg-foot">
            <Icons.bolt size={12} style={{ color: "var(--accent)" }} />
            @mbex_exchange_bot
          </div>

          <AuthOverlay app={app} />
          <AppToast toast={app.toast} />
        </div>
      </div>
    </div>
  );
}

ReactDOM.createRoot(document.getElementById("root")).render(<App />);
