<script setup lang="ts">
import { computed, reactive, watch } from 'vue';
import { fetchGetProjectExecutionAssigneeLogPage } from '@/service/api';
import { useUIPaginatedTable } from '@/hooks/common/table';
import BusinessUserSelect from '@/components/custom/business-user-select.vue';
import { formatDateTime, getExecutionAssigneeActionName, getExecutionAssigneeActionTagType } from '../shared';

defineOptions({ name: 'ProjectExecutionAssigneeLogPanel' });

interface Props {
  projectId: string;
  executionId: string;
  userOptions: Api.SystemManage.UserSimple[];
  active: boolean;
}

const props = defineProps<Props>();

type ActionType = Api.Project.ExecutionAssigneeActionType;

const ACTION_TYPE_OPTIONS: Array<{ label: string; value: ActionType }> = [
  { label: getExecutionAssigneeActionName('join'), value: 'join' },
  { label: getExecutionAssigneeActionName('inactive'), value: 'inactive' },
  { label: getExecutionAssigneeActionName('owner_transfer_in'), value: 'owner_transfer_in' },
  { label: getExecutionAssigneeActionName('owner_transfer_out'), value: 'owner_transfer_out' }
];

const searchParams = reactive<{
  pageNo: number;
  pageSize: number;
  actionTypes?: ActionType[];
  userId?: string;
}>({
  pageNo: 1,
  pageSize: 5,
  actionTypes: undefined,
  userId: undefined
});

const canLoad = computed(() => Boolean(props.projectId && props.executionId));

type LogPageResponse = Awaited<ReturnType<typeof fetchGetProjectExecutionAssigneeLogPage>>;

function buildRequestParams(): Api.Project.ExecutionAssigneeLogSearchParams {
  return {
    pageNo: searchParams.pageNo,
    pageSize: searchParams.pageSize,
    actionTypes: searchParams.actionTypes?.length ? searchParams.actionTypes : undefined,
    userId: searchParams.userId || undefined
  };
}

function transformLogPage(response: LogPageResponse, pageNo: number, pageSize: number) {
  if (!response.error && response.data) {
    return {
      data: response.data.list,
      pageNum: pageNo,
      pageSize,
      total: response.data.total
    };
  }

  return {
    data: [],
    pageNum: pageNo,
    pageSize,
    total: 0
  };
}

const { data, loading, getDataByPage, mobilePagination } = useUIPaginatedTable<
  LogPageResponse,
  Api.Project.ExecutionAssigneeLog
>({
  paginationProps: {
    currentPage: searchParams.pageNo,
    pageSize: searchParams.pageSize
  },
  api: () => {
    if (!canLoad.value) {
      return Promise.resolve({
        data: { total: 0, list: [] },
        error: null
      } as unknown as LogPageResponse);
    }

    return fetchGetProjectExecutionAssigneeLogPage(props.projectId, props.executionId, buildRequestParams());
  },
  transform: response => transformLogPage(response, searchParams.pageNo ?? 1, searchParams.pageSize ?? 5),
  onPaginationParamsChange: params => {
    searchParams.pageNo = params.currentPage ?? 1;
    searchParams.pageSize = params.pageSize ?? 5;
  },
  immediate: false,
  columns: () => [{ prop: 'actionTime', label: '时间' }]
});

// 每次切到该 tab 都按当前筛选条件重拉第 1 页，确保用户在"当前成员" tab 操作后回到这里能看到最新事件
watch(
  () => props.active,
  active => {
    if (active && canLoad.value) {
      getDataByPage(1);
    }
  },
  { immediate: true }
);

// 切换到不同执行项时完全清空筛选条件
watch(
  () => props.executionId,
  () => {
    resetSearchParams();
  }
);

function resetSearchParams() {
  searchParams.pageNo = 1;
  searchParams.actionTypes = undefined;
  searchParams.userId = undefined;
}

async function handleSearch() {
  await getDataByPage(1);
}

async function handleReset() {
  resetSearchParams();
  await getDataByPage(1);
}

function getAssigneeDisplay(row: Api.Project.ExecutionAssigneeLog) {
  return row.userNicknameSnapshot?.trim() || row.userId || '--';
}

function getOperatorDisplay(row: Api.Project.ExecutionAssigneeLog) {
  return row.operatorNicknameSnapshot?.trim() || row.operatorUserId || '--';
}

function refresh() {
  return getDataByPage(1);
}

defineExpose({ refresh });
</script>

<template>
  <div class="assignee-log-panel">
    <div class="assignee-log-panel__toolbar">
      <ElSelect
        v-model="searchParams.actionTypes"
        multiple
        collapse-tags
        collapse-tags-tooltip
        clearable
        placeholder="全部事件"
        class="assignee-log-panel__action-select"
      >
        <ElOption v-for="item in ACTION_TYPE_OPTIONS" :key="item.value" :label="item.label" :value="item.value" />
      </ElSelect>
      <BusinessUserSelect
        v-model="searchParams.userId"
        :options="userOptions"
        placeholder="全部协办人"
        clearable
        class="assignee-log-panel__user-select"
      />
      <div class="assignee-log-panel__actions">
        <ElButton @click="handleReset">重置</ElButton>
        <ElButton type="primary" @click="handleSearch">查询</ElButton>
      </div>
    </div>

    <ElTable v-loading="loading" :data="data" :height="247" border size="default">
      <ElTableColumn label="时间" width="170" align="center">
        <template #default="{ row }">
          {{ formatDateTime(row.actionTime) }}
        </template>
      </ElTableColumn>
      <ElTableColumn label="事件类型" width="130" align="center">
        <template #default="{ row }">
          <ElTag :type="getExecutionAssigneeActionTagType(row.actionType)" effect="light">
            {{ getExecutionAssigneeActionName(row.actionType) }}
          </ElTag>
        </template>
      </ElTableColumn>
      <ElTableColumn label="协办人" min-width="120" show-overflow-tooltip>
        <template #default="{ row }">
          {{ getAssigneeDisplay(row) }}
        </template>
      </ElTableColumn>
      <ElTableColumn label="操作人" min-width="120" show-overflow-tooltip>
        <template #default="{ row }">
          {{ getOperatorDisplay(row) }}
        </template>
      </ElTableColumn>
      <ElTableColumn label="原因" min-width="200" show-overflow-tooltip>
        <template #default="{ row }">
          <span v-if="row.reason">{{ row.reason }}</span>
          <span v-else class="assignee-log-panel__empty">--</span>
        </template>
      </ElTableColumn>

      <template #empty>
        <ElEmpty description="暂无变更记录" :image-size="80" />
      </template>
    </ElTable>

    <div class="assignee-log-panel__pagination">
      <ElPagination
        v-if="mobilePagination.total"
        background
        layout="total, prev, pager, next"
        size="small"
        v-bind="mobilePagination"
        @current-change="mobilePagination['current-change']"
        @size-change="mobilePagination['size-change']"
      />
    </div>
  </div>
</template>

<style scoped lang="scss">
.assignee-log-panel {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.assignee-log-panel__toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
}

.assignee-log-panel__action-select {
  width: 200px;
}

.assignee-log-panel__user-select {
  width: 200px;
}

.assignee-log-panel__actions {
  display: flex;
  gap: 12px;
  margin-left: auto;
}

.assignee-log-panel__empty {
  color: var(--el-text-color-placeholder);
}

.assignee-log-panel__pagination {
  display: flex;
  justify-content: flex-end;
  min-height: 32px;
}
</style>
