<script setup lang="ts">
import { ref, onMounted } from 'vue';
import api from '../api';
import { ElMessage, ElMessageBox } from 'element-plus';
import {
  emptyPlayerCreateForm,
  emptyPlayerEditForm,
  editFormFromDetail,
  buildCreatePlayerPayload,
  type PlayerRow,
  type PlayerDetail,
  type PlayerCreateForm,
  type PlayerEditForm,
} from './user-form';
import {
  formatAmount,
  formatAmountFull,
  shouldCompactAmount as shouldCompact,
} from '../utils/format-amount';

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 depositVisible = ref(false);
const createLoading = ref(false);
const editLoading = ref(false);
const depositLoading = ref(false);

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

const depositForm = ref({ userId: '', amount: 100, remark: '' });

onMounted(() => {
  loadAgentOptions();
  load();
});

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 ?? '平台直属';
}

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;
}

function openDeposit(row: PlayerRow) {
  depositForm.value = { userId: row.id, amount: 100, remark: '管理员上分' };
  depositVisible.value = true;
}

async function submitCreate() {
  let payload: ReturnType<typeof buildCreatePlayerPayload>;
  try {
    payload = buildCreatePlayerPayload(createForm.value);
  } catch (e) {
    ElMessage.warning(e instanceof Error ? e.message : '请检查表单');
    return;
  }
  createLoading.value = true;
  try {
    await api.post('/admin/users', payload);
    ElMessage.success('玩家已创建');
    createVisible.value = false;
    load();
  } catch (e: unknown) {
    const err = e as { response?: { data?: { error?: string } } };
    ElMessage.error(err.response?.data?.error ?? '创建失败');
  } finally {
    createLoading.value = false;
  }
}

async function toggleFreeze(row: PlayerRow) {
  const freeze = row.status === 'ACTIVE';
  const action = freeze ? '冻结' : '解冻';
  try {
    await ElMessageBox.confirm(
      `确定要${action}玩家「${row.username}」吗？${freeze ? '冻结后该账号将无法登录。' : ''}`,
      `${action}账号`,
      { type: 'warning', confirmButtonText: action, cancelButtonText: '取消' },
    );
  } catch {
    return;
  }
  try {
    await api.put(`/admin/users/${row.id}`, {
      status: freeze ? 'SUSPENDED' : 'ACTIVE',
    });
    ElMessage.success(`已${action}`);
    load();
  } catch (e: unknown) {
    const err = e as { response?: { data?: { error?: string } } };
    ElMessage.error(err.response?.data?.error ?? `${action}失败`);
  }
}

async function submitEdit() {
  editLoading.value = true;
  try {
    await api.put(`/admin/users/${editingId.value}`, {
      parentId: editForm.value.parentId || '',
      phone: editForm.value.phone.trim() || undefined,
      email: editForm.value.email.trim() || undefined,
    });
    ElMessage.success('已保存');
    editVisible.value = false;
    load();
  } catch (e: unknown) {
    const err = e as { response?: { data?: { error?: string } } };
    ElMessage.error(err.response?.data?.error ?? '保存失败');
  } finally {
    editLoading.value = false;
  }
}

async function submitDeposit() {
  if (depositForm.value.amount <= 0) {
    ElMessage.warning('金额须大于 0');
    return;
  }
  depositLoading.value = true;
  try {
    await api.post('/admin/wallet/deposit', {
      userId: depositForm.value.userId,
      amount: depositForm.value.amount,
      remark: depositForm.value.remark,
      requestId: `dep-${depositForm.value.userId}-${Date.now()}`,
    });
    ElMessage.success('上分成功');
    depositVisible.value = false;
    load();
  } catch (e: unknown) {
    const err = e as { response?: { data?: { error?: string } } };
    ElMessage.error(err.response?.data?.error ?? '上分失败');
  } finally {
    depositLoading.value = false;
  }
}

function formatTime(v: string) {
  if (!v) return '—';
  return new Date(v).toLocaleString('zh-CN');
}

