<script setup lang="ts">
import { computed, markRaw, onMounted, ref, watch } from 'vue';
import type { RouteKey } from '@elegant-router/types';
import {
  fetchApproveOvertimeApplication,
  fetchGetOvertimeApplicationApprovalPage,
  fetchRejectOvertimeApplication
} from '@/service/api';
import { useRouterPush } from '@/hooks/common/router';
import PersonalItemOperateDialog from '@/views/personal-center/my-item/modules/personal-item-operate-dialog.vue';
import OvertimeApplicationActionDialog from '@/views/personal-center/overtime-application/modules/overtime-application-action-dialog.vue';
import OvertimeApplicationDetailDialog from '@/views/personal-center/overtime-application/modules/overtime-application-detail-dialog.vue';
import OvertimeApplicationStatusLogDialog from '@/views/personal-center/overtime-application/modules/overtime-application-status-log-dialog.vue';
import {
  type WorkbenchTodoDeadlineFilter,
  type WorkbenchTodoItem,
  type WorkbenchTodoMainTab,
  buildWorkbenchTodoItems,
  filterWorkbenchTodoItemsByCategory,
  filterWorkbenchTodoItemsByDeadline,
  isWorkbenchTodoOverdue,
  sortWorkbenchTodoItemsByPriority
} from '../homepage';
import { workbenchTodoMock } from '../mock';
import WorkbenchModuleCard from './workbench-module-card.vue';
import IconMdiCheckCircleOutline from '~icons/mdi/check-circle-outline';
import IconMdiCloseCircleOutline from '~icons/mdi/close-circle-outline';
import IconMdiEyeOutline from '~icons/mdi/eye-outline';
import IconMdiHistory from '~icons/mdi/history';

type SortKey = 'created' | 'priority' | 'deadline';
type OvertimeApprovalActionType = 'approve' | 'reject';
type ApprovalBizType = 'overtime_application';

defineOptions({ name: 'WorkbenchTodoPanel' });

interface Props {
  editing?: boolean;
  collapsed?: boolean;
}

withDefaults(defineProps<Props>(), { editing: false, collapsed: false });

defineEmits<{
  (e: 'hide'): void;
  (e: 'toggle-collapse'): void;
}>();

const { routerPushByKey } = useRouterPush();

const PAGE_SIZE = 5;

const activeTab = ref<WorkbenchTodoMainTab>('all');
const activeDeadlineFilter = ref<WorkbenchTodoDeadlineFilter>(null);
const activeApprovalBizType = ref<ApprovalBizType>('overtime_application');
const activeSort = ref<SortKey>('deadline');
const currentPage = ref(1);

const sortOptions = computed<Array<{ key: SortKey; label: string }>>(() => {
  const base: Array<{ key: SortKey; label: string }> = [
    { key: 'deadline', label: '截止时间' },
    { key: 'created', label: '创建时间' }
  ];
  if (activeTab.value === 'task') {
    base.push({ key: 'priority', label: '优先级' });
  }
  return base;
});

const mainTabs: Array<{ key: WorkbenchTodoMainTab; label: string }> = [
  { key: 'all', label: '全部' },
  { key: 'task', label: '任务' },
  { key: 'ticket', label: '工单' },
  { key: 'personal', label: '个人事项' },
  { key: 'approval', label: '待审批' }
];

const deadlineFilters: Array<{ key: Exclude<WorkbenchTodoDeadlineFilter, null>; label: string }> = [
  { key: 'overdue', label: '已逾期' },
  { key: 'today', label: '今日到期' },
  { key: 'week', label: '本周到期' }
];

const approvalBizTabs: Array<{ key: ApprovalBizType; label: string }> = [
  { key: 'overtime_application', label: '加班申请' }
];

const allItems = computed(() => buildWorkbenchTodoItems(workbenchTodoMock));
const overtimeApprovalItems = ref<WorkbenchTodoItem[]>([]);
const overtimeApprovalRows = ref<Api.OvertimeApplication.OvertimeApplication[]>([]);
const mergedItems = computed(() => {
  const mockItems = allItems.value.filter(item => item.category !== 'approval');

  return [...mockItems, ...overtimeApprovalItems.value];
});

