<script lang="ts" setup>
import type { FormInstance, FormRules } from 'element-plus';
import type { Post, PostCreateInput } from '#/api/core/post';

import { computed, onMounted, reactive, ref } from 'vue';

import { Page } from '@vben/common-ui';
import { Edit, Plus, RefreshCw, Search, Trash2 } from '@vben/icons';

import {
  ElButton,
  ElDialog,
  ElForm,
  ElFormItem,
  ElInput,
  ElInputNumber,
  ElMessage,
  ElMessageBox,
  ElOption,
  ElPagination,
  ElSelect,
  ElSwitch,
  ElTable,
  ElTableColumn,
  ElTag,
} from 'element-plus';

import {
  createPostApi,
  deletePostApi,
  getPostListApi,
  updatePostApi,
} from '#/api/core/post';

defineOptions({ name: 'SystemPost' });

type NullableStatus = '' | boolean;

const postTypeOptions = [
  { label: '管理岗', value: 0 },
  { label: '技术岗', value: 1 },
  { label: '业务岗', value: 2 },
  { label: '职能岗', value: 3 },
  { label: '其他', value: 4 },
];

const postLevelOptions = [
  { label: '高层', value: 0 },
  { label: '中层', value: 1 },
  { label: '基层', value: 2 },
  { label: '一般员工', value: 3 },
];

const loading = ref(false);
const saving = ref(false);
const dialogVisible = ref(false);
const editingPostId = ref<string>();
const tableData = ref<Post[]>([]);
const formRef = ref<FormInstance>();

const query = reactive({
  code: '',
  name: '',
  page: 1,
  pageSize: 20,
  status: '' as NullableStatus,
});

const total = ref(0);

const form = reactive<PostCreateInput>({
  code: '',
  description: '',
  name: '',
  post_level: 3,
  post_type: 4,
  sort: 0,
  status: true,
});

const rules: FormRules = {
  code: [
    { message: '请输入岗位编码', required: true, trigger: 'blur' },
    {
      message: '岗位编码只能包含字母、数字、下划线和横线',
      pattern: /^[\w-]+$/,
      trigger: 'blur',
    },
  ],
  name: [{ message: '请输入岗位名称', required: true, trigger: 'blur' }],
};

const dialogTitle = computed(() =>
  editingPostId.value ? '编辑岗位' : '新增岗位',
);

function getOptionLabel(
  options: Array<{ label: string; value: number }>,
  value?: number,
) {
  return options.find((item) => item.value === value)?.label ?? '-';
}

function resetForm() {
  editingPostId.value = undefined;
  Object.assign(form, {
    code: '',
    description: '',
    name: '',
    post_level: 3,
    post_type: 4,
    sort: 0,
    status: true,
  });
  formRef.value?.clearValidate();
}

async function loadPosts() {
  loading.value = true;
  try {
    const res = await getPostListApi({
      code: query.code || undefined,
      name: query.name || undefined,
      page: query.page,
      pageSize: query.pageSize,
      status: query.status === '' ? undefined : query.status,
    });
    tableData.value = res.items ?? [];
    total.value = res.total ?? 0;
  } finally {
    loading.value = false;
  }
}

function onSearch() {
  query.page = 1;
  loadPosts();
}

function onReset() {
  Object.assign(query, {
    code: '',
    name: '',
    page: 1,
    status: '',
  });
  loadPosts();
}

function onCreate() {
  resetForm();
  dialogVisible.value = true;
}

function onEdit(row: Post) {
  resetForm();
  editingPostId.value = row.id;
  Object.assign(form, {
    code: row.code,
    description: row.description ?? '',
    name: row.name,
    post_level: row.post_level ?? 3,
    post_type: row.post_type ?? 4,
    sort: row.sort ?? 0,
    status: row.status,
  });
  dialogVisible.value = true;
}

async function onSave() {
  await formRef.value?.validate();
  saving.value = true;
  try {
    const payload = { ...form };
    if (editingPostId.value) {
      await updatePostApi(editingPostId.value, payload);
      ElMessage.success('岗位已更新');
    } else {
      await createPostApi(payload);
      ElMessage.success('岗位已新增');
    }
    dialogVisible.value = false;
    await loadPosts();
  } finally {
    saving.value = false;
  }
}

async function onDelete(row: Post) {
  await ElMessageBox.confirm(
    `确定删除岗位「${row.name}」吗？`,
    '删除岗位',
    {
      cancelButtonText: '取消',
      confirmButtonText: '删除',
      type: 'warning',
    },
  );
  await deletePostApi(row.id);
  ElMessage.success('岗位已删除');
  await loadPosts();
}

async function onStatusChange(row: Post, status: boolean) {
  try {
    await updatePostApi(row.id, { status });
    ElMessage.success(status ? '岗位已启用' : '岗位已禁用');
  } catch (error) {
    row.status = !status;
    throw error;
  }
}

onMounted(loadPosts);
</script>

