<script setup lang="ts">
import { Close, Lock, Minus, User } from "@element-plus/icons-vue";
import { ElDialog, ElForm, ElMessage, ElProgress } from "element-plus";
// 报错统一走 host/dialog 原生 message，勿用 ElMessage.error
import { getVersion } from "@tauri-apps/api/app";
import { listen } from "@tauri-apps/api/event";
import { invoke } from "@tauri-apps/api/tauri";
import { computed, onMounted, onUnmounted, reactive, ref } from "vue";
import { api } from "../api";
import { confirmNative, showErrorNative, showInfoNative, showWarningNative } from "../host/dialog";
import { getAllConfig, mergeConfig } from "../host/config";
import { log } from "../host/logger";
import { setSession } from "../host/session";
import type { SessionState } from "../host/types";
import {
  closeWindow,
  minimizeWindow,
  openMainWindow,
  startWindowDragging,
} from "../host/window";

/** el-form 需要稳定引用，勿使用每次渲染新建的 `{ username, password }` 对象 */
const loginForm = reactive({
  username: "admin",
  password: "admin",
});
const loginType = ref("NSFW");
const isLoading = ref(false);
const formRef = ref<InstanceType<typeof ElForm>>();
const isLoginSuccessed = ref(false);
const selectedWin = ref("");
const cachedWinKey = ref("");
const options = ref<Array<{ label: string; value: string }>>([]);
const appVersion = ref("0.1.0");
const checkingUpdate = ref(false);
const ZYYUN_APT_SETUP_PROGRESS_EVENT = "zyyun-apt-setup-progress";

const aptSetupDialogVisible = ref(false);
const aptSetupPercent = ref(0);
const aptSetupHint = ref("");
const aptSetupFinished = ref(false);
const aptSetupProgressStatus = ref<"success" | "exception" | undefined>(undefined);

/** 默认紫云 apt 源行；可通过配置项 apt_source_deb_line 覆盖（见 ~/.config/com.ziyun.callclient/config.json） */
const DEFAULT_APT_SOURCE_DEB_LINE =
  "deb [arch=amd64 signed-by=/usr/share/keyrings/zyyun-archive-keyring.gpg] http://80.12.140.29:80/apt v10 main";
const aptSourceDebLine = ref(DEFAULT_APT_SOURCE_DEB_LINE);

interface AptUpdateCheckResult {
  packageName: string;
  currentVersion: string;
  installedVersion: string;
  candidateVersion: string;
  hasUpdate: boolean;
  sourceAvailable: boolean;
  updateCommand: string;
}

interface AptSetupProgressPayload {
  percent: number;
  message: string;
}

let sessionState: SessionState = {
  empUid: null,
  winUid: null,
  queueToken: null,
  refreshToken: null,
};

const rules = {
  username: [{ required: true, message: "请输入用户名", trigger: "blur" }],
  password: [
    { required: true, message: "请输入密码", trigger: "blur" },
    { min: 5, message: "密码长度不能少于5位", trigger: "blur" },
  ],
};

const isFormValid = computed(
  () => loginForm.username.trim() !== "" && loginForm.password.trim() !== "",
);
const isWindowSelected = computed(() => selectedWin.value !== "");

/**
 * 在窄窗口中使用居中消息，避免提示框被裁剪。
 */
function showMessage(type: "success" | "warning", message: string): void {
  ElMessage({
    type,
    message,
    offset: 52,
    grouping: true,
    customClass: "narrow-window-message",
  });
}

/**
 * 从窗口选择返回账号登录步骤。
 */
function backToUserForm(): void {
  isLoginSuccessed.value = false;
}

/**
 * 处理账号登录。
 */