const addDialogVisible = ref(false);
const overtimeDetailVisible = ref(false);
const overtimeStatusLogVisible = ref(false);
const overtimeActionVisible = ref(false);
const overtimeActionSubmitting = ref(false);
const currentOvertimeApplication = ref<Api.OvertimeApplication.OvertimeApplication | null>(null);
const currentOvertimeActionType = ref<OvertimeApprovalActionType>('approve');

const OVERTIME_APPROVAL_ACTION_ICONS = {
  detail: markRaw(IconMdiEyeOutline),
  approve: markRaw(IconMdiCheckCircleOutline),
  reject: markRaw(IconMdiCloseCircleOutline),
  statusLog: markRaw(IconMdiHistory)
};

function handleOpenAdd() {
  addDialogVisible.value = true;
}

function handleAddSubmitted() {
  activeTab.value = 'personal';
  activeDeadlineFilter.value = null;
}

const tabCounts = computed(() => {
  const counts: Record<WorkbenchTodoMainTab, number> = {
    all: mergedItems.value.length,
    task: 0,
    ticket: 0,
    personal: 0,
    approval: 0
  };
  mergedItems.value.forEach(item => {
    counts[item.category] += 1;
  });
  return counts;
});

const tabOverdueCount = computed(() => {
  const map: Record<WorkbenchTodoMainTab, number> = {
    all: 0,
    task: 0,
    ticket: 0,
    personal: 0,
    approval: 0
  };
  mergedItems.value.forEach(item => {
    if (!isWorkbenchTodoOverdue(item)) return;
    map.all += 1;
    map[item.category] += 1;
  });
  return map;
});

const itemsInTab = computed(() => filterWorkbenchTodoItemsByCategory(mergedItems.value, activeTab.value));

const filteredItems = computed(() => {
  if (activeTab.value === 'approval') {
    return itemsInTab.value.filter(item => item.approvalBizType === activeApprovalBizType.value);
  }

  return filterWorkbenchTodoItemsByDeadline(itemsInTab.value, activeDeadlineFilter.value);
});

const approvalBizTabCounts = computed(() => {
  const counts: Record<ApprovalBizType, number> = {
    overtime_application: 0
  };

  itemsInTab.value.forEach(item => {
    if (item.approvalBizType === 'overtime_application') {
      counts.overtime_application += 1;
    }
  });

  return counts;
});

const sortedItems = computed(() => {
  const base = filteredItems.value;
  if (activeSort.value === 'priority') {
    return sortWorkbenchTodoItemsByPriority(base, 'desc');
  }
  if (activeSort.value === 'deadline') {
    return [...base].sort((left, right) => {
      const leftValue = left.remainingDays === null ? Number.POSITIVE_INFINITY : left.remainingDays;
      const rightValue = right.remainingDays === null ? Number.POSITIVE_INFINITY : right.remainingDays;
      return leftValue - rightValue;
    });
  }
  return base;
});

const currentSortLabel = computed(
  () => sortOptions.value.find(option => option.key === activeSort.value)?.label ?? '排序'
);

const pagedItems = computed(() => {
  const start = (currentPage.value - 1) * PAGE_SIZE;
  return sortedItems.value.slice(start, start + PAGE_SIZE);
});

watch([activeTab, activeDeadlineFilter, activeSort], () => {
  currentPage.value = 1;
});

function handleSelectTab(key: WorkbenchTodoMainTab) {
  if (activeTab.value === key) return;
  activeTab.value = key;
  if (key === 'approval') activeDeadlineFilter.value = null;
  activeDeadlineFilter.value = null;
  if (key !== 'task' && activeSort.value === 'priority') {
    activeSort.value = 'deadline';
  }
}

function handleSelectDeadlineFilter(key: Exclude<WorkbenchTodoDeadlineFilter, null>) {
  activeDeadlineFilter.value = activeDeadlineFilter.value === key ? null : key;
}

function handleSelectApprovalBizType(key: ApprovalBizType) {
  activeApprovalBizType.value = key;
}

function handleSelectSort(key: SortKey) {
  activeSort.value = key;
}

function handleClickItem(item: WorkbenchTodoItem) {
  if (item.approvalBizType === 'overtime_application') {
    openOvertimeDetail(item);
    return;
  }

  if (!item.routeKey) return;
  routerPushByKey(item.routeKey as RouteKey);
}

function findOvertimeApprovalRow(item: WorkbenchTodoItem) {
  if (!item.approvalBizId) {
    return null;
  }

  return overtimeApprovalRows.value.find(row => row.id === item.approvalBizId) || null;
}

