<template>
  <section class="space-y-6">
    <header class="space-y-2">
      <h1 class="mos-title text-2xl font-semibold">审批中心</h1>
      <p class="mos-muted text-sm">处理角色变更与邀请审批。</p>
    </header>

    <ListSection :page="requestPage" :total-pages="requestTotalPages" @prev="requestPage--" @next="requestPage++">
      <template #title>角色变更申请</template>
      <template #filters>
        <input class="mos-input !py-1 !px-2 !text-xs w-44" v-model="requestQuery" placeholder="搜索用户" />
        <input class="mos-input !py-1 !px-2 !text-xs" type="date" v-model="requestStart" />
        <input class="mos-input !py-1 !px-2 !text-xs" type="date" v-model="requestEnd" />
        <input class="mos-input !py-1 !px-2 !text-xs w-48" v-model="batchRejectReason" placeholder="批量拒绝原因" />
      </template>
      <template #actions>
        <button class="mos-btn mos-btn-secondary !py-1 !px-2 !text-xs" @click="selectAllRequests">
          {{ allRequestsSelected ? '取消全选' : '全选' }}
        </button>
        <button class="mos-btn mos-btn-secondary !py-1 !px-2 !text-xs" @click="batchApprove">批量通过</button>
        <button class="mos-btn mos-btn-secondary !py-1 !px-2 !text-xs" @click="batchReject">批量拒绝</button>
      </template>
      <template #default>
        <div v-if="pagedRequests.length" class="space-y-3">
          <div v-for="request in pagedRequests" :key="request.id" class="rounded-xl border border-mosquito-line px-4 py-3">
            <div class="flex items-center justify-between">
              <div class="flex items-center gap-3">
                <input
                  type="checkbox"
                  class="h-4 w-4"
                  :checked="selectedRequestIds.includes(request.id)"
                  @click.stop
                  @change.stop="toggleRequestSelect(request.id)"
                />
                <div>
                  <div class="text-sm font-semibold text-mosquito-ink">{{ getUserName(request.userId) }}</div>
                  <div class="mos-muted text-xs">从 {{ roleLabel(request.currentRole) }} 变更为 {{ roleLabel(request.targetRole) }}</div>
                  <div class="mos-muted text-xs">原因：{{ request.reason }}</div>
                </div>
              </div>
              <div class="flex items-center gap-2">
                <span
                  class="rounded-full px-2 py-1 text-[10px] font-semibold"
                  :class="slaClass(getSlaBadge(request.requestedAt).level)"
                >
                  {{ getSlaBadge(request.requestedAt).label }}
                </span>
                <button class="mos-btn mos-btn-secondary !py-1 !px-2 !text-xs" @click="setRejecting(request.id)">拒绝</button>
                <button class="mos-btn mos-btn-accent !py-1 !px-2 !text-xs" @click="approve(request)">通过</button>
              </div>
            </div>
            <div v-if="rejectingId === request.id" class="mt-3 flex flex-wrap items-center gap-2">
              <input class="mos-input !py-1 !px-2 !text-xs flex-1" v-model="rejectReason" placeholder="请输入拒绝原因" />
              <button class="mos-btn mos-btn-secondary !py-1 !px-2 !text-xs" @click="cancelReject">取消</button>
              <button class="mos-btn mos-btn-accent !py-1 !px-2 !text-xs" @click="confirmReject(request)">确认拒绝</button>
            </div>
          </div>
        </div>
      </template>
      <template #empty>
        <div v-if="!pagedRequests.length" class="mt-4 text-sm text-mosquito-ink/60">暂无待审批申请</div>
      </template>
    </ListSection>

    <ListSection :page="invitePage" :total-pages="inviteTotalPages" @prev="invitePage--" @next="invitePage++">
      <template #title>邀请申请</template>
      <template #filters>
        <input class="mos-input !py-1 !px-2 !text-xs w-44" v-model="inviteQuery" placeholder="搜索邮箱" />
        <input class="mos-input !py-1 !px-2 !text-xs" type="date" v-model="inviteStart" />
        <input class="mos-input !py-1 !px-2 !text-xs" type="date" v-model="inviteEnd" />
      </template>
      <template #actions>
        <button class="mos-btn mos-btn-secondary !py-1 !px-2 !text-xs" @click="selectAllInvites">
          {{ allInvitesSelected ? '取消全选' : '全选' }}
        </button>
        <button class="mos-btn mos-btn-secondary !py-1 !px-2 !text-xs" @click="batchAcceptInvites">批量通过</button>
        <button class="mos-btn mos-btn-secondary !py-1 !px-2 !text-xs" @click="batchRejectInvites">批量拒绝</button>
      </template>
      <template #default>
        <div v-if="pagedInvites.length" class="space-y-3">
          <div v-for="invite in pagedInvites" :key="invite.id" class="flex items-center justify-between rounded-xl border border-mosquito-line px-4 py-3">
            <div class="flex items-center gap-3">
              <input
                type="checkbox"
                class="h-4 w-4"
                :checked="selectedInviteIds.includes(invite.id)"
                @click.stop
                @change.stop="toggleInviteSelect(invite.id)"
              />
              <div>
                <div class="text-sm font-semibold text-mosquito-ink">{{ invite.email }}</div>
                <div class="mos-muted text-xs">角色：{{ roleLabel(invite.role) }}</div>
              </div>
            </div>
            <div class="flex items-center gap-2">
              <button class="mos-btn mos-btn-secondary !py-1 !px-2 !text-xs" @click="rejectInvite(invite)">拒绝</button>
              <button class="mos-btn mos-btn-accent !py-1 !px-2 !text-xs" @click="acceptInvite(invite)">通过</button>
            </div>
          </div>
        </div>
      </template>
      <template #empty>
        <div v-if="!pagedInvites.length" class="mt-4 text-sm text-mosquito-ink/60">暂无待审批邀请</div>
      </template>
    </ListSection>
  </section>
