<template>
  <div class="p-2">
    <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
      <div v-show="showSearch">
        <el-form ref="queryFormRef" :model="queryParams" :inline="true" label-width="150px" class="bg-[#f8f8f9] p-[10px] mb-[10px]">
          <el-form-item label="分类名称" prop="categoryName">
            <el-input v-model="queryParams.categoryName" placeholder="请输入" clearable style="width: 180px" @keyup.enter="handleQuery" />
          </el-form-item>
          <el-form-item>
            <el-button type="primary" class="ml-2" @click="handleQuery">查询</el-button>
            <el-button class="ml-2" @click="resetQuery">重置</el-button>
          </el-form-item>
        </el-form>
      </div>
    </transition>

    <el-card>
      <template #header>
        <el-row :gutter="10" class="mb-[10px]">
          <el-col :span="1.5">
            <el-button type="primary" plain icon="Plus" @click="handleAdd">新增</el-button>
          </el-col>
          <el-col :span="1.5">
            <el-button type="primary" plain icon="CaretBottom" @click="handleExpandAll">{{ isExpanded ? '收起' : '展开' }}所有</el-button>
          </el-col>
        </el-row>
      </template>

      <el-table ref="tableRef" v-loading="loading" :data="categoryTreeData" row-key="categoryId" border :tree-props="{ children: 'children', hasChildren: 'hasChildren' }" class="custom-table">
        <el-table-column label="耗材分类名称" align="left" prop="categoryName" min-width="180" />
        <el-table-column label="操作" align="center" width="180">
          <template #default="scope">
            <el-button link type="danger" icon="Delete" @click="handleDelete(scope.row)" class="table-operation-button">删除</el-button>
          </template>
        </el-table-column>
      </el-table>

      <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" class="mt-[15px]" />
    </el-card>

    <!-- 添加或修改耗材分类对话框 -->
    <el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body :close-on-click-modal="false" destroy-on-close>
      <el-form ref="categoryFormRef" :model="form" :rules="rules" label-width="150px" class="mt-[20px]">
        <el-form-item label="上级分类" prop="parentId">
          <el-tree-select v-model="form.parentId" :data="categoryOptions" placeholder="请选择" clearable :props="{ 
                  label: 'categoryName',
                  value: 'categoryId',
                  children: 'children'
              }" style="width: 100%" />
        </el-form-item>
        <el-form-item label="耗材分类名称" prop="categoryName">
          <el-input v-model="form.categoryName" placeholder="请输入" />
        </el-form-item>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="cancel">关闭</el-button>
          <el-button :loading="buttonLoading" type="primary" @click="submitForm">保存</el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<script setup name="SuppliesCategory" lang="ts">
import { listSuppliesCategory, getSuppliesCategory, delSuppliesCategory, addSuppliesCategory, updateSuppliesCategory } from '@/api/warehouse/suppliesCategory/index';
import { CategoryVO, CategoryQuery, CategoryForm } from '@/api/warehouse/suppliesCategory/types';
import { handleTree } from '@/utils/tree';
import { getCurrentInstance, reactive, ref, onMounted, toRefs } from 'vue';
import type { FormInstance, ElTable } from 'element-plus';
import type { ComponentInternalInstance } from 'vue';

const { proxy } = getCurrentInstance() as ComponentInternalInstance;

const categoryList = ref<CategoryVO[]>([]);
const categoryTreeData = ref<CategoryVO[]>([]);
const loading = ref(false);
const showSearch = ref(true);
const total = ref(0);
const buttonLoading = ref(false);
const categoryOptions = ref<CategoryVO[]>([]);

const queryFormRef = ref<FormInstance>();
const categoryFormRef = ref<FormInstance>();
const tableRef = ref<InstanceType<typeof ElTable>>();
const isExpanded = ref(false);

const data = reactive<{
    form: CategoryForm;
    queryParams: CategoryQuery & {
        pageNum: number;
        pageSize: number;
    };
    rules: Record<string, any[]>;
    dialog: {
        visible: boolean;
        title: string;
    };
}>({
    form: {
        categoryId: undefined,
        parentId: undefined,
        categoryName: ''
    },
    queryParams: {
        pageNum: 1,
        pageSize: 10,
        categoryName: ''
    },
    rules: {
        categoryName: [{ required: true, message: '耗材分类名称不能为空', trigger: 'blur' }]
    },
    dialog: {
        visible: false,
        title: ''
    }
});