function formatLastLogin(v: string | null) {
  if (!v) return '从未登录';
  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('zh-CN', { hour: '2-digit', minute: '2-digit' });
  }
  return d.toLocaleString('zh-CN', {
    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) {
  return s === 'ACTIVE' ? '正常' : s === 'SUSPENDED' ? '停用' : s;
}
</script>

<template>
  <div class="admin-list-page users-page">
  <div class="page-header">
    <div>
      <h2 class="page-title">玩家管理</h2>
      <span class="page-desc">创建玩家、查看余额与投注概况，支持上分与状态管理</span>
    </div>
    <el-button type="primary" @click="openCreate">+ 新建玩家</el-button>
  </div>

  <el-card class="filter-card" shadow="never">
    <el-form inline>
      <el-form-item label="关键词">
        <el-input
          v-model="keyword"
          placeholder="用户名"
          clearable
          style="width: 160px"
          @keyup.enter="load"
        />
      </el-form-item>
      <el-form-item label="所属代理">
        <el-select
          v-model="filterParentId"
          placeholder="全部"
          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="状态">
        <el-select v-model="filterStatus" placeholder="全部" clearable style="width: 120px">
          <el-option label="正常" value="ACTIVE" />
          <el-option label="停用" value="SUSPENDED" />
        </el-select>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="load">查询</el-button>
      </el-form-item>
    </el-form>
  </el-card>

  <el-card class="data-card" shadow="never">
    <div class="table-wrap">
    <el-table :data="users" stripe>
      <el-table-column prop="id" label="ID" width="72" />
      <el-table-column prop="username" label="用户名" min-width="120" />
      <el-table-column label="状态" 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="所属代理" min-width="120">
        <template #default="{ row }">{{ parentLabel(row) }}</template>
      </el-table-column>
      <el-table-column label="可用 / 冻结" 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="注单" width="64" align="center" />
      <el-table-column label="投注 / 派彩" 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="最后登录" 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">从未登录</span>
        </template>
      </el-table-column>
      <el-table-column label="注册时间" 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="操作" width="300" fixed="right" align="center">
        <template #default="{ row }">
          <el-button size="small" link type="primary" @click="openDetail(row.id)">详情</el-button>
          <el-button size="small" link type="primary" @click="openEdit(row.id)">编辑</el-button>
          <el-button size="small" link type="primary" @click="openDeposit(row)">上分</el-button>
          <el-button
            v-if="row.status === 'ACTIVE'"
            size="small"
            link
            type="warning"
            @click="toggleFreeze(row)"
          >
            冻结
          </el-button>
          <el-button
            v-else
            size="small"
            link
            type="primary"
            @click="toggleFreeze(row)"
          >
            解冻
          </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>
  </el-card>

  <el-dialog v-model="createVisible" title="新建玩家" width="520px" destroy-on-close>
    <el-form label-width="100px">
      <el-form-item label="用户名" required>
        <el-input v-model="createForm.username" placeholder="登录用户名，唯一" />
      </el-form-item>
      <el-form-item label="登录密码" required>
        <el-input v-model="createForm.password" type="text" autocomplete="off" />
      </el-form-item>
      <el-form-item label="确认密码" required>
        <el-input v-model="createForm.confirmPassword" type="text" autocomplete="off" />
      </el-form-item>
      <el-form-item label="所属代理">
        <el-select
          v-model="createForm.parentId"
          placeholder="不设置（平台直属玩家）"
          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">留空表示不挂靠代理，由平台直接管理</div>
      </el-form-item>
      <el-form-item label="手机号">
        <el-input v-model="createForm.phone" placeholder="选填" />
      </el-form-item>
      <el-form-item label="邮箱">
        <el-input v-model="createForm.email" placeholder="选填" />
      </el-form-item>
      <el-form-item label="初始余额">
        <el-input-number v-model="createForm.initialDeposit" :min="0" :step="100" style="width: 100%" />
        <div class="field-hint">创建后自动上分，0 表示不开户赠金</div>
      </el-form-item>
      <el-form-item label="上分备注">
        <el-input v-model="createForm.remark" placeholder="有初始余额时写入流水备注" />
      </el-form-item>
    </el-form>
    <template #footer>
      <el-button @click="createVisible = false">取消</el-button>
      <el-button type="primary" :loading="createLoading" @click="submitCreate">创建</el-button>
    </template>
  </el-dialog>

  <el-dialog v-model="editVisible" title="编辑玩家" width="560px" destroy-on-close>
    <el-form label-width="100px">
      <el-form-item label="玩家 ID">
        <el-input :model-value="editForm.id" disabled />
      </el-form-item>
      <el-form-item label="用户名">
        <el-input :model-value="editForm.username" disabled />
      </el-form-item>
      <el-form-item label="账号状态">
        <el-tag :type="statusTagType(editForm.status)" size="small">
          {{ statusLabel(editForm.status) }}
        </el-tag>
        <span class="field-hint inline-hint">冻结/解冻请在列表操作列进行</span>
      </el-form-item>
      <el-form-item label="所属代理">
        <el-select
          v-model="editForm.parentId"
          placeholder="不设置（平台直属玩家）"
          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">留空表示平台直属；变更后会重算相关代理已用授信</div>
      </el-form-item>
      <el-form-item label="可用余额">
        <el-input :model-value="formatAmount(editForm.availableBalance)" disabled />
      </el-form-item>
      <el-form-item label="冻结余额">
        <el-input :model-value="formatAmount(editForm.frozenBalance)" disabled />
      </el-form-item>
      <el-form-item label="注单 / 投注">
        <el-input
          :model-value="`${editForm.betCount} 笔 / ${formatAmount(editForm.totalStake)}`"
          disabled
        />
      </el-form-item>
      <el-form-item label="累计派彩">
        <el-input :model-value="formatAmount(editForm.totalReturn)" disabled />
      </el-form-item>
      <el-form-item label="最后登录">
        <el-input
          :model-value="editForm.lastLoginAt ? formatTime(editForm.lastLoginAt) : '从未登录'"
          disabled
        />
      </el-form-item>
      <el-form-item label="登录失败">
        <el-input :model-value="`${editForm.loginFailCount} 次`" disabled />
      </el-form-item>
      <el-form-item label="注册时间">
        <el-input :model-value="formatTime(editForm.createdAt)" disabled />
      </el-form-item>
      <el-divider />
      <el-form-item label="手机号">
        <el-input v-model="editForm.phone" placeholder="选填" />
      </el-form-item>
      <el-form-item label="邮箱">
        <el-input v-model="editForm.email" placeholder="选填" />
      </el-form-item>
    </el-form>
    <template #footer>
      <el-button @click="editVisible = false">取消</el-button>
      <el-button type="primary" :loading="editLoading" @click="submitEdit">保存资料</el-button>
    </template>
  </el-dialog>

  <el-dialog v-model="depositVisible" title="玩家上分" width="400px" destroy-on-close>
    <el-form label-width="80px">
      <el-form-item label="玩家 ID">
        <el-input :model-value="depositForm.userId" disabled />
      </el-form-item>
      <el-form-item label="金额">
        <el-input-number v-model="depositForm.amount" :min="0.01" :step="10" style="width: 100%" />
      </el-form-item>
      <el-form-item label="备注">
        <el-input v-model="depositForm.remark" />
      </el-form-item>
    </el-form>
    <template #footer>
      <el-button @click="depositVisible = false">取消</el-button>
      <el-button type="primary" :loading="depositLoading" @click="submitDeposit">确认上分</el-button>
    </template>
  </el-dialog>

  <el-dialog v-model="detailVisible" title="玩家详情" width="560px" destroy-on-close>
    <template v-if="detail">
      <el-descriptions :column="2" border size="small">
        <el-descriptions-item label="ID">{{ detail.id }}</el-descriptions-item>
        <el-descriptions-item label="用户名">{{ detail.username }}</el-descriptions-item>
        <el-descriptions-item label="状态">
          <el-tag :type="statusTagType(detail.status)" size="small">
            {{ statusLabel(detail.status) }}
          </el-tag>
        </el-descriptions-item>
        <el-descriptions-item label="所属代理">
          {{ detail.parentUsername ?? '平台直属' }}
        </el-descriptions-item>
        <el-descriptions-item label="可用余额">
          {{ formatAmount(detail.availableBalance) }}
          <span v-if="shouldCompact(detail.availableBalance)" class="amount-full-hint">
            （{{ formatAmountFull(detail.availableBalance) }}）
          </span>
        </el-descriptions-item>
        <el-descriptions-item label="冻结余额">
          {{ formatAmount(detail.frozenBalance) }}
          <span v-if="shouldCompact(detail.frozenBalance)" class="amount-full-hint">
            （{{ formatAmountFull(detail.frozenBalance) }}）
          </span>
        </el-descriptions-item>
        <el-descriptions-item label="手机">{{ detail.phone ?? '—' }}</el-descriptions-item>
        <el-descriptions-item label="邮箱">{{ detail.email ?? '—' }}</el-descriptions-item>
        <el-descriptions-item label="注单数">{{ detail.betCount }}</el-descriptions-item>
        <el-descriptions-item label="累计投注">{{ formatAmount(detail.totalStake) }}</el-descriptions-item>
        <el-descriptions-item label="累计派彩">{{ formatAmount(detail.totalReturn) }}</el-descriptions-item>
        <el-descriptions-item label="最后登录">
          {{ detail.lastLoginAt ? formatTime(detail.lastLoginAt) : '从未登录' }}
        </el-descriptions-item>
        <el-descriptions-item label="登录失败">{{ detail.loginFailCount }} 次</el-descriptions-item>
        <el-descriptions-item label="注册时间" :span="2">
          {{ formatTime(detail.createdAt) }}
        </el-descriptions-item>
      </el-descriptions>
    </template>
  </el-dialog>
  </div>
</template>

<style scoped>
.page-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  margin-bottom: 20px;
}
.page-title { font-size: 20px; font-weight: 700; color: #e0e0e0; margin: 0 0 4px; }
.page-desc { font-size: 13px; color: #666; }
.filter-card { margin-bottom: 16px; border-radius: 12px; }
.data-card { border-radius: 12px; }
.pager { margin-top: 16px; display: flex; justify-content: flex-end; }
.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; }
</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>