function openOvertimeDetail(item: WorkbenchTodoItem) {
  const row = findOvertimeApprovalRow(item);
  if (!row) return;

  currentOvertimeApplication.value = row;
  overtimeDetailVisible.value = true;
}

function openOvertimeStatusLog(item: WorkbenchTodoItem) {
  const row = findOvertimeApprovalRow(item);
  if (!row) return;

  currentOvertimeApplication.value = row;
  overtimeStatusLogVisible.value = true;
}

function openOvertimeAction(item: WorkbenchTodoItem, actionType: OvertimeApprovalActionType) {
  const row = findOvertimeApprovalRow(item);
  if (!row) return;

  currentOvertimeApplication.value = row;
  currentOvertimeActionType.value = actionType;
  overtimeActionVisible.value = true;
}

async function handleOvertimeActionSubmit(reason: string | null) {
  if (!currentOvertimeApplication.value) {
    return;
  }

  overtimeActionSubmitting.value = true;
  const result =
    currentOvertimeActionType.value === 'approve'
      ? await fetchApproveOvertimeApplication(currentOvertimeApplication.value.id, { reason })
      : await fetchRejectOvertimeApplication(currentOvertimeApplication.value.id, { reason });
  overtimeActionSubmitting.value = false;

  if (result.error) {
    return;
  }

  overtimeActionVisible.value = false;
  overtimeDetailVisible.value = false;
  window.$message?.success(currentOvertimeActionType.value === 'approve' ? '加班申请已通过' : '加班申请已退回');
  await loadOvertimeApprovalItems();
}

async function loadOvertimeApprovalItems() {
  const { error, data } = await fetchGetOvertimeApplicationApprovalPage({
    pageNo: 1,
    pageSize: 20,
    statusCode: 'pending',
    keyword: undefined,
    applicantName: undefined,
    approverId: undefined,
    approverName: undefined,
    overtimeDate: undefined,
    createTime: undefined
  });

  if (error || !data) {
    overtimeApprovalRows.value = [];
    overtimeApprovalItems.value = [];
    return;
  }

  overtimeApprovalRows.value = data.list;
  overtimeApprovalItems.value = buildWorkbenchTodoItems(
    data.list.map(item => ({
      id: `overtime-application-${item.id}`,
      category: 'approval',
      title: `${item.applicantName} · ${item.overtimeDate.slice(5, 7)} 月加班 ${item.overtimeDuration} 申请待审批`,
      createdTime: item.submitTime || item.createTime,
      deadline: item.submitTime || item.createTime,
      source: `加班申请 · ${item.applicantName}`,
      priority: 'mid',
      approvalBizType: 'overtime_application',
      approvalBizId: item.id
    }))
  );
}

function getDeadlineToneClass(item: WorkbenchTodoItem) {
  if (isWorkbenchTodoOverdue(item)) return 'workbench-todo__deadline--rose';
  if (item.remainingDays === 0) return 'workbench-todo__deadline--amber';
  return 'workbench-todo__deadline--slate';
}

onMounted(loadOvertimeApprovalItems);
</script>