async function handleLogin(): Promise<void> {
  if (!isFormValid.value) {
    showMessage("warning", "请输入用户名和密码");
    return;
  }

  const form = formRef.value;
  if (!form) {
    return;
  }

  isLoading.value = true;
  try {
    await form.validate();
  } catch {
    isLoading.value = false;
    return;
  }

  try {
    const loginRes = await api.user.login({
      loginMode: loginType.value,
      clientType: "CALLER",
      username: loginForm.username,
      password: loginForm.password,
      hallRegNum: "",
    });

    if (!loginRes?.queueToken) {
      await log(
        "warn",
        `登录失败: 接口未返回有效 queueToken, user=${loginForm.username}`,
      );
      await showErrorNative("登录失败：服务器未返回有效凭据，请稍后重试。", "登录");
      return;
    }

    sessionState = {
      empUid: loginRes.operatorProfile.empUid,
      /** 未选窗口前不写占位数字 0，避免与「无效窗口」混淆且与 MainView `<=0` 判定一致 */
      winUid: null,
      queueToken: loginRes.queueToken,
      refreshToken: loginRes.refreshToken,
    };

    await setSession(sessionState);

    const winList = await api.window.list();
    options.value = winList.windows.map((win) => ({
      label: win.windowName,
      value: win.windowUid.toString(),
    }));

    if (
      cachedWinKey.value &&
      options.value.some((item) => item.value === cachedWinKey.value)
    ) {
      selectedWin.value = cachedWinKey.value;
    }

    isLoginSuccessed.value = true;
    await log(
      "info",
      `登录成功: user=${loginForm.username}, empUid=${sessionState.empUid}`,
    );
  } catch (error) {
    const message = error instanceof Error ? error.message : String(error);
    await log("error", `登录失败: user=${loginForm.username}, ${message}`);
    await showErrorNative(message || "登录失败", "登录");
  } finally {
    isLoading.value = false;
  }
}

/**
 * 处理窗口登录确认。
 */
async function handleWindowLogin(): Promise<void> {
  isLoading.value = true;
  try {
    const winUid = Number.parseInt(selectedWin.value, 10);
    if (!Number.isFinite(winUid) || winUid <= 0) {
      showMessage("warning", "请选择有效窗口");
      return;
    }

    const selected = options.value.find(
      (item) => item.value === selectedWin.value,
    );

    const initRes = await api.action.init({
      empUid: Number(sessionState.empUid ?? -1),
      windowUid: winUid,
    });

    const initSuccess =
      ((initRes as { data?: { success?: boolean } }).data?.success ??
        (initRes as { success?: boolean }).success) === true;

    if (!initSuccess) {
      const initData = (initRes as { data?: { message?: string } }).data;
      const msg =
        (typeof initData?.message === "string" && initData.message.trim() !== ""
          ? initData.message
          : null) ??
        (typeof (initRes as { message?: string }).message === "string"
          ? (initRes as { message?: string }).message
          : null) ??
        "窗口初始化失败，请重试或更换窗口";
      await showErrorNative(String(msg), "窗口初始化");
      await log("warn", `call-terminal/init 未成功: windowUid=${winUid}`);
      return;
    }

    await mergeConfig({
      last_username: loginForm.username.trim(),
      selected_win_key: selectedWin.value,
      selected_win_value: selected?.label ?? "",
      selected_win_uid: winUid,
    });

    sessionState.winUid = winUid;
    await setSession(sessionState);

    // 登录完成后拉取 caller-init，并将返回 data 作为运行时缓存写入 session。
    try {
      const callerInit = await api.action.callerInit();
      const callerWin = Number(callerInit.windowUid);
      const resolvedWinUid =
        Number.isFinite(callerWin) && callerWin > 0 ? callerWin : winUid;
      const callerEmp = Number(callerInit.empUid);
      const resolvedEmpUid = Number.isFinite(callerEmp) ? callerEmp : Number(sessionState.empUid ?? -1);

      sessionState = {
        ...sessionState,
        winUid: resolvedWinUid,
        empUid: resolvedEmpUid,
        windowName: String(callerInit.windowName ?? ""),
        empName: String(callerInit.empName ?? ""),
        autoCallEnabled: Boolean(callerInit.autoCallEnabled),
        autoCallWaitSeconds: Number(callerInit.autoCallWaitSeconds ?? 0),
        autoStartEnabled: Boolean(callerInit.autoStartEnabled),
        autoStartWaitSeconds: Number(callerInit.autoStartWaitSeconds ?? 0),
        callInHistoryEnabled: Boolean(callerInit.callInHistoryEnabled),
        callNotifyForward: Number(callerInit.callNotifyForward ?? 0),
        callNotifyMode: Number(callerInit.callNotifyMode ?? 0),
        callNotifySmsUrl: String(callerInit.callNotifySmsUrl ?? ""),
        callTransferEnabled: Boolean(callerInit.callTransferEnabled),
        realnameCheckApi: String(callerInit.realnameCheckApi ?? ""),
        rankWaitSeconds: Number(callerInit.rankWaitSeconds ?? 0),
        ziyunServiceUrl: String(callerInit.ziyunServiceUrl ?? ""),
      };
      await setSession(sessionState);
      await log(
        "info",
        `caller-init 缓存完成: windowUid=${sessionState.winUid}, empUid=${sessionState.empUid}`,
      );
    } catch (error) {
      const message = error instanceof Error ? error.message : String(error);
      await log("warn", `caller-init 调用失败，继续使用本地会话: ${message}`);
    }

    await openMainWindow();
  } catch (error) {
    const message = error instanceof Error ? error.message : String(error);
    await showErrorNative(message || "打开主窗口失败", "打开主窗口");
    await log("error", `打开主窗口失败: ${message}`);
  } finally {
    isLoading.value = false;
  }
}

