<script setup lang="ts">
import { ref, onMounted, computed } from 'vue';
import { useRouter } from 'vue-router';
import { ElMessage, ElMessageBox } from 'element-plus';
import { useAdminLocale } from '../composables/useAdminLocale';
import { resolveFormError } from '../i18n/form-validation';
import api from '../api';
import { clearStaffSession } from '../stores/auth';

const { t, localeTag } = useAdminLocale();
const router = useRouter();
import {
  emptyPlayerCreateForm,
  emptyPlayerEditForm,
  editFormFromDetail,
  buildCreatePlayerPayload,
  type PlayerRow,
  type PlayerDetail,
  type PlayerCreateForm,
  type PlayerEditForm,
} from './user-form.ts';
import {
  formatAmount,
  formatAmountFull,
  shouldCompactAmount as shouldCompact,
} from '../utils/format-amount';
import AdminTableEmpty from '../components/AdminTableEmpty.vue';
import WalletTransferContext from '../components/WalletTransferContext.vue';
import { useAdminPlayerTransfer } from '../composables/useAdminPlayerTransfer';

const users = ref<PlayerRow[]>([]);
const total = ref(0);
const page = ref(1);
const pageSize = ref(10);
const keyword = ref('');
const filterStatus = ref('');
const filterParentId = ref('');

const agentOptions = ref<{ id: string; username: string }[]>([]);

const createVisible = ref(false);
const editVisible = ref(false);
const detailVisible = ref(false);
const createLoading = ref(false);
const editLoading = ref(false);

const createForm = ref<PlayerCreateForm>(emptyPlayerCreateForm());
const editForm = ref<PlayerEditForm>(emptyPlayerEditForm());
const detail = ref<PlayerDetail | null>(null);
const editingId = ref('');

const {
  transferVisible,
  transferLoading,
  transferType,
  transferTarget,
  transferAmount,
  transferRemark,
  transferContext,
  transferContextLoading,
  transferAmountRange,
  transferAmountDisabled,
  transferTitle,
  openTransfer,
  submitTransfer,
} = useAdminPlayerTransfer(() => load());

const playerSettings = ref({ allowPasswordChange: true, allowUsernameChange: false });
const bettingLimits = ref({
  minStake: 1,
  maxStakeSingle: 50000,
  maxStakeParlay: 20000,
  maxPayoutSingle: 500000,
  maxPayoutParlay: 1000000,
  dailyStakeLimit: 200000,
});
const settingsSaving = ref(false);
const limitsSaving = ref(false);
const resetAllowed = ref(false);
const resetLoading = ref(false);
const resetConfirmPhrase = ref('');
const settingsCollapseOpen = ref<string[]>([]);

onMounted(() => {
  loadAgentOptions();
  loadPlayerSettings();
  loadBettingLimits();
  loadResetDatabaseStatus();
  load();
});

async function loadResetDatabaseStatus() {
  try {
    const { data } = await api.get('/admin/system/reset-database');
    resetAllowed.value = !!data.data?.allowed;
  } catch {
    resetAllowed.value = false;
  }
}

async function resetDatabase() {
  if (resetConfirmPhrase.value !== 'RESET') {
    ElMessage.warning(t('user.reset_database_confirm_label'));
    return;
  }
  try {
    await ElMessageBox.confirm(t('user.reset_database_hint'), t('user.reset_database'), {
      type: 'warning',
      confirmButtonText: t('user.reset_database_btn'),
      cancelButtonText: t('common.cancel'),
    });
  } catch {
    return;
  }

  resetLoading.value = true;
  try {
    const { data } = await api.post('/admin/system/reset-database', {
      confirmPhrase: 'RESET',
    });
    const accounts: string[] = data.data?.demoAccounts ?? [];
    ElMessage.success({
      message: `${t('user.reset_database_success')}\n${t('user.reset_database_accounts')}: ${accounts.join(' · ')}`,
      duration: 8000,
    });
    clearStaffSession();
    await router.push('/login');
  } catch (e: unknown) {
    const err = e as { response?: { data?: { error?: string } } };
    ElMessage.error(err.response?.data?.error ?? t('msg.save_failed'));
  } finally {
    resetLoading.value = false;
  }
}