<template>
  <Page auto-content-height>
    <div class="flex h-full min-h-0 flex-col gap-3">
      <div
        class="bg-background flex flex-wrap items-end gap-3 rounded-lg border border-border px-4 py-3"
      >
        <ElForm inline :model="query" class="post-search-form">
          <ElFormItem label="岗位名称">
            <ElInput
              v-model="query.name"
              clearable
              placeholder="请输入岗位名称"
              @keyup.enter="onSearch"
            />
          </ElFormItem>
          <ElFormItem label="岗位编码">
            <ElInput
              v-model="query.code"
              clearable
              placeholder="请输入岗位编码"
              @keyup.enter="onSearch"
            />
          </ElFormItem>
          <ElFormItem label="状态">
            <ElSelect
              v-model="query.status"
              clearable
              placeholder="全部"
              class="w-[120px]"
            >
              <ElOption label="启用" :value="true" />
              <ElOption label="禁用" :value="false" />
            </ElSelect>
          </ElFormItem>
          <ElFormItem>
            <ElButton type="primary" :icon="Search" @click="onSearch">
              查询
            </ElButton>
            <ElButton :icon="RefreshCw" @click="onReset">重置</ElButton>
          </ElFormItem>
        </ElForm>
        <div class="ml-auto">
          <ElButton type="primary" :icon="Plus" @click="onCreate">
            新增岗位
          </ElButton>
        </div>
      </div>

      <div
        class="bg-background flex min-h-0 flex-1 flex-col rounded-lg border border-border"
      >
        <ElTable
          v-loading="loading"
          :data="tableData"
          height="100%"
          row-key="id"
          stripe
        >
          <ElTableColumn type="index" width="56" label="#" />
          <ElTableColumn prop="name" label="岗位名称" min-width="150" />
          <ElTableColumn prop="code" label="岗位编码" min-width="140" />
          <ElTableColumn label="岗位类型" min-width="110">
            <template #default="{ row }">
              {{ getOptionLabel(postTypeOptions, row.post_type) }}
            </template>
          </ElTableColumn>
          <ElTableColumn label="岗位级别" min-width="110">
            <template #default="{ row }">
              {{ getOptionLabel(postLevelOptions, row.post_level) }}
            </template>
          </ElTableColumn>
          <ElTableColumn prop="dept_name" label="所属部门" min-width="140">
            <template #default="{ row }">
              {{ row.dept_name || '-' }}
            </template>
          </ElTableColumn>
          <ElTableColumn label="状态" width="110">
            <template #default="{ row }">
              <ElSwitch
                v-model="row.status"
                inline-prompt
                active-text="启"
                inactive-text="禁"
                @change="(value) => onStatusChange(row, value as boolean)"
              />
            </template>
          </ElTableColumn>
          <ElTableColumn label="用户数" width="90" align="center">
            <template #default="{ row }">
              <ElTag type="info" effect="plain">{{ row.user_count ?? 0 }}</ElTag>
            </template>
          </ElTableColumn>
          <ElTableColumn prop="sort" label="排序" width="90" align="center" />
          <ElTableColumn
            prop="sys_create_datetime"
            label="创建时间"
            min-width="170"
          />
          <ElTableColumn label="操作" width="150" fixed="right">
            <template #default="{ row }">
              <ElButton link type="primary" :icon="Edit" @click="onEdit(row)">
                编辑
              </ElButton>
              <ElButton link type="danger" :icon="Trash2" @click="onDelete(row)">
                删除
              </ElButton>
            </template>
          </ElTableColumn>
        </ElTable>

        <div class="flex justify-end border-t border-border px-4 py-3">
          <ElPagination
            v-model:current-page="query.page"
            v-model:page-size="query.pageSize"
            :page-sizes="[10, 20, 50, 100]"
            :total="total"
            background
            layout="total, sizes, prev, pager, next, jumper"
            @current-change="loadPosts"
            @size-change="onSearch"
          />
        </div>
      </div>
    </div>

    <ElDialog v-model="dialogVisible" :title="dialogTitle" width="520px">
      <ElForm ref="formRef" :model="form" :rules="rules" label-width="92px">
        <ElFormItem label="岗位名称" prop="name">
          <ElInput v-model="form.name" maxlength="64" placeholder="请输入岗位名称" />
        </ElFormItem>
        <ElFormItem label="岗位编码" prop="code">
          <ElInput v-model="form.code" maxlength="32" placeholder="请输入岗位编码" />
        </ElFormItem>
        <ElFormItem label="岗位类型">
          <ElSelect v-model="form.post_type" class="w-full">
            <ElOption
              v-for="item in postTypeOptions"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            />
          </ElSelect>
        </ElFormItem>
        <ElFormItem label="岗位级别">
          <ElSelect v-model="form.post_level" class="w-full">
            <ElOption
              v-for="item in postLevelOptions"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            />
          </ElSelect>
        </ElFormItem>
        <ElFormItem label="排序">
          <ElInputNumber v-model="form.sort" :min="0" class="w-full" />
        </ElFormItem>
        <ElFormItem label="状态">
          <ElSwitch
            v-model="form.status"
            inline-prompt
            active-text="启用"
            inactive-text="禁用"
          />
        </ElFormItem>
        <ElFormItem label="岗位描述">
          <ElInput
            v-model="form.description"
            maxlength="200"
            placeholder="请输入岗位描述"
            show-word-limit
            type="textarea"
            :rows="3"
          />
        </ElFormItem>
      </ElForm>
      <template #footer>
        <ElButton @click="dialogVisible = false">取消</ElButton>
        <ElButton type="primary" :loading="saving" @click="onSave">
          保存
        </ElButton>
      </template>
    </ElDialog>
  </Page>
</template>

<style scoped>
.post-search-form {
  margin-bottom: -18px;
}
</style>