<template>
  <WorkbenchModuleCard
    title="我的待办"
    icon="mdi:clipboard-text-clock-outline"
    :editing="editing"
    :collapsed="collapsed"
    @hide="$emit('hide')"
    @toggle-collapse="$emit('toggle-collapse')"
  >
    <div class="workbench-todo__tabs">
      <div class="workbench-todo__tabs-group">
        <ElTooltip
          v-for="tab in mainTabs"
          :key="tab.key"
          :content="`已逾期 ${tabOverdueCount[tab.key]} 项，建议尽快处理`"
          :disabled="tabOverdueCount[tab.key] === 0"
          placement="top"
          effect="dark"
        >
          <button
            type="button"
            class="workbench-todo__tab"
            :class="{ 'workbench-todo__tab--active': activeTab === tab.key }"
            @click="handleSelectTab(tab.key)"
          >
            <span>{{ tab.label }}</span>
            <span class="workbench-todo__tab-count">{{ tabCounts[tab.key] }}</span>
            <span v-if="tabOverdueCount[tab.key] > 0" class="workbench-todo__tab-dot" />
          </button>
        </ElTooltip>
      </div>

      <button type="button" class="workbench-todo__add" @click="handleOpenAdd">
        <SvgIcon icon="mdi:plus" class="workbench-todo__add-icon" />
        <span>个人事项</span>
      </button>
    </div>

    <div class="workbench-todo__filters">
      <div v-if="activeTab !== 'approval'" class="workbench-todo__filters-left">
        <button
          v-for="filter in deadlineFilters"
          :key="filter.key"
          type="button"
          class="workbench-todo__filter"
          :class="{ 'workbench-todo__filter--active': activeDeadlineFilter === filter.key }"
          @click="handleSelectDeadlineFilter(filter.key)"
        >
          {{ filter.label }}
        </button>
      </div>
      <div v-else class="workbench-todo__filters-left">
        <button
          v-for="tab in approvalBizTabs"
          :key="tab.key"
          type="button"
          class="workbench-todo__filter"
          :class="{ 'workbench-todo__filter--active': activeApprovalBizType === tab.key }"
          @click="handleSelectApprovalBizType(tab.key)"
        >
          {{ tab.label }}
          <span class="workbench-todo__filter-count">{{ approvalBizTabCounts[tab.key] }}</span>
        </button>
      </div>

      <ElDropdown trigger="click" placement="bottom-end" @command="handleSelectSort">
        <span class="workbench-todo__sort">
          排序：{{ currentSortLabel }}
          <SvgIcon icon="mdi:chevron-down" class="workbench-todo__sort-icon" />
        </span>
        <template #dropdown>
          <ElDropdownMenu>
            <ElDropdownItem
              v-for="option in sortOptions"
              :key="option.key"
              :command="option.key"
              :class="{ 'is-active': activeSort === option.key }"
            >
              {{ option.label }}
            </ElDropdownItem>
          </ElDropdownMenu>
        </template>
      </ElDropdown>
    </div>

    <div class="workbench-todo__content">
      <div v-if="pagedItems.length" class="workbench-todo__list">
        <article
          v-for="item in pagedItems"
          :key="item.id"
          class="workbench-todo__item"
          :class="{ 'workbench-todo__item--clickable': Boolean(item.routeKey || item.approvalBizType) }"
          @click="handleClickItem(item)"
        >
          <div class="workbench-todo__leading">
            <span class="workbench-todo__category" :class="`workbench-todo__category--${item.categoryTone}`">
              {{ item.categoryLabel }}
            </span>
            <span v-if="item.priority === 'high'" class="workbench-todo__priority">高</span>
          </div>

          <div class="workbench-todo__body">
            <h4 class="workbench-todo__item-title">{{ item.title }}</h4>
            <div class="workbench-todo__meta">
              <span class="workbench-todo__source">{{ item.source }}</span>
            </div>
          </div>

          <div class="workbench-todo__trailing">
            <div v-if="item.approvalBizType === 'overtime_application'" class="workbench-todo__actions" @click.stop>
              <ElTooltip content="详情">
                <ElButton link type="primary" class="workbench-todo__action-btn" @click="openOvertimeDetail(item)">
                  <component :is="OVERTIME_APPROVAL_ACTION_ICONS.detail" class="text-15px" />
                </ElButton>
              </ElTooltip>
              <ElTooltip content="通过">
                <ElButton
                  link
                  type="success"
                  class="workbench-todo__action-btn"
                  @click="openOvertimeAction(item, 'approve')"
                >
                  <component :is="OVERTIME_APPROVAL_ACTION_ICONS.approve" class="text-15px" />
                </ElButton>
              </ElTooltip>
              <ElTooltip content="退回">
                <ElButton
                  link
                  type="danger"
                  class="workbench-todo__action-btn"
                  @click="openOvertimeAction(item, 'reject')"
                >
                  <component :is="OVERTIME_APPROVAL_ACTION_ICONS.reject" class="text-15px" />
                </ElButton>
              </ElTooltip>
              <ElTooltip content="状态日志">
                <ElButton link type="info" class="workbench-todo__action-btn" @click="openOvertimeStatusLog(item)">
                  <component :is="OVERTIME_APPROVAL_ACTION_ICONS.statusLog" class="text-15px" />
                </ElButton>
              </ElTooltip>
            </div>
            <span class="workbench-todo__deadline" :class="getDeadlineToneClass(item)">
              {{ item.deadlineLabel }}
            </span>
          </div>
        </article>
      </div>
      <ElEmpty v-else description="当前筛选下暂无待办" :image-size="72" />
    </div>

    <div class="workbench-todo__pager">
      <ElPagination
        v-if="filteredItems.length > PAGE_SIZE"
        v-model:current-page="currentPage"
        :page-size="PAGE_SIZE"
        :total="filteredItems.length"
        background
        small
        layout="prev, pager, next"
      />
    </div>

    <PersonalItemOperateDialog
      v-model:visible="addDialogVisible"
      operate-type="add"
      :row-data="null"
      @submitted="handleAddSubmitted"
    />

    <OvertimeApplicationDetailDialog v-model:visible="overtimeDetailVisible" :row-data="currentOvertimeApplication" />
    <OvertimeApplicationStatusLogDialog
      v-model:visible="overtimeStatusLogVisible"
      :row-data="currentOvertimeApplication"
    />
    <OvertimeApplicationActionDialog
      v-model:visible="overtimeActionVisible"
      :action-type="currentOvertimeActionType"
      :loading="overtimeActionSubmitting"
      @submit="handleOvertimeActionSubmit"
    />
  </WorkbenchModuleCard>