async function loadBettingLimits() {
  try {
    const { data } = await api.get('/admin/settings/betting-limits');
    bettingLimits.value = data.data;
  } catch {
    /* 使用默认值 */
  }
}

async function saveBettingLimits() {
  limitsSaving.value = true;
  try {
    const { data } = await api.put('/admin/settings/betting-limits', bettingLimits.value);
    bettingLimits.value = data.data;
    ElMessage.success(t('msg.saved'));
  } catch (e: unknown) {
    const err = e as { response?: { data?: { error?: string } } };
    ElMessage.error(err.response?.data?.error ?? t('msg.save_failed'));
    loadBettingLimits();
  } finally {
    limitsSaving.value = false;
  }
}

async function loadPlayerSettings() {
  try {
    const { data } = await api.get('/admin/users/settings/account');
    playerSettings.value = data.data;
  } catch {
    /* 使用默认值 */
  }
}

async function savePlayerSettings() {
  settingsSaving.value = true;
  try {
    const { data } = await api.put('/admin/users/settings/account', playerSettings.value);
    playerSettings.value = data.data;
    ElMessage.success(t('msg.saved'));
  } catch (e: unknown) {
    const err = e as { response?: { data?: { error?: string } } };
    ElMessage.error(err.response?.data?.error ?? t('msg.save_failed'));
    loadPlayerSettings();
  } finally {
    settingsSaving.value = false;
  }
}

async function loadAgentOptions() {
  const { data } = await api.get('/admin/agents/options');
  agentOptions.value = data.data;
}

async function load() {
  const { data } = await api.get('/admin/users', {
    params: {
      page: page.value,
      pageSize: pageSize.value,
      keyword: keyword.value || undefined,
      status: filterStatus.value || undefined,
      parentId: filterParentId.value || undefined,
    },
  });
  users.value = data.data.items;
  total.value = data.data.total;
}

function onPageChange(p: number) {
  page.value = p;
  load();
}

function onSizeChange(size: number) {
  pageSize.value = size;
  page.value = 1;
  load();
}

function openCreate() {
  createForm.value = emptyPlayerCreateForm();
  createVisible.value = true;
}

function parentLabel(row: PlayerRow) {
  return row.parentUsername ?? t('common.platform_direct');
}

async function openDetail(id: string) {
  const { data } = await api.get(`/admin/users/${id}`);
  detail.value = data.data as PlayerDetail;
  detailVisible.value = true;
}

async function openEdit(id: string) {
  const { data } = await api.get(`/admin/users/${id}`);
  const d = data.data as PlayerDetail;
  editingId.value = id;
  editForm.value = editFormFromDetail(d);
  editVisible.value = true;
}

async function submitCreate() {
  let payload: ReturnType<typeof buildCreatePlayerPayload>;
  try {
    payload = buildCreatePlayerPayload(createForm.value);
  } catch (e) {
    ElMessage.warning(resolveFormError(e, t));
    return;
  }
  createLoading.value = true;
  try {
    await api.post('/admin/users', payload);
    ElMessage.success(
      createForm.value.asTier1Agent
        ? t('msg.agent_created')
        : t('user.msg.created_with_password', { password: createForm.value.password }),
    );
    createVisible.value = false;
    load();
  } catch (e: unknown) {
    const err = e as { response?: { data?: { error?: string } } };
    ElMessage.error(err.response?.data?.error ?? t('msg.create_failed'));
  } finally {
    createLoading.value = false;
  }
}

async function toggleFreeze(row: PlayerRow) {
  const freeze = row.status === 'ACTIVE';
  const action = freeze ? t('common.freeze') : t('common.unfreeze');
  try {
    await ElMessageBox.confirm(
      t('msg.freeze_confirm_body', {
        action,
        name: row.username,
        extra: freeze ? t('msg.freeze_extra') : '',
      }),
      t('msg.freeze_confirm_title', { action }),
      { type: 'warning', confirmButtonText: action, cancelButtonText: t('common.cancel') },
    );
  } catch {
    return;
  }
  try {
    await api.put(`/admin/users/${row.id}`, {
      status: freeze ? 'SUSPENDED' : 'ACTIVE',
    });
    ElMessage.success(t('msg.freeze_done', { action }));
    load();
  } catch (e: unknown) {
    const err = e as { response?: { data?: { error?: string } } };
    ElMessage.error(err.response?.data?.error ?? t('msg.freeze_failed', { action }));
  }
}

