<template>
  <div class="space-y-4">
    <a-page-header title="成员管理" sub-title="成员邀请、角色与权限">
      <template #extra>
        <a-space>
          <a-input
            v-model:value="keywords"
            allow-clear
            placeholder="搜索账号/昵称/手机号"
            class="w-64"
            @press-enter="doSearch"
          />
          <a-button :loading="loading" @click="reload">刷新</a-button>
          <a-button type="primary" @click="openInvite">邀请成员</a-button>
        </a-space>
      </template>
    </a-page-header>

    <a-row :gutter="[16, 16]">
      <a-col :xs="24" :lg="12">
        <a-card :bordered="false" class="card" title="成员配额">
          <a-descriptions :column="2" size="small" bordered>
            <a-descriptions-item label="成员上限">
              {{ company?.members ?? '-' }}
            </a-descriptions-item>
            <a-descriptions-item label="当前人数">
              {{ company?.users ?? '-' }}
            </a-descriptions-item>
          </a-descriptions>
          <div class="mt-4 text-sm text-gray-500">
            成员数据来自系统用户（租户维度），可进行邀请、禁用、重置密码与角色设置。
          </div>
        </a-card>
      </a-col>
      <a-col :xs="24" :lg="12">
        <a-card :bordered="false" class="card" title="快速操作">
          <a-space wrap>
            <a-button @click="openInvite">邀请成员</a-button>
            <a-button @click="reload">刷新列表</a-button>
          </a-space>
        </a-card>
      </a-col>
    </a-row>

    <a-card :bordered="false" class="card">
      <a-alert v-if="error" class="mb-4" show-icon type="error" :message="error" />

      <a-table
        :data-source="list"
        :loading="loading"
        :pagination="false"
        size="middle"
        :row-key="(r: any) => r.userId ?? r.username"
      >
        <a-table-column title="ID" data-index="userId" width="90" />
        <a-table-column title="账号" data-index="username" width="180" />
        <a-table-column title="昵称" data-index="nickname" width="160" />
        <a-table-column title="手机号" data-index="phone" width="140" />
        <a-table-column title="角色" key="roleName" width="160">
          <template #default="{ record }">
            <span>{{ resolveRoleName(record) }}</span>
          </template>
        </a-table-column>
        <a-table-column title="状态" key="status" width="120">
          <template #default="{ record }">
            <a-tag v-if="record.status === 0 || record.status === undefined" color="green">正常</a-tag>
            <a-tag v-else color="default">冻结</a-tag>
          </template>
        </a-table-column>
        <a-table-column title="创建时间" data-index="createTime" width="180" />
        <a-table-column title="操作" key="actions" width="260" fixed="right">
          <template #default="{ record }">
            <a-space>
              <a-button size="small" @click="openRole(record)" :disabled="!record.userId">设置角色</a-button>
              <a-button size="small" @click="openReset(record)" :disabled="!record.userId">重置密码</a-button>
              <a-button
                size="small"
                :loading="busyUserId === record.userId"
                @click="toggleStatus(record)"
                :disabled="!record.userId"
              >
                {{ record.status === 1 ? '解冻' : '冻结' }}
              </a-button>
              <a-popconfirm
                title="确定删除该成员？"
                ok-text="删除"
                cancel-text="取消"
                @confirm="remove(record)"
              >
                <a-button size="small" danger :disabled="!record.userId">删除</a-button>
              </a-popconfirm>
            </a-space>
          </template>
        </a-table-column>
      </a-table>

      <div class="mt-4 flex items-center justify-end">
        <a-pagination
          :current="page"
          :page-size="limit"
          :total="total"
          show-size-changer
          :page-size-options="['10', '20', '50', '100']"
          @change="onPageChange"
          @show-size-change="onPageSizeChange"
        />
      </div>
    </a-card>

    <a-modal
      v-model:open="inviteOpen"
      title="邀请成员"
      ok-text="创建账号"
      cancel-text="取消"
      :confirm-loading="inviting"
      @ok="submitInvite"
    >
      <a-form ref="inviteFormRef" layout="vertical" :model="inviteForm" :rules="inviteRules">
        <a-form-item label="账号" name="username">
          <a-input v-model:value="inviteForm.username" placeholder="例如：tom / tom@example.com" />
        </a-form-item>
        <a-form-item label="昵称" name="nickname">
          <a-input v-model:value="inviteForm.nickname" placeholder="例如：Tom" />
        </a-form-item>
        <a-form-item label="手机号" name="phone">
          <a-input v-model:value="inviteForm.phone" placeholder="例如：13800000000" />
        </a-form-item>
        <a-form-item label="角色" name="roleId">
          <a-select
            v-model:value="inviteForm.roleId"
            placeholder="请选择角色"
            allow-clear
            :options="roleOptions"
          />
        </a-form-item>
        <a-form-item label="初始密码" name="password">
          <a-input-password v-model:value="inviteForm.password" placeholder="请输入初始密码" />
        </a-form-item>
        <a-form-item label="确认密码" name="password2">
          <a-input-password v-model:value="inviteForm.password2" placeholder="再次输入密码" />
        </a-form-item>
      </a-form>
      <a-alert
        class="mt-2"
        type="info"
        show-icon
        message="创建后可在本页进行冻结/解冻、重置密码与角色设置。"
      />
    </a-modal>

    <a-modal
      v-model:open="roleOpen"
      title="设置角色"
      ok-text="保存"
      cancel-text="取消"
      :confirm-loading="savingRole"
      @ok="submitRole"
    >
      <a-form layout="vertical">
        <a-form-item label="成员">
          <a-input :value="selectedUser?.nickname || selectedUser?.username || ''" disabled />
        </a-form-item>
        <a-form-item label="角色">
          <a-select v-model:value="selectedRoleId" placeholder="请选择角色" :options="roleOptions" />
        </a-form-item>
      </a-form>
    </a-modal>

    <a-modal
      v-model:open="resetOpen"
      title="重置密码"
      ok-text="确认重置"
      cancel-text="取消"
      :confirm-loading="resetting"
      @ok="submitReset"
    >
      <a-form layout="vertical">
        <a-form-item label="成员">
          <a-input :value="selectedUser?.nickname || selectedUser?.username || ''" disabled />
        </a-form-item>
        <a-form-item label="新密码">
          <a-input-password v-model:value="resetPassword" placeholder="请输入新密码" />
        </a-form-item>
      </a-form>
      <a-alert class="mt-2" type="warning" show-icon message="重置后请尽快通知成员修改密码。" />
    </a-modal>
  </div>
