<script setup lang="ts">
import { ref, onMounted } from 'vue';
import { useRouter } from 'vue-router';
import { useAdminLocale } from '../composables/useAdminLocale';
import { resolveFormError, resolveApiError } from '../i18n/form-validation';
import api from '../api';

const { t } = useAdminLocale();
const router = useRouter();
import { ElMessage } from 'element-plus';
import {
  emptyAgentCreateForm,
  emptyAgentEditForm,
  editFormFromAgentDetail,
  buildCreateAgentPayload,
  applyPromotableUserToForm,
  type AgentRow,
  type AgentDetail,
  type AgentCreateForm,
  type AgentEditForm,
  type PromotableUserOption,
} from './agent-form';
import {
  formatAmount,
  formatAmountFull,
  shouldCompactAmount as shouldCompact,
} from '../utils/format-amount';
import AdminTableEmpty from '../components/AdminTableEmpty.vue';
import InviteCodePanel from '../components/InviteCodePanel.vue';
import RatePercentInput from '../components/RatePercentInput.vue';
import AgentCreditContext from '../components/AgentCreditContext.vue';
import { formatRatePercent, percentToDecimalRate } from '../utils/rate-percent';
import {
  fetchAdminAgentCreditContext,
  maxCreditIncreaseAmount,
  type AgentCreditAdjustContext,
} from '../utils/agent-credit-context';

const agents = ref<AgentRow[]>([]);
const total = ref(0);
const page = ref(1);
const pageSize = ref(10);
const keyword = ref('');

function creditLine(row: AgentRow) {
  return `${formatAmount(row.creditLimit)} / ${formatAmount(row.usedCredit)} / ${formatAmount(row.availableCredit)}`;
}

function creditLineFull(row: AgentRow) {
  return `${formatAmountFull(row.creditLimit)} / ${formatAmountFull(row.usedCredit)} / ${formatAmountFull(row.availableCredit)}`;
}

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

const createForm = ref<AgentCreateForm>(emptyAgentCreateForm());
const promotableUsers = ref<PromotableUserOption[]>([]);
const promotableLoading = ref(false);
const promotableKeyword = ref('');
const editForm = ref<AgentEditForm>(emptyAgentEditForm());
const detail = ref<AgentDetail | null>(null);
const editingId = ref('');

const creditForm = ref({ amount: 10000, remark: '' });
const creditContext = ref<AgentCreditAdjustContext | null>(null);
const creditContextLoading = ref(false);

onMounted(load);

async function load() {
  const { data } = await api.get('/admin/agents', {
    params: {
      page: page.value,
      pageSize: pageSize.value,
      keyword: keyword.value.trim() || undefined,
    },
  });
  agents.value = data.data.items as AgentRow[];
  total.value = data.data.total;
}

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

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

async function loadPromotableUsers() {
  promotableLoading.value = true;
  try {
    const { data } = await api.get('/admin/users/promotable-for-agent', {
      params: { keyword: promotableKeyword.value.trim() || undefined },
    });
    promotableUsers.value = data.data as PromotableUserOption[];
  } finally {
    promotableLoading.value = false;
  }
}

function openCreate() {
  createForm.value = emptyAgentCreateForm();
  promotableKeyword.value = '';
  createVisible.value = true;
  loadPromotableUsers();
}

function onPromotableSearch(q: string) {
  promotableKeyword.value = q;
  void loadPromotableUsers();
}

function onPromotableUserChange(userId: string) {
  const user = promotableUsers.value.find((u) => u.id === userId);
  if (user) applyPromotableUserToForm(createForm.value, user);
}

function formatPromotableLabel(u: PromotableUserOption) {
  const parent = u.parentUsername ? ` · ${u.parentUsername}` : '';
  return `${u.username} (#${u.id})${parent}`;
}

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

async function openEdit(userId: string) {
  const { data } = await api.get(`/admin/agents/${userId}`);
  const d = data.data as AgentDetail;
  editingId.value = userId;
  editForm.value = editFormFromAgentDetail(d);
  editVisible.value = true;
}