async function submitEdit() {
  if (editForm.value.newPassword && editForm.value.newPassword.length < 8) {
    ElMessage.warning(t('err.password_min'));
    return;
  }
  editLoading.value = true;
  try {
    const newPwd = editForm.value.newPassword.trim();
    const { data } = await api.put(`/admin/users/${editingId.value}`, {
      username: editForm.value.username.trim(),
      parentId: editForm.value.parentId || '',
      phone: editForm.value.phone.trim() || undefined,
      email: editForm.value.email.trim() || undefined,
      password: newPwd || undefined,
    });
    const updated = data.data as PlayerDetail;
    if (newPwd) {
      editForm.value.managedPassword = updated.managedPassword ?? newPwd;
      editForm.value.newPassword = '';
      ElMessage.success(t('user.msg.password_saved', { password: editForm.value.managedPassword }));
      return;
    }
    ElMessage.success(t('msg.saved'));
    editVisible.value = false;
    load();
  } catch (e: unknown) {
    const err = e as { response?: { data?: { error?: string } } };
    ElMessage.error(err.response?.data?.error ?? t('msg.save_failed'));
  } finally {
    editLoading.value = false;
  }
}

function formatTime(v: string) {
  if (!v) return '—';
  return new Date(v).toLocaleString(localeTag.value);
}

function formatLastLogin(v: string | null) {
  if (!v) return t('common.never_login');
  const d = new Date(v);
  const now = new Date();
  const sameDay =
    d.getFullYear() === now.getFullYear() &&
    d.getMonth() === now.getMonth() &&
    d.getDate() === now.getDate();
  if (sameDay) {
    return d.toLocaleTimeString(localeTag.value, { hour: '2-digit', minute: '2-digit' });
  }
  return d.toLocaleString(localeTag.value, {
    month: '2-digit',
    day: '2-digit',
    hour: '2-digit',
    minute: '2-digit',
  });
}

function statusTagType(s: string) {
  return s === 'ACTIVE' ? 'success' : 'warning';
}

function statusLabel(s: string) {
  const key = `user.status.${s}`;
  const v = t(key);
  return v !== key ? v : s;
}
</script>