</template>

<script setup lang="ts">
import { computed, onMounted, reactive, ref } from 'vue'
import { message, type FormInstance } from 'ant-design-vue'
import { getTenantInfo } from '@/api/layout'
import { listRoles } from '@/api/system/role'
import { addUser, pageUsers, removeUser, updateUserPassword, updateUserStatus } from '@/api/system/user'
import { addUserRole, listUserRole, updateUserRole } from '@/api/system/userRole'
import type { Company } from '@/api/system/company/model'
import type { Role } from '@/api/system/role/model'
import type { User } from '@/api/system/user/model'

definePageMeta({ layout: 'console' })

const loading = ref(false)
const error = ref<string>('')

const company = ref<Company | null>(null)
const roles = ref<Role[]>([])

const list = ref<User[]>([])
const total = ref(0)
const page = ref(1)
const limit = ref(10)
const keywords = ref('')

const roleOptions = computed(() =>
  roles.value.map((r) => ({ label: r.roleName ?? String(r.roleId ?? ''), value: r.roleId }))
)

function resolveRoleName(user: User) {
  const direct = typeof user.roleName === 'string' ? user.roleName.trim() : ''
  if (direct) return direct
  const hit = roles.value.find((r) => r.roleId === user.roleId)
  return hit?.roleName ?? '-'
}

async function loadCompany() {
  try {
    company.value = await getTenantInfo()
  } catch {
    // ignore
  }
}

async function loadRolesOnce() {
  if (roles.value.length) return
  try {
    roles.value = await listRoles()
  } catch {
    roles.value = []
  }
}

async function loadMembers() {
  loading.value = true
  error.value = ''
  try {
    const res = await pageUsers({
      page: page.value,
      limit: limit.value,
      keywords: keywords.value || undefined
    })
    list.value = res?.list ?? []
    total.value = res?.count ?? 0
  } catch (e) {
    error.value = e instanceof Error ? e.message : '成员列表加载失败'
  } finally {
    loading.value = false
  }
}

async function reload() {
  await Promise.all([loadCompany(), loadRolesOnce(), loadMembers()])
}

function doSearch() {
  page.value = 1
  loadMembers()
}

function onPageChange(nextPage: number) {
  page.value = nextPage
  loadMembers()
}