async function openCredit(row: AgentRow) {
  editingId.value = row.userId;
  creditForm.value = { amount: 10000, remark: '' };
  creditContext.value = null;
  creditVisible.value = true;
  creditContextLoading.value = true;
  try {
    creditContext.value = await fetchAdminAgentCreditContext(row.userId);
  } catch (e: unknown) {
    const err = e as { response?: { data?: { error?: string } } };
    ElMessage.error(err.response?.data?.error ?? t('msg.load_failed'));
    creditVisible.value = false;
  } finally {
    creditContextLoading.value = false;
  }
}

async function submitCreate() {
  let payload: ReturnType<typeof buildCreateAgentPayload>;
  try {
    payload = buildCreateAgentPayload(createForm.value);
  } catch (e) {
    ElMessage.warning(resolveFormError(e, t));
    return;
  }
  createLoading.value = true;
  try {
    await api.post('/admin/agents', payload);
    ElMessage.success(t('msg.agent_created'));
    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 submitEdit() {
  editLoading.value = true;
  try {
    await api.put(`/admin/agents/${editingId.value}`, {
      status: editForm.value.status,
      phone: editForm.value.phone.trim() || undefined,
      email: editForm.value.email.trim() || undefined,
      cashbackRate: percentToDecimalRate(editForm.value.cashbackRate),
    });
    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;
  }
}

async function submitCredit() {
  if (creditForm.value.amount === 0) {
    ElMessage.warning(t('msg.credit_zero'));
    return;
  }
  const maxInc = maxCreditIncreaseAmount(creditContext.value);
  if (creditForm.value.amount > 0 && maxInc !== undefined && creditForm.value.amount > maxInc) {
    ElMessage.warning(t('err.insufficient_credit'));
    return;
  }
  creditLoading.value = true;
  try {
    await api.post(`/admin/agents/${editingId.value}/credit`, {
      amount: creditForm.value.amount,
      requestId: `credit-${editingId.value}-${Date.now()}`,
      remark: creditForm.value.remark || undefined,
    });
    ElMessage.success(t('msg.credit_adjusted'));
    creditVisible.value = false;
    load();
  } catch (e: unknown) {
    ElMessage.error(resolveApiError(e, t, 'msg.credit_adjust_failed'));
  } finally {
    creditLoading.value = false;
  }
}

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

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

function creditTypeLabel(type: string) {
  if (type === 'CREDIT_INCREASE') return t('agent.credit.increase');
  if (type === 'CREDIT_DECREASE') return t('agent.credit.decrease');
  return type;
}
</script>

<template>
  <div class="admin-list-page">
  <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('agent.filter.username_ph')"
            clearable
            style="width: 180px"
            @keyup.enter="load"
          />
        </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('agent.create_btn') }}</el-button>
      </div>
    </div>
  </div>

  <section class="list-panel">
    <div class="table-wrap">
    <el-table :data="agents" stripe>
      <template #empty>
        <AdminTableEmpty />
      </template>
      <el-table-column prop="userId" 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 prop="level" :label="t('agent.col.level')" width="72" align="center" />
      <el-table-column :label="t('agent.col.credit')" min-width="168" align="right">
        <template #default="{ row }">
          <el-tooltip :content="creditLineFull(row)" placement="top">
            <span class="amount-compact">{{ creditLine(row) }}</span>
          </el-tooltip>
        </template>
      </el-table-column>
      <el-table-column prop="directPlayerCount" :label="t('agent.col.direct_players')" width="96" align="center" />
      <el-table-column prop="childAgentCount" :label="t('agent.col.sub_agents')" width="96" align="center" />
      <el-table-column :label="t('agent.col.cashback')" width="88" align="right">
        <template #default="{ row }">{{ formatRatePercent(row.cashbackRate) }}</template>
      </el-table-column>
      <el-table-column prop="phone" :label="t('agent.col.phone')" min-width="110">
        <template #default="{ row }">{{ row.phone ?? '—' }}</template>
      </el-table-column>
      <el-table-column :label="t('agent.col.created')" min-width="158">
        <template #default="{ row }">{{ formatTime(row.createdAt) }}</template>
      </el-table-column>
      <el-table-column :label="t('common.actions')" width="240" fixed="right" align="center">
        <template #default="{ row }">
          <el-button size="small" link type="primary" @click="openDetail(row.userId)">{{ t('common.detail') }}</el-button>
          <el-button size="small" link type="primary" @click="openEdit(row.userId)">{{ t('common.edit') }}</el-button>
          <el-button size="small" link type="primary" @click="openCredit(row)">{{ t('common.adjust_credit') }}</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('agent.dialog.create')" width="520px" destroy-on-close>
    <el-form label-width="100px">
      <el-form-item :label="t('agent.field.select_user')" required>
        <el-select
          v-model="createForm.userId"
          filterable
          remote
          :remote-method="onPromotableSearch"
          :loading="promotableLoading"
          :placeholder="t('agent.ph.select_user')"
          style="width: 100%"
          @change="onPromotableUserChange"
        >
          <el-option
            v-for="u in promotableUsers"
            :key="u.id"
            :label="formatPromotableLabel(u)"
            :value="u.id"
          />
        </el-select>
        <div class="field-hint">{{ t('agent.hint.select_user') }}</div>
      </el-form-item>
      <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')">
        <RatePercentInput v-model="createForm.cashbackRate" />
        <div class="field-hint">{{ t('agent.hint.cashback_example') }}</div>
      </el-form-item>
      <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>
    </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('agent.dialog.edit')" width="480px" destroy-on-close>
    <el-form label-width="88px">
      <el-form-item :label="t('user.field.account_status')">
        <el-radio-group v-model="editForm.status">
          <el-radio value="ACTIVE">{{ t('user.status.ACTIVE') }}</el-radio>
          <el-radio value="SUSPENDED">{{ t('user.status.SUSPENDED') }}</el-radio>
        </el-radio-group>
      </el-form-item>
      <el-form-item :label="t('agent.field.cashback_rate')">
        <RatePercentInput v-model="editForm.cashbackRate" />
      </el-form-item>
      <el-form-item :label="t('user.field.phone')">
        <el-input v-model="editForm.phone" />
      </el-form-item>
      <el-form-item :label="t('user.field.email')">
        <el-input v-model="editForm.email" />
      </el-form-item>
    </el-form>
    <template #footer>
      <el-button @click="editVisible = false">{{ t('common.cancel') }}</el-button>
      <el-button type="primary" :loading="editLoading" @click="submitEdit">{{ t('common.save') }}</el-button>
    </template>
  </el-dialog>

  <el-dialog v-model="creditVisible" :title="t('agent.dialog.credit')" width="520px" destroy-on-close>
    <AgentCreditContext
      :context="creditContext"
      :loading="creditContextLoading"
      :adjust-amount="creditForm.amount"
    />
    <el-form label-width="88px">
      <el-form-item :label="t('agent.field.agent_id')">
        <el-input :model-value="editingId" disabled />
      </el-form-item>
      <el-form-item :label="t('agent.field.adjust_amount')">
        <el-input-number v-model="creditForm.amount" :step="1000" style="width: 100%" />
        <div class="field-hint">{{ t('agent.hint.credit_adjust') }}</div>
      </el-form-item>
      <el-form-item :label="t('user.field.remark')">
        <el-input v-model="creditForm.remark" :placeholder="t('agent.hint.credit_remark')" />
      </el-form-item>
    </el-form>
    <template #footer>
      <el-button @click="creditVisible = false">{{ t('common.cancel') }}</el-button>
      <el-button type="primary" :loading="creditLoading" @click="submitCredit">{{ t('agent.btn.confirm_adjust') }}</el-button>
    </template>
  </el-dialog>

  <el-dialog v-model="detailVisible" :title="t('agent.dialog.detail')" width="640px" destroy-on-close>
    <template v-if="detail">
      <el-descriptions :column="2" border size="small" class="detail-block">
        <el-descriptions-item :label="t('common.col_id')">{{ detail.userId }}</el-descriptions-item>
        <el-descriptions-item :label="t('user.col.username')">{{ detail.username }}</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('agent.col.level')">L{{ detail.level }}</el-descriptions-item>
        <el-descriptions-item :label="t('agent.field.credit_limit')">
          {{ formatAmount(detail.creditLimit) }}
          <span v-if="shouldCompact(detail.creditLimit)" class="amount-full-hint">
            （{{ formatAmountFull(detail.creditLimit) }}）
          </span>
        </el-descriptions-item>
        <el-descriptions-item :label="t('agent.field.used_credit')">
          {{ formatAmount(detail.usedCredit) }}
          <span v-if="shouldCompact(detail.usedCredit)" class="amount-full-hint">
            （{{ formatAmountFull(detail.usedCredit) }}）
          </span>
        </el-descriptions-item>
        <el-descriptions-item :label="t('agent.field.available_credit')">
          {{ formatAmount(detail.availableCredit) }}
          <span v-if="shouldCompact(detail.availableCredit)" class="amount-full-hint">
            （{{ formatAmountFull(detail.availableCredit) }}）
          </span>
        </el-descriptions-item>
        <el-descriptions-item :label="t('agent.col.direct_players')">{{ detail.directPlayerCount }} {{ t('common.people') }}</el-descriptions-item>
        <el-descriptions-item :label="t('agent.field.player_liability')">
          {{ formatAmount(detail.directPlayerLiability) }}
        </el-descriptions-item>
        <el-descriptions-item :label="t('agent.field.sub_agent_exposure')">
          {{ formatAmount(detail.childAgentExposure) }}
        </el-descriptions-item>
        <el-descriptions-item :label="t('agent.col.cashback')">{{ formatRatePercent(detail.cashbackRate) }}</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.col.last_login')" :span="2">
          {{ detail.lastLoginAt ? formatTime(detail.lastLoginAt) : t('common.never_login') }}
        </el-descriptions-item>
        <el-descriptions-item :label="t('agent.col.created')" :span="2">
          {{ formatTime(detail.createdAt) }}
        </el-descriptions-item>
      </el-descriptions>

      <InviteCodePanel :invite-code="detail.inviteCode" compact readonly class="detail-invite" />

      <div class="section-title section-title--row">
        <span>{{ t('agent.section.credit_log') }}</span>
        <el-button
          v-if="detail"
          link
          type="primary"
          @click="router.push({ path: '/agent-credit-transactions', query: { agentId: detail.userId } })"
        >
          {{ t('agent.credit_tx.view_all') }}
        </el-button>
      </div>
      <el-table
        :data="detail.recentCreditTransactions"
        size="small"
        stripe
        :empty-text="t('agent.col.no_records')"
      >
        <el-table-column :label="t('agent.col.credit_type')" width="80">
          <template #default="{ row }">{{ creditTypeLabel(row.transactionType) }}</template>
        </el-table-column>
        <el-table-column :label="t('agent.col.credit_change')" width="96" align="right">
          <template #default="{ row }">
            <el-tooltip :content="formatAmountFull(row.amount)" placement="top">
              <span>{{ formatAmount(row.amount) }}</span>
            </el-tooltip>
          </template>
        </el-table-column>
        <el-table-column :label="t('agent.col.credit_after')" width="96" align="right">
          <template #default="{ row }">
            <el-tooltip :content="formatAmountFull(row.creditAfter)" placement="top">
              <span>{{ formatAmount(row.creditAfter) }}</span>
            </el-tooltip>
          </template>
        </el-table-column>
        <el-table-column prop="remark" :label="t('user.field.remark')" min-width="120" show-overflow-tooltip />
        <el-table-column :label="t('audit.col.time')" min-width="150">
          <template #default="{ row }">{{ formatTime(row.createdAt) }}</template>
        </el-table-column>
      </el-table>
    </template>
  </el-dialog>
  </div>
</template>

<style scoped>
.field-hint { font-size: 12px; color: #888; margin-top: 4px; }
.detail-block { margin-bottom: 16px; }
.section-title {
  font-size: 13px;
  font-weight: 600;
  color: #666;
  margin-bottom: 8px;
}

.section-title--row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}
.amount-compact {
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
  cursor: default;
}
.amount-full-hint {
  font-size: 11px;
  color: #666;
  margin-left: 4px;
}

.field-hint,
.section-title,
.amount-full-hint {
  color: var(--text-muted);
}

.detail-block {
  border-color: var(--border);
}

@media (max-width: 760px) {
  .section-title--row {
    align-items: flex-start;
    flex-direction: column;
  }
}
</style>
