<script setup lang="ts">
import { computed, onMounted, onActivated, ref } from 'vue';

defineOptions({ name: 'AdminStaffManage' });
import { ElMessage, ElMessageBox } from 'element-plus';
import api from '../api';
import { useAdminLocale } from '../composables/useAdminLocale';
import { useAuthStore } from '../stores/auth';
import AdminTableEmpty from '../components/AdminTableEmpty.vue';
import AdminTableWrap from '../components/AdminTableWrap.vue';

interface StaffRow {
  id: string;
  username: string;
  status: string;
  role: string | null;
  roleName: string | null;
  lastLoginAt: string | null;
  createdAt: string;
  visibleMenus: string | null;
}

interface RoleOption {
  id: string;
  code: string;
  name: string;
}

const { t, localeTag } = useAdminLocale();
const authStore = useAuthStore();
const currentUserId = computed(() => authStore.user.value?.id);

const loading = ref(false);
const rows = ref<StaffRow[]>([]);
const total = ref(0);
const page = ref(1);
const pageSize = ref(10);
const keyword = ref('');
const roles = ref<RoleOption[]>([]);

const menuOptions = [
  { key: 'dashboard', label: 'nav.dashboard' },
  { key: 'matches', label: 'nav.matches' },
  { key: 'users', label: 'nav.agents_players' },
  { key: 'finance-logs', label: 'nav.finance_logs' },
  { key: 'deposit', label: 'nav.deposit_manage' },
  { key: 'cashback', label: 'nav.cashback' },
  { key: 'bets', label: 'nav.bets' },
  { key: 'contents', label: 'nav.contents' },
  { key: 'media', label: 'nav.media' },
  { key: 'audit', label: 'nav.audit' },
  { key: 'staff', label: 'nav.staff' },
  { key: 'smoke-tests', label: 'nav.smoke_tests' },
];

const ROLE_DEFAULT_MENUS: Record<string, string[]> = {
  SUPER_ADMIN: ['dashboard', 'matches', 'users', 'finance-logs', 'deposit', 'cashback', 'bets', 'contents', 'media', 'audit', 'staff', 'smoke-tests'],
  MATCH_ADMIN: ['matches', 'bets', 'contents', 'media'],
  FINANCE_ADMIN: ['dashboard', 'users', 'finance-logs', 'deposit', 'cashback', 'bets'],
  SUPPORT: ['users', 'bets', 'contents', 'media'],
};

const createVisible = ref(false);
const createLoading = ref(false);
const createForm = ref({ username: '', password: '', confirmPassword: '', roleCode: 'MATCH_ADMIN', checkedMenus: [] as string[] });

const editVisible = ref(false);
const editLoading = ref(false);
const editForm = ref({ id: '', username: '', status: 'ACTIVE', roleCode: 'MATCH_ADMIN', password: '', checkedMenus: [] as string[] });

const roleLabel = computed(() => {
  const map: Record<string, string> = {
    SUPER_ADMIN: t('role.super_admin'),
    MATCH_ADMIN: t('role.match_admin'),
    FINANCE_ADMIN: t('role.finance_admin'),
    SUPPORT: t('role.support'),
  };
  return (code: string | null) => (code ? map[code] ?? code : '—');
});

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

async function loadRoles() {
  const { data } = await api.get('/admin/staff/roles');
  roles.value = (data.data ?? []) as RoleOption[];
}

async function load(opts?: { silent?: boolean }) {
  if (!opts?.silent) loading.value = true;
  try {
    const { data } = await api.get('/admin/staff', {
      params: {
        page: page.value,
        pageSize: pageSize.value,
        keyword: keyword.value.trim() || undefined,
      },
    });
    rows.value = data.data.items as StaffRow[];
    total.value = data.data.total;
  } catch {
    rows.value = [];
    total.value = 0;
  } finally {
    if (!opts?.silent) loading.value = false;
  }
}

function onCreateRoleChange(newRole: string) {
  createForm.value.checkedMenus = [...(ROLE_DEFAULT_MENUS[newRole] || [])];
}

function openCreate() {
  createForm.value = {
    username: '',
    password: '',
    confirmPassword: '',
    roleCode: 'MATCH_ADMIN',
    checkedMenus: [...ROLE_DEFAULT_MENUS['MATCH_ADMIN']],
  };
  createVisible.value = true;
}