<template>
  <div class="admin-list-page users-page">
  <el-collapse v-model="settingsCollapseOpen" class="list-settings">
    <el-collapse-item :title="t('user.page_settings')" name="settings">
      <div class="list-settings-block">
        <p class="list-settings-title">{{ t('user.global_settings') }}</p>
        <el-form inline size="small" class="settings-form">
          <el-form-item :label="t('user.field.allow_password_change')">
            <el-switch
              v-model="playerSettings.allowPasswordChange"
              :loading="settingsSaving"
              @change="savePlayerSettings"
            />
          </el-form-item>
          <el-form-item :label="t('user.field.allow_username_change')">
            <el-switch
              v-model="playerSettings.allowUsernameChange"
              :loading="settingsSaving"
              @change="savePlayerSettings"
            />
          </el-form-item>
        </el-form>
      </div>
      <div class="list-settings-block">
        <p class="list-settings-title">{{ t('user.betting_limits') }}</p>
        <el-form inline size="small" class="settings-form limits-form">
          <el-form-item :label="t('user.limit.min_stake')">
            <el-input-number v-model="bettingLimits.minStake" :min="0" :step="1" controls-position="right" />
          </el-form-item>
          <el-form-item :label="t('user.limit.max_stake_single')">
            <el-input-number v-model="bettingLimits.maxStakeSingle" :min="0" :step="100" controls-position="right" />
          </el-form-item>
          <el-form-item :label="t('user.limit.max_stake_parlay')">
            <el-input-number v-model="bettingLimits.maxStakeParlay" :min="0" :step="100" controls-position="right" />
          </el-form-item>
          <el-form-item :label="t('user.limit.max_payout_single')">
            <el-input-number v-model="bettingLimits.maxPayoutSingle" :min="0" :step="1000" controls-position="right" />
          </el-form-item>
          <el-form-item :label="t('user.limit.max_payout_parlay')">
            <el-input-number v-model="bettingLimits.maxPayoutParlay" :min="0" :step="1000" controls-position="right" />
          </el-form-item>
          <el-form-item :label="t('user.limit.daily_stake')">
            <el-input-number v-model="bettingLimits.dailyStakeLimit" :min="0" :step="1000" controls-position="right" />
          </el-form-item>
          <el-form-item>
            <el-button type="primary" :loading="limitsSaving" @click="saveBettingLimits">
              {{ t('common.save') }}
            </el-button>
          </el-form-item>
        </el-form>
      </div>
      <div class="list-settings-block list-settings-block--danger">
        <p class="list-settings-title">{{ t('user.reset_database') }}</p>
        <p class="list-settings-hint">{{ t('user.reset_database_hint') }}</p>
        <el-alert
          v-if="!resetAllowed"
          type="warning"
          :closable="false"
          show-icon
          class="reset-db-alert"
          :title="t('user.reset_database_disabled_prod')"
        />
        <el-form inline size="small" class="settings-form reset-db-form">
          <el-form-item :label="t('user.reset_database_confirm_label')">
            <el-input
              v-model="resetConfirmPhrase"
              :placeholder="t('user.reset_database_confirm_ph')"
              style="width: 160px"
              :disabled="!resetAllowed"
              autocomplete="off"
            />
          </el-form-item>
          <el-form-item>
            <el-button
              type="danger"
              plain
              :loading="resetLoading"
              :disabled="!resetAllowed || resetConfirmPhrase !== 'RESET'"
              @click="resetDatabase"
            >
              {{ t('user.reset_database_btn') }}
            </el-button>
          </el-form-item>
        </el-form>
      </div>
    </el-collapse-item>
  </el-collapse>

  <div class="list-chrome">
    <div class="list-chrome__row">
      <el-form inline class="list-chrome__grow">
        <el-form-item :label="t('common.keyword')">
          <el-input
            v-model="keyword"
            :placeholder="t('user.filter.username_ph')"
            clearable
            style="width: 160px"
            @keyup.enter="load"
          />
        </el-form-item>
        <el-form-item :label="t('user.filter.agent')">
          <el-select
            v-model="filterParentId"
            :placeholder="t('user.filter.agent_ph')"
            clearable
            style="width: 180px"
          >
            <el-option
              v-for="a in agentOptions"
              :key="a.id"
              :label="a.username"
              :value="a.id"
            />
          </el-select>
        </el-form-item>
        <el-form-item :label="t('common.status')">
          <el-select v-model="filterStatus" :placeholder="t('common.all')" clearable style="width: 120px">
            <el-option :label="t('user.status.ACTIVE')" value="ACTIVE" />
            <el-option :label="t('user.status.SUSPENDED')" value="SUSPENDED" />
          </el-select>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="load">{{ t('common.search') }}</el-button>
        </el-form-item>
      </el-form>
      <div class="list-chrome__actions">
        <el-button type="primary" @click="openCreate">{{ t('user.create_btn') }}</el-button>
      </div>
    </div>
  </div>

  <section class="list-panel">
    <div class="table-wrap">
    <el-table :data="users" stripe>
      <template #empty>
        <AdminTableEmpty />
      </template>
      <el-table-column prop="id" label="ID" width="72" />
      <el-table-column prop="username" :label="t('user.col.username')" min-width="120" />
      <el-table-column :label="t('common.status')" width="88">
        <template #default="{ row }">
          <el-tag :type="statusTagType(row.status)" size="small">
            {{ statusLabel(row.status) }}
          </el-tag>
        </template>
      </el-table-column>
      <el-table-column :label="t('user.col.agent')" min-width="120">
        <template #default="{ row }">{{ parentLabel(row) }}</template>
      </el-table-column>
      <el-table-column :label="t('user.col.balance')" min-width="128" align="right">
        <template #default="{ row }">
          <el-tooltip
            :content="`${formatAmountFull(row.availableBalance)} / ${formatAmountFull(row.frozenBalance)}`"
            placement="top"
          >
            <span class="amount-compact">
              {{ formatAmount(row.availableBalance) }} / {{ formatAmount(row.frozenBalance) }}
            </span>
          </el-tooltip>
        </template>
      </el-table-column>
      <el-table-column prop="betCount" :label="t('user.col.bets')" width="64" align="center" />
      <el-table-column :label="t('user.col.stake_payout')" min-width="108" align="right">
        <template #default="{ row }">
          <span class="amount-compact">
            {{ formatAmount(row.totalStake) }} / {{ formatAmount(row.totalReturn) }}
          </span>
        </template>
      </el-table-column>
      <el-table-column :label="t('user.col.last_login')" width="108">
        <template #default="{ row }">
          <el-tooltip v-if="row.lastLoginAt" :content="formatTime(row.lastLoginAt)" placement="top">
            <span>{{ formatLastLogin(row.lastLoginAt) }}</span>
          </el-tooltip>
          <span v-else class="text-muted">{{ t('common.never_login') }}</span>
        </template>
      </el-table-column>
      <el-table-column :label="t('user.col.created')" width="108">
        <template #default="{ row }">
          <el-tooltip :content="formatTime(row.createdAt)" placement="top">
            <span>{{ formatLastLogin(row.createdAt) }}</span>
          </el-tooltip>
        </template>
      </el-table-column>
      <el-table-column :label="t('common.actions')" width="340" fixed="right" align="center">
        <template #default="{ row }">
          <el-button size="small" link type="primary" @click="openDetail(row.id)">{{ t('common.detail') }}</el-button>
          <el-button size="small" link type="primary" @click="openEdit(row.id)">{{ t('common.edit') }}</el-button>
          <el-button size="small" link type="success" @click="openTransfer('deposit', row)">{{ t('common.topup') }}</el-button>
          <el-button size="small" link type="warning" @click="openTransfer('withdraw', row)">{{ t('agent_portal.withdraw_btn_label') }}</el-button>
          <el-button
            v-if="row.status === 'ACTIVE'"
            size="small"
            link
            type="warning"
            @click="toggleFreeze(row)"
          >
            {{ t('common.freeze') }}
          </el-button>
          <el-button
            v-else
            size="small"
            link
            type="primary"
            @click="toggleFreeze(row)"
          >
            {{ t('common.unfreeze') }}
          </el-button>
        </template>
      </el-table-column>
    </el-table>
    </div>
    <div class="pager">
      <el-pagination
        v-model:current-page="page"
        v-model:page-size="pageSize"
        :total="total"
        :page-sizes="[10, 20, 50, 100]"
        layout="total, sizes, prev, pager, next"
        background
        @current-change="onPageChange"
        @size-change="onSizeChange"
      />
    </div>
  </section>

  <el-dialog v-model="createVisible" :title="t('user.dialog.create')" width="520px" destroy-on-close>
    <el-form label-width="100px">
      <el-form-item :label="t('user.col.username')" required>
        <el-input v-model="createForm.username" :placeholder="t('user.ph.username_unique')" />
      </el-form-item>
      <el-form-item :label="t('user.field.password')" required>
        <el-input v-model="createForm.password" type="text" autocomplete="off" />
      </el-form-item>
      <el-form-item :label="t('user.field.confirm_password')" required>
        <el-input v-model="createForm.confirmPassword" type="text" autocomplete="off" />
      </el-form-item>
      <el-form-item :label="t('user.field.account_type')">
        <el-radio-group v-model="createForm.asTier1Agent">
          <el-radio :value="false">{{ t('user.type.player') }}</el-radio>
          <el-radio :value="true">{{ t('user.type.tier1_agent') }}</el-radio>
        </el-radio-group>
        <div class="field-hint">{{ t('user.hint.account_type') }}</div>
      </el-form-item>
      <template v-if="!createForm.asTier1Agent">
        <el-form-item :label="t('user.filter.agent')">
          <el-select
            v-model="createForm.parentId"
            :placeholder="t('user.ph.no_agent')"
            clearable
            style="width: 100%"
          >
            <el-option
              v-for="a in agentOptions"
              :key="a.id"
              :label="`${a.username} (#${a.id})`"
              :value="a.id"
            />
          </el-select>
          <div class="field-hint">{{ t('user.hint.no_agent') }}</div>
        </el-form-item>
      </template>
      <template v-else>
        <el-form-item :label="t('agent.field.credit_limit')" required>
          <el-input-number
            v-model="createForm.creditLimit"
            :min="0"
            :step="10000"
            style="width: 100%"
          />
          <div class="field-hint">{{ t('agent.hint.credit_limit') }}</div>
        </el-form-item>
        <el-form-item :label="t('agent.field.cashback_rate')">
          <el-input-number
            v-model="createForm.cashbackRate"
            :min="0"
            :max="1"
            :step="0.001"
            :precision="4"
            style="width: 100%"
          />
          <div class="field-hint">{{ t('agent.hint.cashback_example') }}</div>
        </el-form-item>
      </template>
      <el-form-item :label="t('user.field.phone')">
        <el-input v-model="createForm.phone" :placeholder="t('common.optional')" />
      </el-form-item>
      <el-form-item :label="t('user.field.email')">
        <el-input v-model="createForm.email" :placeholder="t('common.optional')" />
      </el-form-item>
      <template v-if="!createForm.asTier1Agent">
        <el-form-item :label="t('user.field.initial_balance')">
          <el-input-number v-model="createForm.initialDeposit" :min="0" :step="100" style="width: 100%" />
          <div class="field-hint">{{ t('user.hint.initial_balance') }}</div>
        </el-form-item>
        <el-form-item :label="t('user.field.deposit_remark')">
          <el-input v-model="createForm.remark" :placeholder="t('user.ph.remark_initial')" />
        </el-form-item>
      </template>
    </el-form>
    <template #footer>
      <el-button @click="createVisible = false">{{ t('common.cancel') }}</el-button>
      <el-button type="primary" :loading="createLoading" @click="submitCreate">{{ t('user.btn.create') }}</el-button>
    </template>
  </el-dialog>

  <el-dialog
    v-model="editVisible"
    :title="t('user.dialog.edit')"
    width="480px"
    destroy-on-close
    class="user-edit-dialog"
  >
    <el-form label-width="84px" size="small" class="compact-edit-form">
      <div class="edit-meta">
        <span>ID {{ editForm.id }}</span>
        <el-tag :type="statusTagType(editForm.status)" size="small">{{ statusLabel(editForm.status) }}</el-tag>
      </div>

      <el-form-item :label="t('user.col.username')">
        <el-input v-model="editForm.username" :placeholder="t('user.ph.username_unique')" />
      </el-form-item>

      <div class="password-mgmt-block">
        <div class="block-title">{{ t('user.section.password_mgmt') }}</div>
        <el-form-item :label="t('user.field.current_password')">
          <span v-if="editForm.managedPassword" class="password-plain">{{ editForm.managedPassword }}</span>
          <span v-else class="password-empty">—</span>
        </el-form-item>
        <p v-if="!editForm.managedPassword" class="field-hint block-hint">
          {{ t('user.hint.password_reset_to_view') }}
        </p>
        <el-form-item :label="t('user.field.reset_password')">
          <el-input
            v-model="editForm.newPassword"
            type="text"
            autocomplete="off"
            :placeholder="t('user.ph.reset_password_short')"
          />
        </el-form-item>
      </div>

      <el-form-item :label="t('user.filter.agent')">
        <el-select
          v-model="editForm.parentId"
          :placeholder="t('user.ph.no_agent')"
          clearable
          style="width: 100%"
        >
          <el-option
            v-for="a in agentOptions"
            :key="a.id"
            :label="`${a.username} (#${a.id})`"
            :value="a.id"
          />
        </el-select>
      </el-form-item>
      <el-form-item :label="t('user.field.phone')">
        <el-input v-model="editForm.phone" :placeholder="t('common.optional')" />
      </el-form-item>
      <el-form-item :label="t('user.field.email')">
        <el-input v-model="editForm.email" :placeholder="t('common.optional')" />
      </el-form-item>

      <el-descriptions :column="2" size="small" border class="edit-stats">
        <el-descriptions-item :label="t('user.field.available')">
          {{ formatAmount(editForm.availableBalance) }}
        </el-descriptions-item>
        <el-descriptions-item :label="t('user.field.frozen_balance')">
          {{ formatAmount(editForm.frozenBalance) }}
        </el-descriptions-item>
        <el-descriptions-item :label="t('user.field.bets_summary')">
          {{ t('user.bets_edit_value', { n: editForm.betCount, stake: formatAmount(editForm.totalStake) }) }}
        </el-descriptions-item>
        <el-descriptions-item :label="t('user.field.total_payout')">
          {{ formatAmount(editForm.totalReturn) }}
        </el-descriptions-item>
        <el-descriptions-item :label="t('user.col.last_login')" :span="2">
          {{ editForm.lastLoginAt ? formatTime(editForm.lastLoginAt) : t('common.never_login') }}
          · {{ t('user.login_fail_value', { n: editForm.loginFailCount }) }}
        </el-descriptions-item>
      </el-descriptions>
    </el-form>
    <template #footer>
      <el-button size="small" @click="editVisible = false">{{ t('common.cancel') }}</el-button>
      <el-button size="small" type="primary" :loading="editLoading" @click="submitEdit">
        {{ t('user.btn.save_profile') }}
      </el-button>
    </template>
  </el-dialog>

  <el-dialog v-model="transferVisible" :title="transferTitle()" width="520px" destroy-on-close>
    <WalletTransferContext
      :context="transferContext"
      :mode="transferType"
      :loading="transferContextLoading"
    />
    <el-form label-width="88px">
      <el-form-item :label="t('common.col_id')">
        <span>{{ transferTarget?.id }}</span>
      </el-form-item>
      <el-form-item :label="t('user.field.amount')">
        <el-input-number
          v-model="transferAmount"
          :min="transferAmountRange.min"
          :max="transferAmountRange.max"
          :disabled="transferAmountDisabled"
          :step="10"
          :precision="2"
          style="width: 100%"
        />
      </el-form-item>
      <el-form-item :label="t('user.field.remark')">
        <el-input v-model="transferRemark" />
      </el-form-item>
    </el-form>
    <template #footer>
      <el-button @click="transferVisible = false">{{ t('common.cancel') }}</el-button>
      <el-button
        type="primary"
        :loading="transferLoading"
        :disabled="transferAmountDisabled"
        @click="submitTransfer"
      >
        {{ t('common.confirm') }}
      </el-button>
    </template>
  </el-dialog>

  <el-dialog v-model="detailVisible" :title="t('user.dialog.detail')" width="560px" destroy-on-close>
    <template v-if="detail">
      <el-descriptions :column="2" border size="small">
        <el-descriptions-item :label="t('common.col_id')">{{ detail.id }}</el-descriptions-item>
        <el-descriptions-item :label="t('user.col.username')">{{ detail.username }}</el-descriptions-item>
        <el-descriptions-item :label="t('user.field.current_password')">
          {{ detail.managedPassword ?? '—' }}
        </el-descriptions-item>
        <el-descriptions-item v-if="!detail.managedPassword" :span="2">
          <span class="field-hint">{{ t('user.hint.password_reset_to_view') }}</span>
        </el-descriptions-item>
        <el-descriptions-item :label="t('common.status')">
          <el-tag :type="statusTagType(detail.status)" size="small">
            {{ statusLabel(detail.status) }}
          </el-tag>
        </el-descriptions-item>
        <el-descriptions-item :label="t('user.col.agent')">
          {{ detail.parentUsername ?? t('common.platform_direct') }}
        </el-descriptions-item>
        <el-descriptions-item :label="t('user.field.available')">
          {{ formatAmount(detail.availableBalance) }}
          <span v-if="shouldCompact(detail.availableBalance)" class="amount-full-hint">
            （{{ formatAmountFull(detail.availableBalance) }}）
          </span>
        </el-descriptions-item>
        <el-descriptions-item :label="t('user.field.frozen_balance')">
          {{ formatAmount(detail.frozenBalance) }}
          <span v-if="shouldCompact(detail.frozenBalance)" class="amount-full-hint">
            （{{ formatAmountFull(detail.frozenBalance) }}）
          </span>
        </el-descriptions-item>
        <el-descriptions-item :label="t('user.field.phone')">{{ detail.phone ?? '—' }}</el-descriptions-item>
        <el-descriptions-item :label="t('user.field.email')">{{ detail.email ?? '—' }}</el-descriptions-item>
        <el-descriptions-item :label="t('user.field.bet_count')">{{ detail.betCount }}</el-descriptions-item>
        <el-descriptions-item :label="t('user.field.total_stake')">{{ formatAmount(detail.totalStake) }}</el-descriptions-item>
        <el-descriptions-item :label="t('user.field.total_payout')">{{ formatAmount(detail.totalReturn) }}</el-descriptions-item>
        <el-descriptions-item :label="t('user.col.last_login')">
          {{ detail.lastLoginAt ? formatTime(detail.lastLoginAt) : t('common.never_login') }}
        </el-descriptions-item>
        <el-descriptions-item :label="t('user.field.login_fail')">{{ t('user.login_fail_value', { n: detail.loginFailCount }) }}</el-descriptions-item>
        <el-descriptions-item :label="t('user.field.registered_at')" :span="2">
          {{ formatTime(detail.createdAt) }}
        </el-descriptions-item>
      </el-descriptions>
    </template>
  </el-dialog>
  </div>