function onPageSizeChange(_current: number, nextSize: number) {
  limit.value = nextSize
  page.value = 1
  loadMembers()
}

onMounted(async () => {
  await reload()
})

const busyUserId = ref<number | null>(null)
async function toggleStatus(user: User) {
  if (!user.userId) return
  const next = user.status === 1 ? 0 : 1
  busyUserId.value = user.userId
  try {
    await updateUserStatus(user.userId, next)
    message.success(next === 0 ? '已解冻' : '已冻结')
    await loadMembers()
  } catch (e) {
    message.error(e instanceof Error ? e.message : '操作失败')
  } finally {
    busyUserId.value = null
  }
}

async function remove(user: User) {
  if (!user.userId) return
  busyUserId.value = user.userId
  try {
    await removeUser(user.userId)
    message.success('已删除')
    await loadMembers()
  } catch (e) {
    message.error(e instanceof Error ? e.message : '删除失败')
  } finally {
    busyUserId.value = null
  }
}

const inviteOpen = ref(false)
const inviting = ref(false)
const inviteFormRef = ref<FormInstance>()
const inviteForm = reactive<{ username: string; nickname: string; phone: string; roleId?: number; password: string; password2: string }>({
  username: '',
  nickname: '',
  phone: '',
  roleId: undefined,
  password: '',
  password2: ''
})
const inviteRules = reactive({
  username: [{ required: true, type: 'string', message: '请输入账号' }],
  nickname: [{ required: true, type: 'string', message: '请输入昵称' }],
  password: [{ required: true, type: 'string', message: '请输入初始密码' }],
  password2: [{ required: true, type: 'string', message: '请再次输入密码' }]
})

function openInvite() {
  inviteForm.username = ''
  inviteForm.nickname = ''
  inviteForm.phone = ''
  inviteForm.roleId = undefined
  inviteForm.password = ''
  inviteForm.password2 = ''
  inviteOpen.value = true
}

async function submitInvite() {
  try {
    await inviteFormRef.value?.validate()
  } catch {
    return
  }
  if (inviteForm.password !== inviteForm.password2) {
    message.error('两次输入的密码不一致')
    return
  }

  inviting.value = true
  try {
    await addUser({
      username: inviteForm.username.trim(),
      nickname: inviteForm.nickname.trim(),
      phone: inviteForm.phone.trim() || undefined,
      password: inviteForm.password,
      password2: inviteForm.password2,
      roleId: inviteForm.roleId
    })
    message.success('成员已创建')
    inviteOpen.value = false
    await loadMembers()
  } catch (e) {
    message.error(e instanceof Error ? e.message : '创建失败')
  } finally {
    inviting.value = false
  }
}

const roleOpen = ref(false)
const savingRole = ref(false)
const selectedUser = ref<User | null>(null)
const selectedRoleId = ref<number | undefined>(undefined)
function openRole(user: User) {
  selectedUser.value = user
  selectedRoleId.value = user.roleId
  roleOpen.value = true
}

async function submitRole() {
  if (!selectedUser.value?.userId) return
  if (!selectedRoleId.value) {
    message.error('请选择角色')
    return
  }
  savingRole.value = true
  try {
    const mappings = await listUserRole({ userId: selectedUser.value.userId })
    const first = Array.isArray(mappings) ? mappings[0] : undefined
    if (first?.id) {
      await updateUserRole({ ...first, roleId: selectedRoleId.value })
    } else {
      await addUserRole({ userId: selectedUser.value.userId, roleId: selectedRoleId.value })
    }
    message.success('角色已更新')
    roleOpen.value = false
    await loadMembers()
  } catch (e) {
    message.error(e instanceof Error ? e.message : '更新失败')
  } finally {
    savingRole.value = false
  }
}

const resetOpen = ref(false)
const resetting = ref(false)
const resetPassword = ref('')
function openReset(user: User) {
  selectedUser.value = user
  resetPassword.value = ''
  resetOpen.value = true
}

async function submitReset() {
  if (!selectedUser.value?.userId) return
  const pwd = resetPassword.value.trim()
  if (!pwd) {
    message.error('请输入新密码')
    return
  }
  resetting.value = true
  try {
    await updateUserPassword(selectedUser.value.userId, pwd)
    message.success('密码已重置')
    resetOpen.value = false
  } catch (e) {
    message.error(e instanceof Error ? e.message : '重置失败')
  } finally {
    resetting.value = false
  }
}
</script>

<style scoped>
.card {
  border-radius: 12px;
}
</style>