async function submitCreate() {
  const f = createForm.value;
  if (!f.username.trim()) {
    ElMessage.warning(t('err.username_required'));
    return;
  }
  if (f.password.length < 8) {
    ElMessage.warning(t('err.password_min'));
    return;
  }
  if (f.password !== f.confirmPassword) {
    ElMessage.warning(t('err.password_mismatch'));
    return;
  }
  createLoading.value = true;
  try {
    await api.post('/admin/staff', {
      username: f.username.trim(),
      password: f.password,
      roleCode: f.roleCode,
      visibleMenus: f.checkedMenus.join(','),
    });
    ElMessage.success(t('msg.saved'));
    createVisible.value = false;
    await load();
  } catch (e: unknown) {
    const err = e as { response?: { data?: { error?: string } } };
    ElMessage.error(err.response?.data?.error ?? t('msg.save_failed'));
  } finally {
    createLoading.value = false;
  }
}

function onEditRoleChange(newRole: string) {
  editForm.value.checkedMenus = [...(ROLE_DEFAULT_MENUS[newRole] || [])];
}

function openEdit(row: StaffRow) {
  editForm.value = {
    id: row.id,
    username: row.username,
    status: row.status,
    roleCode: row.role ?? 'MATCH_ADMIN',
    password: '',
    checkedMenus: row.visibleMenus
      ? row.visibleMenus.split(',').filter(Boolean)
      : [...(ROLE_DEFAULT_MENUS[row.role ?? 'MATCH_ADMIN'] || [])],
  };
  editVisible.value = true;
}