</template>

<style scoped>
.workbench-todo__tabs {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 8px;
  margin-bottom: 10px;
}

.workbench-todo__tabs-group {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
}

.workbench-todo__add {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 5px 12px;
  border: 1px solid rgb(14 116 144 / 60%);
  border-radius: 999px;
  background-color: rgb(240 253 250 / 80%);
  color: rgb(14 116 144 / 96%);
  font-size: 12px;
  font-weight: 600;
  white-space: nowrap;
  cursor: pointer;
  transition: all 160ms ease;
}

.workbench-todo__add:hover {
  background-color: rgb(14 116 144 / 96%);
  border-color: rgb(14 116 144 / 96%);
  color: white;
}

.workbench-todo__add-icon {
  font-size: 14px;
}

.workbench-todo__tab {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;
  border: 1px solid rgb(226 232 240 / 92%);
  border-radius: 999px;
  background-color: rgb(255 255 255 / 96%);
  color: rgb(71 85 105 / 94%);
  font-size: 13px;
  cursor: pointer;
  transition: all 160ms ease;
}

.workbench-todo__tab:hover {
  border-color: rgb(14 116 144 / 64%);
  color: rgb(14 116 144 / 96%);
}

.workbench-todo__tab--active {
  border-color: rgb(14 116 144 / 92%);
  background-color: rgb(14 116 144 / 96%);
  color: white;
}

.workbench-todo__tab--active:hover {
  color: white;
}

.workbench-todo__tab-count {
  padding: 1px 6px;
  border-radius: 999px;
  background-color: rgb(241 245 249 / 96%);
  color: rgb(71 85 105 / 94%);
  font-size: 11px;
  font-weight: 600;
}

.workbench-todo__tab--active .workbench-todo__tab-count {
  background-color: rgb(255 255 255 / 22%);
  color: white;
}

.workbench-todo__tab-dot {
  position: absolute;
  top: 4px;
  right: 6px;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background-color: rgb(225 29 72 / 96%);
  box-shadow: 0 0 0 2px rgb(255 255 255 / 96%);
}

.workbench-todo__tab--active .workbench-todo__tab-dot {
  box-shadow: 0 0 0 2px rgb(14 116 144 / 96%);
}

.workbench-todo__filters {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  margin-bottom: 14px;
}

.workbench-todo__filters-left {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
}

.workbench-todo__sort {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  padding: 4px 8px;
  border-radius: 6px;
  color: rgb(100 116 139 / 92%);
  font-size: 12px;
  white-space: nowrap;
  cursor: pointer;
  transition: all 160ms ease;
}

.workbench-todo__sort:hover {
  background-color: rgb(241 245 249 / 96%);
  color: rgb(14 116 144 / 96%);
}

.workbench-todo__sort-icon {
  font-size: 14px;
}

:deep(.el-dropdown-menu__item.is-active) {
  color: var(--el-color-primary);
  font-weight: 600;
}

.workbench-todo__filter {
  padding: 3px 10px;
  border: 1px dashed rgb(203 213 225 / 92%);
  border-radius: 999px;
  background-color: transparent;
  color: rgb(100 116 139 / 92%);
  font-size: 12px;
  cursor: pointer;
  transition: all 160ms ease;
}