</template>

<script setup lang="ts">
import { computed, onMounted, ref, watch } from 'vue'
import { useUserStore, type RoleChangeRequest, type InviteRequest } from '../stores/users'
import { useDataService } from '../services'
import { useAuditStore } from '../stores/audit'
import ListSection from '../components/ListSection.vue'
import { getSlaBadge, normalizeRejectReason } from '../utils/approval'

const store = useUserStore()
const service = useDataService()
const auditStore = useAuditStore()
const rejectingId = ref<string | null>(null)
const rejectReason = ref('')
const batchRejectReason = ref('')
const requestQuery = ref('')
const inviteQuery = ref('')
const requestStart = ref('')
const requestEnd = ref('')
const inviteStart = ref('')
const inviteEnd = ref('')
const requestPage = ref(0)
const invitePage = ref(0)
const pageSize = 6
const selectedRequestIds = ref<string[]>([])
const selectedInviteIds = ref<string[]>([])

onMounted(async () => {
  const [users, invites, requests] = await Promise.all([
    service.getUsers(),
    service.getInvites(),
    service.getRoleRequests()
  ])
  store.init(users, invites, requests)
})

const pendingRequests = computed(() => store.pendingRoleRequests)
const pendingInvites = computed(() => store.invites.filter((item) => item.status === '待接受'))

const roleLabel = (role: string) => {
  if (role === 'admin') return '管理员'
  if (role === 'operator') return '运营'
  return '只读'
}

const getUserName = (id: string) => store.byId(id)?.name ?? id

const slaClass = (level: ReturnType<typeof getSlaBadge>['level']) => {
  if (level === 'danger') return 'bg-rose-100 text-rose-600'
  if (level === 'warning') return 'bg-amber-100 text-amber-600'
  return 'bg-mosquito-accent/10 text-mosquito-brand'
}

const approve = (request: RoleChangeRequest) => {
  store.approveRoleChange(request.id, '演示管理员')
  auditStore.addLog('审批通过角色变更', getUserName(request.userId))
  service.addNotification({
    title: '角色变更审批通过',
    detail: `${getUserName(request.userId)} 角色变更已通过`
  })
}

const setRejecting = (id: string) => {
  rejectingId.value = id
  rejectReason.value = ''
}

const cancelReject = () => {
  rejectingId.value = null
  rejectReason.value = ''
}

const confirmReject = (request: RoleChangeRequest) => {
  const reason = normalizeRejectReason(rejectReason.value, '未填写原因')
  store.rejectRoleChange(request.id, '演示管理员', reason)
  auditStore.addLog('审批拒绝角色变更', `${getUserName(request.userId)}：${reason}`)
  service.addNotification({
    title: '角色变更审批拒绝',
    detail: `${getUserName(request.userId)}：${reason}`
  })
  cancelReject()
}

const acceptInvite = (invite: InviteRequest) => {
  store.acceptInvite(invite.id)
  auditStore.addLog('审批通过邀请', invite.email)
  service.addNotification({
    title: '邀请审批通过',
    detail: `${invite.email} 已通过`
  })
}