async function submitEdit() {
  const f = editForm.value;
  if (f.password && f.password.length < 8) {
    ElMessage.warning(t('err.password_min'));
    return;
  }
  editLoading.value = true;
  try {
    const payload: Record<string, string> = {
      status: f.status,
      roleCode: f.roleCode,
      visibleMenus: f.checkedMenus.join(','),
    };
    if (f.password.trim()) payload.password = f.password.trim();
    const { data } = await api.patch(`/admin/staff/${f.id}`, payload);
    if (data.data?.password) {
      ElMessage.success(t('user.msg.password_saved', { password: data.data.password }));
    } else {
      ElMessage.success(t('msg.saved'));
    }
    editVisible.value = false;
    await 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 toggleFreeze(row: StaffRow, targetStatus: string) {
  const actionText = targetStatus === 'SUSPENDED' ? t('common.freeze') : t('common.unfreeze');
  try {
    await ElMessageBox.confirm(
      `确定要${actionText}管理员「${row.username}」吗？`,
      t('msg.freeze_confirm_title', { action: actionText }),
      { type: 'warning' },
    );
  } catch {
    return;
  }

  try {
    await api.patch(`/admin/staff/${row.id}`, { status: targetStatus });
    ElMessage.success(t('msg.saved'));
    await load();
  } catch (e: unknown) {
    const err = e as { response?: { data?: { error?: string } } };
    ElMessage.error(err.response?.data?.error ?? t('msg.save_failed'));
  }
}

async function deleteStaff(row: StaffRow) {
  try {
    await ElMessageBox.confirm(
      `确定要删除管理员「${row.username}」吗？此操作无法撤销。`,
      t('common.delete'),
      { type: 'warning' },
    );
  } catch {
    return;
  }

  try {
    await api.delete(`/admin/staff/${row.id}`);
    ElMessage.success(t('msg.saved'));
    await load();
  } catch (e: unknown) {
    const err = e as { response?: { data?: { error?: string } } };
    ElMessage.error(err.response?.data?.error ?? t('msg.save_failed'));
  }
}

onMounted(async () => {
  await loadRoles();
  await load();
});
onActivated(() => {
  if (rows.value.length > 0) void load({ silent: true });
});
</script>

<template>
  <div class="admin-list-page staff-page">
    <section class="list-panel">
      <div class="list-panel-toolbar">
        <el-form inline class="list-chrome__grow">
          <el-form-item :label="t('common.keyword')">
            <el-input
              v-model="keyword"
              :placeholder="t('login.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('staff.create_btn') }}</el-button>
        </div>
      </div>

      <AdminTableWrap>
        <el-table v-loading="loading" :data="rows" stripe>
          <template #empty>
            <AdminTableEmpty />
          </template>
          <el-table-column type="index" :index="(i: number) => (page - 1) * pageSize + i + 1" :label="t('common.seq')" width="70" align="center" />
          <el-table-column prop="username" :label="t('login.username')" min-width="120" />
          <el-table-column :label="t('staff.col.role')" min-width="140">
            <template #default="{ row }">{{ roleLabel(row.role) }}</template>
          </el-table-column>
          <el-table-column :label="t('common.status')" width="100" align="center">
            <template #default="{ row }">
              <el-tag
                size="small"
                :type="row.status === 'ACTIVE' ? 'success' : row.status === 'SUSPENDED' ? 'warning' : 'danger'"
                effect="dark"
              >
                {{ t(`user.status.${row.status}`) }}
              </el-tag>
            </template>
          </el-table-column>
          <el-table-column :label="t('staff.col.last_login')" min-width="160">
            <template #default="{ row }">{{ formatTime(row.lastLoginAt) }}</template>
          </el-table-column>
          <el-table-column :label="t('common.actions')" width="220" align="center" fixed="right">
            <template #default="{ row }">
              <el-button link type="primary" size="small" @click="openEdit(row)">
                {{ t('common.edit') }}
              </el-button>

              <el-button
                v-if="row.status === 'ACTIVE'"
                link
                type="warning"
                size="small"
                :disabled="row.id === currentUserId"
                @click="toggleFreeze(row, 'SUSPENDED')"
              >
                {{ t('common.freeze') }}
              </el-button>
              <el-button
                v-else
                link
                type="success"
                size="small"
                :disabled="row.id === currentUserId"
                @click="toggleFreeze(row, 'ACTIVE')"
              >
                {{ t('common.unfreeze') }}
              </el-button>

              <el-button
                link
                type="danger"
                size="small"
                :disabled="row.id === currentUserId"
                @click="deleteStaff(row)"
              >
                {{ t('common.delete') }}
              </el-button>
            </template>
          </el-table-column>
        </el-table>
      </AdminTableWrap>

      <div class="pager">
        <el-pagination
          v-model:current-page="page"
          v-model:page-size="pageSize"
          :total="total"
          :page-sizes="[10, 20, 50]"
          layout="total, sizes, prev, pager, next"
          background
          @current-change="load"
          @size-change="load"
        />
      </div>
    </section>

    <el-dialog v-model="createVisible" :title="t('staff.dialog.create')" width="480px" destroy-on-close>
      <el-form label-width="120px">
        <el-form-item :label="t('login.username')" required>
          <el-input v-model="createForm.username" autocomplete="off" />
        </el-form-item>
        <el-form-item :label="t('staff.col.role')" required>
          <el-select v-model="createForm.roleCode" style="width: 100%" @change="onCreateRoleChange">
            <el-option
              v-for="r in roles.filter((x) => x.code !== 'SUPER_ADMIN')"
              :key="r.code"
              :label="roleLabel(r.code)"
              :value="r.code"
            />
          </el-select>
        </el-form-item>
        <el-form-item :label="t('staff.field.visible_menus')">
          <el-checkbox-group v-model="createForm.checkedMenus">
            <div class="menu-grid">
              <el-checkbox
                v-for="item in menuOptions"
                :key="item.key"
                :label="item.key"
              >
                {{ t(item.label) }}
              </el-checkbox>
            </div>
          </el-checkbox-group>
        </el-form-item>
        <el-form-item :label="t('login.password')" required>
          <el-input v-model="createForm.password" type="password" autocomplete="new-password" />
        </el-form-item>
        <el-form-item :label="t('user.field.confirm_password')" required>
          <el-input v-model="createForm.confirmPassword" type="password" autocomplete="new-password" />
        </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('common.confirm') }}</el-button>
      </template>
    </el-dialog>

    <el-dialog v-model="editVisible" :title="t('staff.dialog.edit')" width="480px" destroy-on-close>
      <el-form label-width="120px">
        <el-form-item :label="t('login.username')">
          <el-input :model-value="editForm.username" disabled />
        </el-form-item>
        <el-form-item :label="t('staff.col.role')">
          <el-select v-model="editForm.roleCode" style="width: 100%" :disabled="editForm.roleCode === 'SUPER_ADMIN'" @change="onEditRoleChange">
            <el-option
              v-for="r in roles"
              :key="r.code"
              :label="roleLabel(r.code)"
              :value="r.code"
            />
          </el-select>
        </el-form-item>
        <el-form-item :label="t('staff.field.visible_menus')">
          <el-checkbox-group v-model="editForm.checkedMenus">
            <div class="menu-grid">
              <el-checkbox
                v-for="item in menuOptions"
                :key="item.key"
                :label="item.key"
              >
                {{ t(item.label) }}
              </el-checkbox>
            </div>
          </el-checkbox-group>
        </el-form-item>
        <el-form-item :label="t('common.status')">
          <el-select v-model="editForm.status" style="width: 100%">
            <el-option :label="t('user.status.ACTIVE')" value="ACTIVE" />
            <el-option :label="t('user.status.SUSPENDED')" value="SUSPENDED" />
            <el-option :label="t('user.status.DISABLED')" value="DISABLED" />
          </el-select>
        </el-form-item>
        <el-form-item :label="t('user.field.reset_password')">
          <el-input v-model="editForm.password" type="password" autocomplete="new-password" :placeholder="t('user.ph.reset_password_short')" />
        </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.confirm') }}</el-button>
      </template>
    </el-dialog>
  </div>
</template>

<style scoped>
.staff-page .pager {
  margin-top: 12px;
  display: flex;
  justify-content: flex-end;
}
.menu-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 4px 12px;
  width: 100%;
}
</style>