async function handleMinimizeClick(event: MouseEvent): Promise<void> {
  event.preventDefault();
  event.stopPropagation();
  try {
    await minimizeWindow();
  } catch (error) {
    const message = error instanceof Error ? error.message : String(error);
    await showErrorNative(message || "最小化窗口失败", "最小化");
    await log("error", `最小化窗口失败: ${message}`);
  }
}

async function handleCloseClick(event: MouseEvent): Promise<void> {
  event.preventDefault();
  event.stopPropagation();
  try {
    await closeWindow();
  } catch (error) {
    const message = error instanceof Error ? error.message : String(error);
    await showErrorNative(message || "关闭窗口失败", "关闭窗口");
    await log("error", `关闭窗口失败: ${message}`);
  }
}

async function handleDragMouseDown(event: MouseEvent): Promise<void> {
  if (event.button !== 0) {
    return;
  }
  try {
    await startWindowDragging();
  } catch {
    // 失败时仍可回退到 data-tauri-drag-region 行为。
  }
}

/**
 * 处理回车键触发登录。
 */
function handleKeyPress(event: KeyboardEvent): void {
  if (event.key === "Enter" && isFormValid.value && !isLoginSuccessed.value) {
    void handleLogin();
  }
}

/**
 * 聚焦时选中输入内容。
 */
function handleInputFocus(event: Event): void {
  const target = event.target as HTMLInputElement;
  target.select();
}

/**
 * 自动写入紫云 apt 源并 apt-get update；Rust 通过事件推送进度。
 */
async function runZyyunAptSourceSetupWithProgress(debLine: string): Promise<void> {
  aptSetupDialogVisible.value = true;
  aptSetupFinished.value = false;
  aptSetupPercent.value = 0;
  aptSetupHint.value = "准备中…";
  aptSetupProgressStatus.value = undefined;

  const unlisten = await listen<AptSetupProgressPayload>(ZYYUN_APT_SETUP_PROGRESS_EVENT, (e) => {
    const p = e.payload;
    aptSetupPercent.value = Math.min(100, Math.max(0, Number(p.percent) || 0));
    aptSetupHint.value = typeof p.message === "string" ? p.message : "";
  });

  const trimmed = debLine.trim();
  const debPreview =
    trimmed.length > 220 ? `${trimmed.slice(0, 220)}…(共 ${trimmed.length} 字符)` : trimmed;
  await log(
    "info",
    `[apt-setup][前端] 即将 invoke setup_zyyun_apt_source, debLen=${trimmed.length}, debPreview=${debPreview}`,
  );

  try {
    await invoke("setup_zyyun_apt_source", { debLine: trimmed });
    aptSetupProgressStatus.value = "success";
    await log("info", "[apt-setup][前端] setup_zyyun_apt_source invoke 成功结束");
  } catch (error) {
    aptSetupProgressStatus.value = "exception";
    const message = error instanceof Error ? error.message : String(error);
    await log("error", `[apt-setup][前端] setup_zyyun_apt_source invoke 失败: ${message}`);
    throw error;
  } finally {
    unlisten();
    aptSetupFinished.value = true;
  }
}

/**
 * 检查 apt 仓库中是否有新版本；配源与升级均在应用内由固定 Rust 脚本 + pkexec 完成，不向用户暴露可手写的 shell 命令。
 */