const { form, queryParams, rules, dialog } = toRefs(data);

/** 查询分类列表 */
const getList = async () => {
    loading.value = true;
    try {
        const res = await listSuppliesCategory(queryParams.value);
        categoryList.value = res.rows;
        total.value = res.total;
        // 构建树形数据
        categoryTreeData.value = handleTree(res.rows, 'categoryId', 'parentId');
        // 构建选择项数据
        categoryOptions.value = handleTree(res.rows, 'categoryId', 'parentId');
    } catch (error) {
        console.error(error);
    } finally {
        loading.value = false;
    }
}

/** 取消按钮 */
const cancel = () => {
    reset();
    dialog.value.visible = false;
}

/** 表单重置 */
const reset = () => {
    form.value = {
        categoryId: undefined,
        parentId: undefined,
        categoryName: ''
    };
    categoryFormRef.value?.resetFields();
}

/** 搜索按钮操作 */
const handleQuery = () => {
    queryParams.value.pageNum = 1;
    getList();
}

/** 重置按钮操作 */
const resetQuery = () => {
    queryFormRef.value?.resetFields();
    handleQuery();
}

/** 新增按钮操作 */
const handleAdd = () => {
    reset();
    dialog.value.visible = true;
    dialog.value.title = '新增';
}

/** 修改按钮操作 */
const handleUpdate = async (row: CategoryVO) => {
    reset();
    const id = row.categoryId;
    const res = await getSuppliesCategory(id);
    Object.assign(form.value, res.data);
    dialog.value.visible = true;
    dialog.value.title = '修改分类';
}

/** 提交按钮 */
const submitForm = async () => {
    categoryFormRef.value?.validate(async (valid: boolean) => {
        if (valid) {
            buttonLoading.value = true;
            try {
                if (form.value.categoryId) {
                    await updateSuppliesCategory(form.value);
                } else {
                    await addSuppliesCategory(form.value);
                }
                proxy?.$modal.msgSuccess('操作成功');
                dialog.value.visible = false;
                await getList();
            } catch (error) {
                console.error(error);
            } finally {
                buttonLoading.value = false;
            }
        }
    });
}

/** 删除按钮操作 */
const handleDelete = async (row: CategoryVO) => {
    const categoryIds = [row.categoryId];
    proxy?.$modal.confirm('是否确认删除分类编号为"' + categoryIds + '"的数据项?').then(async () => {
        try {
            await delSuppliesCategory(categoryIds);
            proxy?.$modal.msgSuccess('删除成功');
            await getList();
        } catch (error) {
            console.error(error);
        }
    });
}

/** 展开/收起所有 */
const handleExpandAll = () => {
    if (!tableRef.value) return;

    const status = !isExpanded.value;
    isExpanded.value = status;

    categoryTreeData.value.forEach((row) => {
        tableRef.value?.toggleRowExpansion(row, status);
    });
};

onMounted(() => {
    getList();
});
</script>

<style lang="scss" scoped>
    .custom-table {
        :deep(.el-table__border) {
            border-color: #ebeef5;
        }

        :deep(.el-table__inner-wrapper::before) {
            background-color: #ebeef5;
        }

        :deep(.el-table__row) {
            height: 50px;
        }

        :deep(.el-table__cell) {
            padding: 8px 0;
        }

        :deep(.table-operation-button) {
            padding: 0 12px;
            font-size: 14px;

            &.el-button--danger {
                color: #ff4d4f;
                margin-left: 16px;

                &:hover {
                    color: #ff7875;
                }
            }
        }
    }

    :deep(.el-card) {
        border-radius: 4px;

        .el-card__header {
            padding: 12px 20px;
            border-bottom: 1px solid #ebeef5;
        }
    }

    :deep(.el-dialog) {
        border-radius: 8px;

        .el-dialog__header {
            margin: 0;
            padding: 15px 20px;
            border-bottom: 1px solid #dcdfe6;
        }

        .el-dialog__title {
            font-size: 15px;
            font-weight: 500;
        }

        .el-dialog__body {
            padding: 20px;
        }

        .el-dialog__footer {
            padding: 15px 20px;
            border-top: 1px solid #dcdfe6;
        }
    }
</style>