.workbench-todo__filter:hover {
  border-style: solid;
  border-color: rgb(14 116 144 / 60%);
  color: rgb(14 116 144 / 96%);
}

.workbench-todo__filter--active {
  border-style: solid;
  border-color: rgb(190 18 60 / 80%);
  background-color: rgb(255 228 230 / 96%);
  color: rgb(190 18 60 / 96%);
}

.workbench-todo__filter--active:hover {
  border-color: rgb(190 18 60 / 92%);
  color: rgb(190 18 60 / 96%);
}

.workbench-todo__filter-count {
  margin-left: 4px;
  font-size: 11px;
  font-weight: 700;
}

.workbench-todo__content {
  min-height: 400px;
  display: flex;
  flex-direction: column;
}

.workbench-todo__content :deep(.el-empty) {
  margin: auto;
}

.workbench-todo__list {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.workbench-todo__item {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 14px;
  padding: 14px 16px;
  border: 1px solid rgb(226 232 240 / 90%);
  border-radius: 16px;
  background-color: rgb(255 255 255 / 98%);
  transition:
    border-color 160ms ease,
    background-color 160ms ease;
}

.workbench-todo__item--clickable {
  cursor: pointer;
}

.workbench-todo__item--clickable:hover {
  border-color: rgb(14 116 144 / 60%);
  background-color: rgb(240 253 250 / 84%);
}

.workbench-todo__leading {
  display: flex;
  align-items: center;
  gap: 8px;
}

.workbench-todo__category {
  display: inline-flex;
  align-items: center;
  padding: 3px 10px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 600;
}

.workbench-todo__category--sky {
  background-color: rgb(224 242 254 / 96%);
  color: rgb(14 116 144 / 96%);
}

.workbench-todo__category--emerald {
  background-color: rgb(220 252 231 / 96%);
  color: rgb(5 150 105 / 96%);
}

.workbench-todo__category--amber {
  background-color: rgb(254 243 199 / 96%);
  color: rgb(180 83 9 / 96%);
}

.workbench-todo__category--rose {
  background-color: rgb(255 228 230 / 96%);
  color: rgb(190 18 60 / 96%);
}

.workbench-todo__category--violet {
  background-color: rgb(237 233 254 / 96%);
  color: rgb(109 40 217 / 96%);
}

.workbench-todo__priority {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  border-radius: 6px;
  background-color: rgb(254 226 226 / 96%);
  color: rgb(220 38 38 / 96%);
  font-size: 11px;
  font-weight: 800;
}

.workbench-todo__body {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.workbench-todo__item-title {
  margin: 0;
  color: rgb(15 23 42 / 98%);
  font-size: 14px;
  font-weight: 600;
  line-height: 1.5;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.workbench-todo__meta {
  display: flex;
  align-items: center;
  gap: 8px;
}

.workbench-todo__source {
  color: rgb(100 116 139 / 92%);
  font-size: 12px;
  line-height: 1.5;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.workbench-todo__trailing {
  display: flex;
  align-items: center;
  gap: 12px;
}

.workbench-todo__actions {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  white-space: nowrap;
}

.workbench-todo__actions :deep(.el-button + .el-button) {
  margin-left: 0;
}

:deep(.workbench-todo__action-btn) {
  min-width: auto;
  height: auto;
  padding: 3px;
  line-height: 1;
}

.workbench-todo__deadline {
  display: inline-flex;
  align-items: center;
  padding: 4px 10px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 600;
  white-space: nowrap;
}

.workbench-todo__deadline--slate {
  background-color: rgb(241 245 249 / 96%);
  color: rgb(71 85 105 / 94%);
}

.workbench-todo__deadline--amber {
  background-color: rgb(254 243 199 / 96%);
  color: rgb(180 83 9 / 96%);
}

.workbench-todo__deadline--rose {
  background-color: rgb(255 228 230 / 96%);
  color: rgb(190 18 60 / 96%);
}

.workbench-todo__pager {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  min-height: 32px;
  margin-top: 12px;
}

@media (width <= 600px) {
  .workbench-todo__item {
    grid-template-columns: auto minmax(0, 1fr);
  }

  .workbench-todo__trailing {
    grid-column: 1 / -1;
    justify-content: flex-end;
  }
}
</style>