async function handleCheckUpdate(): Promise<void> {
  if (checkingUpdate.value) {
    return;
  }

  checkingUpdate.value = true;
  try {
    await log(
      "info",
      `检查更新(前端): 开始, package=call-client, currentVersion=${appVersion.value}`,
    );

    const invokeCheck = (): Promise<AptUpdateCheckResult> =>
      invoke<AptUpdateCheckResult>("check_apt_update", {
        packageName: "call-client",
        currentVersion: appVersion.value,
      });

    let result = await invokeCheck();
    await log(
      "info",
      `检查更新(前端): 首次 check_apt_update 返回 installed=${result.installedVersion}, candidate=${result.candidateVersion}, sourceAvailable=${result.sourceAvailable}, hasUpdate=${result.hasUpdate}`,
    );

    if (!result.sourceAvailable) {
      const cfg = await getAllConfig();
      const alreadyConfigured = cfg.zyyun_apt_source_configured === true;

      if (alreadyConfigured) {
        await log(
          "warn",
          "检查更新: 已记录自动配置过 apt 源，但候选版本仍不可用，请人工排查网络或 GPG 密钥",
        );
        await showWarningNative(
          "本机已自动配置过紫云软件源，但 apt 仍无法解析候选版本。请联系管理员检查内网仓库、网络或密钥文件；勿在终端自行执行来源不明的更新脚本。",
          "检查更新",
        );
        return;
      }

      const doConfigure = await confirmNative({
        title: "配置更新源",
        message:
          "未检测到可用更新源。是否使用管理员权限由本程序自动写入紫云软件源并执行 apt 更新？（将弹出 pkexec 授权，请输入管理员密码；无需在终端自行输入命令。）",
        okLabel: "开始配置",
        cancelLabel: "取消",
      });
      if (!doConfigure) {
        await log("info", "检查更新(前端): 用户在「配置更新源」对话框选择取消");
        await showInfoNative(
          [
            "未执行自动配置。稍后可再次点击「检查更新」，在提示中选择「开始配置」并输入管理员密码，",
            "由本程序自动完成软件源与索引更新。",
            "",
            "请勿在终端自行编写或执行未经验证的更新命令；若仍无法使用，请联系管理员。",
          ].join("\n"),
          "更新源未配置",
        );
        return;
      }

      await log("info", "检查更新(前端): 用户确认自动配置 apt 源，开始 runZyyunAptSourceSetupWithProgress");
      await runZyyunAptSourceSetupWithProgress(aptSourceDebLine.value);
      await mergeConfig({ zyyun_apt_source_configured: true });
      await log("info", "已写入配置: zyyun_apt_source_configured=true");

      result = await invokeCheck();
      await log(
        "info",
        `检查更新(前端): 自动配置后再次 check_apt_update 返回 installed=${result.installedVersion}, candidate=${result.candidateVersion}, sourceAvailable=${result.sourceAvailable}, hasUpdate=${result.hasUpdate}`,
      );

      if (!result.sourceAvailable) {
        await log("warn", "自动配置 apt 源后仍无法解析候选版本");
        await showErrorNative(
          [
            "自动配置已完成，但 apt 仍无法解析候选版本。",
            "请联系管理员检查内网 apt 仓库、GPG 与网络；请勿在终端自行执行未经验证的安装脚本。",
            "",
            "您可稍后再次点击「检查更新」重试。",
          ].join("\n"),
          "更新源不可用",
          { logActions: "file" },
        );
        return;
      }
    }

    if (!result.hasUpdate) {
      await log("info", `检查更新提示: 当前已是最新版本, version=${result.installedVersion}`);
      showMessage("success", `当前已是最新版本（${result.installedVersion}）`);
      return;
    }

    await log(
      "info",
      `检查更新提示: 检测到新版本, installed=${result.installedVersion}, candidate=${result.candidateVersion}`,
    );
    const doUpgrade = await confirmNative({
      title: "发现新版本",
      message: [
        `检测到新版本：${result.candidateVersion}`,
        `当前已安装：${result.installedVersion}`,
        "",
        "升级将由本程序在授权后固定执行（更新索引并仅升级 call-client），需在弹出框中输入管理员密码。",
        "请勿在终端自行编写或执行更新脚本。",
      ].join("\n"),
      okLabel: "应用内升级",
      cancelLabel: "稍后再说",
    });
    if (!doUpgrade) {
      await log("info", "检查更新(前端): 用户选择稍后再升级");
      return;
    }

    await log(
      "info",
      "检查更新(前端): 用户选择应用内 apt 升级（invoke upgrade_call_client_via_apt）",
    );
    await invoke("upgrade_call_client_via_apt");
    await log("info", "检查更新(前端): upgrade_call_client_via_apt 已成功返回");
    try {
      appVersion.value = await getVersion();
    } catch {
      // 忽略版本读取失败
    }
    showMessage(
      "success",
      `升级已执行。界面显示版本：${appVersion.value}。若仍为旧版本，请重启本客户端后再试。`,
    );
  } catch (error) {
    const message = error instanceof Error ? error.message : String(error);
    await showErrorNative(`检查更新失败：${message}`, "检查更新", {
      logActions: "file",
    });
    await log("error", `检查更新失败: ${message}`);
  } finally {
    checkingUpdate.value = false;
  }
}