const rejectInvite = (invite: InviteRequest) => {
  invite.status = '已拒绝'
  auditStore.addLog('审批拒绝邀请', invite.email)
  service.addNotification({
    title: '邀请审批拒绝',
    detail: `${invite.email} 已拒绝`
  })
}

const filteredRequests = computed(() => {
  return pendingRequests.value.filter((request) => {
    const matchesQuery = getUserName(request.userId).includes(requestQuery.value)
    const startOk = requestStart.value ? new Date(request.requestedAt).getTime() >= new Date(requestStart.value).getTime() : true
    const endOk = requestEnd.value ? new Date(request.requestedAt).getTime() <= new Date(requestEnd.value).getTime() : true
    return matchesQuery && startOk && endOk
  })
})

const filteredInvites = computed(() => {
  return pendingInvites.value.filter((invite) => {
    const matchesQuery = invite.email.includes(inviteQuery.value)
    const startOk = inviteStart.value ? new Date(invite.invitedAt).getTime() >= new Date(inviteStart.value).getTime() : true
    const endOk = inviteEnd.value ? new Date(invite.invitedAt).getTime() <= new Date(inviteEnd.value).getTime() : true
    return matchesQuery && startOk && endOk
  })
})

const requestTotalPages = computed(() => Math.max(1, Math.ceil(filteredRequests.value.length / pageSize)))
const inviteTotalPages = computed(() => Math.max(1, Math.ceil(filteredInvites.value.length / pageSize)))

const pagedRequests = computed(() => {
  const start = requestPage.value * pageSize
  return filteredRequests.value.slice(start, start + pageSize)
})

const pagedInvites = computed(() => {
  const start = invitePage.value * pageSize
  return filteredInvites.value.slice(start, start + pageSize)
})

watch([requestQuery, requestStart, requestEnd], () => {
  requestPage.value = 0
})

watch([inviteQuery, inviteStart, inviteEnd], () => {
  invitePage.value = 0
})

const allRequestsSelected = computed(() => {
  return filteredRequests.value.length > 0 && filteredRequests.value.every((req) => selectedRequestIds.value.includes(req.id))
})

const allInvitesSelected = computed(() => {
  return filteredInvites.value.length > 0 && filteredInvites.value.every((invite) => selectedInviteIds.value.includes(invite.id))
})

const toggleRequestSelect = (id: string) => {
  if (selectedRequestIds.value.includes(id)) {
    selectedRequestIds.value = selectedRequestIds.value.filter((item) => item !== id)
  } else {
    selectedRequestIds.value = [...selectedRequestIds.value, id]
  }
}

const toggleInviteSelect = (id: string) => {
  if (selectedInviteIds.value.includes(id)) {
    selectedInviteIds.value = selectedInviteIds.value.filter((item) => item !== id)
  } else {
    selectedInviteIds.value = [...selectedInviteIds.value, id]
  }
}

const selectAllRequests = () => {
  if (allRequestsSelected.value) {
    selectedRequestIds.value = []
  } else {
    selectedRequestIds.value = filteredRequests.value.map((req) => req.id)
  }
}

const selectAllInvites = () => {
  if (allInvitesSelected.value) {
    selectedInviteIds.value = []
  } else {
    selectedInviteIds.value = filteredInvites.value.map((inv) => inv.id)
  }
}

const batchApprove = () => {
  filteredRequests.value
    .filter((req) => selectedRequestIds.value.includes(req.id))
    .forEach(approve)
}

const batchReject = () => {
  const reason = normalizeRejectReason(batchRejectReason.value)
  filteredRequests.value
    .filter((req) => selectedRequestIds.value.includes(req.id))
    .forEach((req) => {
      store.rejectRoleChange(req.id, '演示管理员', reason)
      auditStore.addLog('审批拒绝角色变更', `${getUserName(req.userId)}：${reason}`)
      service.addNotification({
        title: '角色变更审批拒绝',
        detail: `${getUserName(req.userId)}：${reason}`
      })
    })
  selectedRequestIds.value = []
  batchRejectReason.value = ''
}

const batchAcceptInvites = () => {
  filteredInvites.value
    .filter((inv) => selectedInviteIds.value.includes(inv.id))
    .forEach(acceptInvite)
  selectedInviteIds.value = []
}

const batchRejectInvites = () => {
  filteredInvites.value
    .filter((inv) => selectedInviteIds.value.includes(inv.id))
    .forEach(rejectInvite)
  selectedInviteIds.value = []
}
</script>