</template>

<style scoped>
.settings-form :deep(.el-form-item) {
  margin-bottom: 0;
  margin-right: 12px;
}
.field-hint { font-size: 12px; color: #888; margin-top: 4px; }
.inline-hint { margin-top: 0; margin-left: 10px; display: inline-block; }
.amount-compact { white-space: nowrap; font-variant-numeric: tabular-nums; cursor: default; }
.amount-full-hint { font-size: 11px; color: #666; margin-left: 4px; }
.text-muted { color: #666; font-size: 12px; }
.password-mgmt-block {
  margin: 4px 0 10px;
  padding: 10px 12px;
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 8px;
  background: rgba(0, 0, 0, 0.15);
}
.block-title {
  font-size: 12px;
  font-weight: 700;
  color: #e8a84a;
  margin-bottom: 8px;
  letter-spacing: 0.04em;
}
.password-plain {
  font-family: ui-monospace, monospace;
  font-size: 14px;
  font-weight: 600;
  color: #f0d090;
  letter-spacing: 0.06em;
}
.password-empty {
  color: #666;
}
.block-hint {
  margin: -4px 0 8px;
}
.edit-meta {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 10px;
  font-size: 12px;
  color: #888;
}
.compact-edit-form :deep(.el-form-item) {
  margin-bottom: 10px;
}
.edit-stats {
  margin-top: 4px;
}
.list-settings-block--danger {
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px dashed rgba(245, 108, 108, 0.35);
}
.list-settings-hint {
  font-size: 12px;
  color: #888;
  margin: 0 0 10px;
  line-height: 1.5;
}
.reset-db-alert {
  margin-bottom: 10px;
}
</style>

<style>
/* 玩家列表「冻结」：橙黄底白字 */
.users-page .el-button.is-link.el-button--warning {
  color: #ffffff !important;
  background: linear-gradient(165deg, #e8a84a 0%, #c47a18 42%, #9a5c10 100%) !important;
  border: 1px solid rgba(232, 168, 74, 0.45) !important;
  border-radius: 6px !important;
  padding: 5px 11px !important;
  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.12) inset, 0 1px 6px rgba(0, 0, 0, 0.35) !important;
  text-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
}
.users-page .el-button.is-link.el-button--warning:hover,
.users-page .el-button.is-link.el-button--warning:focus {
  color: #ffffff !important;
  background: linear-gradient(165deg, #f0bc62 0%, #d48a28 42%, #a86814 100%) !important;
  border-color: rgba(240, 188, 98, 0.55) !important;
}
</style>