onMounted(async () => {
  try {
    appVersion.value = await getVersion();
  } catch {
    appVersion.value = "0.1.0";
  }

  const config = await getAllConfig();
  if (
    typeof config.apt_source_deb_line === "string" &&
    config.apt_source_deb_line.trim() !== ""
  ) {
    aptSourceDebLine.value = config.apt_source_deb_line.trim();
  }
  if (typeof config.last_username === "string" && config.last_username.trim()) {
    loginForm.username = config.last_username;
  }
  if (
    typeof config.selected_win_key === "string" &&
    config.selected_win_key.trim()
  ) {
    cachedWinKey.value = config.selected_win_key;
    selectedWin.value = config.selected_win_key;
  }
  window.addEventListener("keydown", handleKeyPress);
});

onUnmounted(() => {
  window.removeEventListener("keydown", handleKeyPress);
});
</script>

<template>
  <div class="login-container">
    <div class="background-elements">
      <div class="circle circle-1"></div>
      <div class="circle circle-2"></div>
    </div>

    <div class="login-header">
      <div
        class="login-header-drag"
        data-tauri-drag-region
        @dblclick.prevent.stop
        @mousedown="handleDragMouseDown"
      ></div>
      <div class="login-header-actions">
        <button
          class="control-button"
          type="button"
          @mousedown.stop
          @click="handleMinimizeClick"
        >
          <el-icon class="control-icon">
            <component :is="Minus" />
          </el-icon>
        </button>
        <button
          class="control-button"
          type="button"
          @mousedown.stop
          @dblclick.prevent.stop
          @click="handleCloseClick"
        >
          <el-icon class="control-icon">
            <component :is="Close" />
          </el-icon>
        </button>
      </div>
    </div>

    <div class="login-main">
      <div
        class="header-section"
        data-tauri-drag-region
        @dblclick.prevent.stop
        @mousedown="handleDragMouseDown"
      >
        <div class="app-info" data-tauri-drag-region>
          <h1 class="app-title" data-tauri-drag-region>紫云智慧大厅</h1>
          <h2 class="app-subtitle" data-tauri-drag-region>呼叫客户端系统</h2>
        </div>
      </div>

      <div class="form-section">
        <div class="form-wrapper">
          <div v-show="!isLoginSuccessed" class="user-form">
            <div class="form-header">
              <p class="form-subtitle">请选择登录方式并输入账号信息</p>
            </div>

            <div class="type-selector">
              <el-radio-group v-model="loginType" size="large">
                <el-radio-button value="NSFW">综合管理平台账号</el-radio-button>
                <el-radio-button value="QUEUE">自建账号</el-radio-button>
              </el-radio-group>
            </div>

            <el-form
              ref="formRef"
              :model="loginForm"
              :rules="rules"
              class="login-form"
              label-position="top"
              @submit.prevent
            >
              <el-form-item label="账号" prop="username">
                <el-input
                  v-model="loginForm.username"
                  :prefix-icon="User"
                  placeholder="请输入用户名/手机号"
                  size="large"
                  @focus="handleInputFocus"
                />
              </el-form-item>

              <el-form-item label="密码" prop="password">
                <el-input
                  v-model="loginForm.password"
                  :prefix-icon="Lock"
                  type="password"
                  placeholder="请输入登录密码"
                  size="large"
                  show-password
                  @focus="handleInputFocus"
                />
              </el-form-item>

              <div class="form-actions">
                <el-button
                  type="primary"
                  size="large"
                  :loading="isLoading"
                  :disabled="!isFormValid"
                  class="login-button"
                  @click="handleLogin"
                >
                  {{ isLoading ? "登录中..." : "立即登录" }}
                </el-button>
              </div>
            </el-form>
          </div>

          <div v-show="isLoginSuccessed" class="window-form">
            <div class="form-header">
              <p class="form-subtitle">请选择登录窗口</p>
            </div>
            <el-form>
              <el-form-item class="window-select-item">
                <el-select
                  v-model="selectedWin"
                  placeholder="请选择登录窗口"
                  size="large"
                >
                  <el-option
                    v-for="item in options"
                    :key="item.value"
                    :label="item.label"
                    :value="item.value"
                  />
                </el-select>
              </el-form-item>
              <div class="form-actions">
                <el-button
                  type="primary"
                  size="large"
                  :loading="isLoading"
                  :disabled="!isWindowSelected"
                  class="login-button"
                  @click="handleWindowLogin"
                >
                  {{ isLoading ? "登录中..." : "立即登录" }}
                </el-button>
              </div>
              <div class="form-actions">
                <el-button
                  type="primary"
                  size="large"
                  class="login-button"
                  @click="backToUserForm"
                >
                  返回
                </el-button>
              </div>
            </el-form>
          </div>

          <div class="version-info">
            <div class="version-row">
              <div class="version">版本号：V{{ appVersion }}</div>
              <el-button
                text
                type="primary"
                size="small"
                :loading="checkingUpdate"
                @click="handleCheckUpdate"
              >
                检查更新
              </el-button>
            </div>
            <div class="copyright">© 2023 紫云科技 版权所有</div>
          </div>
        </div>
      </div>
    </div>

      <el-dialog
        v-model="aptSetupDialogVisible"
        title="正在配置更新源"
        width="440px"
        class="apt-setup-dialog"
        :close-on-click-modal="false"
        :close-on-press-escape="aptSetupFinished"
        :show-close="aptSetupFinished"
      >
        <el-progress
          :percentage="aptSetupPercent"
          :status="aptSetupProgressStatus"
          :stroke-width="16"
        />
        <p class="apt-setup-hint">{{ aptSetupHint }}</p>
      </el-dialog>
    </div>
</template>

<style lang="scss" scoped>
.login-container {
  width: 100vw;
  height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-start;
  background: linear-gradient(135deg, #004d99 0%, #003b7a 100%);
  overflow: hidden;
  position: relative;
  border-radius: 5px;
  padding: 0 16px;
}

.background-elements {
  position: absolute;
  width: 100%;
  height: 100%;
  pointer-events: none;

  .circle {
    position: absolute;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.1);

    &.circle-1 {
      width: 300px;
      height: 300px;
      top: -100px;
      left: -100px;
    }

    &.circle-2 {
      width: 200px;
      height: 200px;
      right: -80px;
      bottom: -80px;
    }
  }
}

.login-header {
  width: 100%;
  height: 32px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-shrink: 0;
}

.login-header-drag {
  flex: 1;
  height: 100%;
}

.login-header-actions {
  display: flex;
  align-items: center;
}

.control-button {
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: white;
  border-radius: 4px;
  -webkit-app-region: no-drag;
  border: none;
  background: transparent;
  cursor: pointer;
}

.control-button,
.control-button * {
  cursor: pointer;
}

.control-button:hover {
  background: rgba(255, 255, 255, 0.1);
}

.control-icon {
  font-size: 20px;
}

.login-main {
  width: 100%;
  max-width: 420px;
  z-index: 1;
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding-bottom: 16px;
}

.header-section {
  text-align: center;
  margin-bottom: 10px;
  position: relative;
  z-index: 2;
}

.app-title {
  font-size: 28px;
  font-weight: 700;
  color: white;
  margin-bottom: 8px;
}

.app-subtitle {
  font-size: 16px;
  color: rgba(255, 255, 255, 0.9);
  font-weight: 500;
}

.form-wrapper {
  background: rgba(255, 255, 255, 0.95);
  border-radius: 5px;
  padding: 28px 30px 22px;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
}

.form-header {
  text-align: center;
  margin-bottom: 25px;
}

.form-subtitle {
  color: #666;
  font-size: 13px;
}

.type-selector {
  margin-bottom: 25px;

  :deep(.el-radio-group) {
    width: 100%;
  }

  :deep(.el-radio-button) {
    flex: 1;
  }

  :deep(.el-radio-button__inner) {
    width: 100%;
  }
}

.form-actions {
  .login-button {
    width: 100%;
    margin-top: 10px;
  }
}

.window-select-item {
  margin: 80px 0;
}

.version-info {
  margin-top: 18px;
  text-align: center;
  color: #999;
  font-size: 12px;
  padding-top: 10px;
  border-top: 1px solid rgba(0, 0, 0, 0.1);
}

.version-row {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
}

.version {
  margin-bottom: 0;
}

.copyright {
  margin-top: 5px;
}

.apt-setup-hint {
  margin-top: 12px;
  font-size: 13px;
  color: #606266;
  line-height: 1.45;
}

:global(.narrow-window-message) {
  min-width: 0 !important;
  width: calc(100vw - 32px) !important;
  left: 16px !important;
  right: 16px !important;
}
</style>
