<template>
  <div class="users-container">
    <el-card>
      <div class="header-actions">
        <el-form :inline="true" :model="searchForm" class="search-form">
          <el-form-item label="关键词">
            <el-input
              v-model="searchForm.keyword"
              placeholder="姓名或手机号"
              clearable
            />
          </el-form-item>
          <el-form-item label="角色">
            <el-select
              v-model="searchForm.role"
              placeholder="请选择角色"
              clearable
            >
              <el-option
                v-for="option in availableRoleOptions"
                :key="option.value"
                :label="option.label"
                :value="option.value"
              />
            </el-select>
          </el-form-item>
          <el-form-item>
            <el-button type="primary" @click="handleSearch" icon="Search">
              查询
            </el-button>
            <el-button @click="resetSearch" icon="Refresh">重置</el-button>
            <el-button
              v-if="canManageUsers"
              type="success"
              @click="openCreateDialog"
              icon="Plus"
            >
              {{ createButtonText }}
            </el-button>
          </el-form-item>
        </el-form>
      </div>

      <el-table
        :data="tableData"
        v-loading="loading"
        border
        stripe
        style="width: 100%"
      >
        <el-table-column prop="id" label="ID" width="80" align="center" />
        <el-table-column prop="name" label="姓名" min-width="120" />
        <el-table-column prop="phone" label="手机号" min-width="150" />
        <el-table-column label="角色" min-width="120">
          <template #default="{ row }">
            <el-tag :type="getRoleTagType(row.role)">
              {{ getRoleName(row.role) }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column v-if="canManageUsers" label="所属医院" min-width="150">
          <template #default="{ row }">
            {{ resolveHospitalName(row.hospitalId) }}
          </template>
        </el-table-column>
        <el-table-column label="所属科室" min-width="150">
          <template #default="{ row }">
            {{ resolveDepartmentName(row.departmentId) }}
          </template>
        </el-table-column>
        <el-table-column label="所属小组" min-width="150">
          <template #default="{ row }">
            {{ resolveGroupName(row.groupId) }}
          </template>
        </el-table-column>
        <el-table-column label="操作" width="280" fixed="right" align="center">
          <template #default="{ row }">
            <el-button
              v-if="canViewPatientRecords(row)"
              size="small"
              type="success"
              plain
              @click="openPatientRecords(row)"
            >
              手术记录
            </el-button>
            <el-button
              v-if="
                row.role === 'ENGINEER' && userStore.role === 'SYSTEM_ADMIN'
              "
              size="small"
              type="warning"
              @click="openAssignDialog(row)"
            >
              分配医院
            </el-button>
            <el-button
              v-if="canManageUsers"
              size="small"
              type="primary"
              @click="openEditDialog(row)"
            >
              编辑
            </el-button>
            <el-button
              v-if="canDeleteUser(row)"
              size="small"
              type="danger"
              @click="handleDelete(row)"
            >
              删除
            </el-button>
          </template>
        </el-table-column>
      </el-table>

      <div class="pagination-container">
        <el-pagination
          v-model:current-page="page"
          v-model:page-size="pageSize"
          :page-sizes="[10, 20, 50, 100]"
          :total="total"
          background
          layout="total, sizes, prev, pager, next, jumper"
          @size-change="fetchData"
          @current-change="fetchData"
        />
      </div>
    </el-card>

    <el-dialog
      :title="dialogTitle"
      v-model="dialogVisible"
      width="620px"
      @close="resetForm"
    >
      <el-form :model="form" :rules="rules" ref="formRef" label-width="100px">
        <el-form-item label="姓名" prop="name">
          <el-input v-model="form.name" placeholder="请输入姓名" />
        </el-form-item>
        <el-form-item label="手机号" prop="phone">
          <el-input v-model="form.phone" placeholder="请输入手机号" />
        </el-form-item>
        <el-form-item label="密码" prop="password" v-if="!isEdit">
          <el-input
            v-model="form.password"
            type="password"
            show-password
            placeholder="请输入密码（至少 8 位）"
          />
        </el-form-item>
        <el-form-item label="角色" prop="role">
          <el-select
            v-model="form.role"
            placeholder="请选择角色"
            style="width: 100%"
          >
            <el-option
              v-for="option in availableRoleOptions"
              :key="option.value"
              :label="option.label"
              :value="option.value"
            />
          </el-select>
        </el-form-item>

        <el-form-item label="所属医院" prop="hospitalId" v-if="needHospital">
          <el-select
            v-model="form.hospitalId"
            placeholder="请选择医院"
            style="width: 100%"
            :disabled="lockHospital"
          >
            <el-option
              v-for="hospital in hospitals"
              :key="hospital.id"
              :label="hospital.name"
              :value="hospital.id"
            />
          </el-select>
        </el-form-item>

        <el-form-item
          label="所属科室"
          prop="departmentId"
          v-if="needDepartment"
        >
          <el-select
            v-model="form.departmentId"
            placeholder="请选择科室"
            style="width: 100%"
            :disabled="lockDepartment"
          >
            <el-option
              v-for="department in formDepartments"
              :key="department.id"
              :label="department.name"
              :value="department.id"
            />
          </el-select>
        </el-form-item>

        <el-form-item label="所属小组" prop="groupId" v-if="needGroup">
          <el-select
            v-model="form.groupId"
            placeholder="请选择小组"
            style="width: 100%"
          >
            <el-option
              v-for="group in formGroups"
              :key="group.id"
              :label="group.name"
              :value="group.id"
            />
          </el-select>
        </el-form-item>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="dialogVisible = false">取消</el-button>
          <el-button
            type="primary"
            @click="handleSubmit"
            :loading="submitLoading"
          >
            确定
          </el-button>
        </div>
      </template>
    </el-dialog>

    <el-dialog
      title="分配工程师医院"
      v-model="assignDialogVisible"
      width="500px"
    >
      <el-form label-width="100px">
        <el-form-item label="工程师">
          <el-input :value="currentAssignUser?.name" disabled />
        </el-form-item>
        <el-form-item label="医院" required>
          <el-select
            v-model="assignHospitalId"
            placeholder="请选择医院"
            style="width: 100%"
          >
            <el-option
              v-for="hospital in hospitals"
              :key="hospital.id"
              :label="hospital.name"
              :value="hospital.id"
            />
          </el-select>
        </el-form-item>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="assignDialogVisible = false">取消</el-button>
          <el-button
            type="primary"
            @click="handleAssignSubmit"
            :loading="submitLoading"
          >
            确定
          </el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
import { computed, onMounted, reactive, ref, watch } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import { ElMessage, ElMessageBox } from 'element-plus';
import {
  getUsers,
  createUser,
  updateUser,
  deleteUser,
  assignEngineerHospital,
} from '../../api/users';
import {
  getHospitals,
  getDepartments,
  getGroups,
} from '../../api/organization';
import { useUserStore } from '../../store/user';

const BASE_ROLE_OPTIONS = [
  { label: '系统管理员', value: 'SYSTEM_ADMIN' },
  { label: '医院管理员', value: 'HOSPITAL_ADMIN' },
  { label: '科室主任', value: 'DIRECTOR' },
  { label: '小组组长', value: 'LEADER' },
  { label: '医生', value: 'DOCTOR' },
  { label: '工程师', value: 'ENGINEER' },
];

const route = useRoute();
const router = useRouter();
const userStore = useUserStore();

const loading = ref(false);
const tableData = ref([]);
const total = ref(0);
const page = ref(1);
const pageSize = ref(10);

const hospitals = ref([]);
const departments = ref([]);
const groups = ref([]);

const isDirector = computed(() => userStore.role === 'DIRECTOR');
const isLeader = computed(() => userStore.role === 'LEADER');
const canManageUsers = computed(() =>
  ['SYSTEM_ADMIN', 'HOSPITAL_ADMIN'].includes(userStore.role),
);
const availableRoleOptions = computed(() => {
  if (isDirector.value) {
    return BASE_ROLE_OPTIONS.filter((option) =>
      ['LEADER', 'DOCTOR'].includes(option.value),
    );
  }

  if (isLeader.value) {
    return BASE_ROLE_OPTIONS.filter((option) => option.value === 'DOCTOR');
  }

  if (userStore.role === 'HOSPITAL_ADMIN') {
    return BASE_ROLE_OPTIONS.filter(
      (option) => !['SYSTEM_ADMIN', 'HOSPITAL_ADMIN'].includes(option.value),
    );
  }

  return BASE_ROLE_OPTIONS;
});
const searchForm = reactive({
  keyword: '',
  role: '',
});

const dialogVisible = ref(false);
const isEdit = ref(false);
const submitLoading = ref(false);
const formRef = ref(null);
const currentId = ref(null);
const formDepartments = ref([]);
const formGroups = ref([]);

const form = reactive({
  name: '',
  phone: '',
  password: '',
  role: '',
  hospitalId: null,
  departmentId: null,
  groupId: null,
});

const assignDialogVisible = ref(false);
const currentAssignUser = ref(null);
const assignHospitalId = ref(null);

const createButtonText = computed(() => '新增用户');
const dialogTitle = computed(() => (isEdit.value ? '编辑用户' : '新增用户'));
const needHospital = computed(() => form.role && form.role !== 'SYSTEM_ADMIN');
const needDepartment = computed(() =>
  ['DIRECTOR', 'LEADER', 'DOCTOR'].includes(form.role),
);
const needGroup = computed(() => ['LEADER', 'DOCTOR'].includes(form.role));
const lockHospital = computed(() => userStore.role === 'HOSPITAL_ADMIN');
const lockDepartment = computed(() => false);

const rules = computed(() => ({
  name: [{ required: true, message: '请输入姓名', trigger: 'blur' }],
  phone: [
    { required: true, message: '请输入手机号', trigger: 'blur' },
    { pattern: /^1\d{10}$/, message: '请输入正确的手机号', trigger: 'blur' },
  ],
  password: isEdit.value
    ? []
    : [
        { required: true, message: '请输入密码', trigger: 'blur' },
        { min: 8, message: '密码长度至少为 8 位', trigger: 'blur' },
      ],
  role: [{ required: true, message: '请选择角色', trigger: 'change' }],
  hospitalId: needHospital.value
    ? [{ required: true, message: '请选择所属医院', trigger: 'change' }]
    : [],
  departmentId: needDepartment.value
    ? [{ required: true, message: '请选择所属科室', trigger: 'change' }]
    : [],
  groupId: needGroup.value
    ? [{ required: true, message: '请选择所属小组', trigger: 'change' }]
    : [],
}));

const roleMap = {
  SYSTEM_ADMIN: '系统管理员',
  HOSPITAL_ADMIN: '医院管理员',
  DIRECTOR: '科室主任',
  LEADER: '小组组长',
  DOCTOR: '医生',
  ENGINEER: '工程师',
};

const getRoleName = (role) => roleMap[role] || role;

const getRoleTagType = (role) => {
  if (role === 'SYSTEM_ADMIN') return 'danger';
  if (role === 'HOSPITAL_ADMIN') return 'warning';
  if (role === 'ENGINEER') return 'success';
  return 'info';
};

const hospitalMap = computed(
  () => new Map(hospitals.value.map((item) => [item.id, item.name])),
);
const departmentMap = computed(
  () => new Map(departments.value.map((item) => [item.id, item.name])),
);
const groupMap = computed(
  () => new Map(groups.value.map((item) => [item.id, item.name])),
);

const resolveHospitalName = (id) => {
  if (!id) return '-';
  return hospitalMap.value.get(id) || `#${id}`;
};

const resolveDepartmentName = (id) => {
  if (!id) return '-';
  return departmentMap.value.get(id) || `#${id}`;
};

const resolveGroupName = (id) => {
  if (!id) return '-';
  return groupMap.value.get(id) || `#${id}`;
};

const fetchCommonData = async () => {
  const [hospitalRes, departmentRes, groupRes] = await Promise.all([
    getHospitals({ page: 1, pageSize: 100 }),
    getDepartments({ page: 1, pageSize: 100 }),
    getGroups({ page: 1, pageSize: 100 }),
  ]);

  hospitals.value = hospitalRes.list || [];
  departments.value = departmentRes.list || [];
  groups.value = groupRes.list || [];
};

const fetchDepartmentsForForm = async (hospitalId) => {
  form.departmentId = null;
  form.groupId = null;
  formGroups.value = [];
  if (!hospitalId) {
    formDepartments.value = [];
    return;
  }
  const res = await getDepartments({
    hospitalId,
    page: 1,
    pageSize: 100,
  });
  formDepartments.value = res.list || [];
};

const fetchGroupsForForm = async (departmentId) => {
  form.groupId = null;
  if (!departmentId) {
    formGroups.value = [];
    return;
  }
  const res = await getGroups({
    departmentId,
    page: 1,
    pageSize: 100,
  });
  formGroups.value = res.list || [];
};

const fetchData = async () => {
  loading.value = true;
  try {
    const res = await getUsers({
      page: page.value,
      pageSize: pageSize.value,
      role: searchForm.role || undefined,
      keyword: searchForm.keyword || undefined,
    });
    tableData.value = res.list || [];
    total.value = res.total || 0;
  } finally {
    loading.value = false;
  }
};

const handleSearch = () => {
  page.value = 1;
  fetchData();
};

const resetSearch = () => {
  searchForm.keyword = '';
  searchForm.role = '';
  page.value = 1;
  fetchData();
};

const openCreateDialog = async () => {
  if (!canManageUsers.value) {
    ElMessage.warning('当前角色仅支持查看，不可新增用户');
    return;
  }

  resetForm();
  isEdit.value = false;
  currentId.value = null;

  if (userStore.role === 'HOSPITAL_ADMIN') {
    form.hospitalId = userStore.userInfo?.hospitalId || null;
    if (form.hospitalId) {
      await fetchDepartmentsForForm(form.hospitalId);
    }
  }

  dialogVisible.value = true;
};

const openEditDialog = async (row) => {
  if (!canManageUsers.value) {
    ElMessage.warning('当前角色仅支持查看，不可编辑用户');
    return;
  }

  isEdit.value = true;
  currentId.value = row.id;

  form.name = row.name;
  form.phone = row.phone;
  form.password = '';
  form.role = row.role;
  form.hospitalId = row.hospitalId;
  form.departmentId = row.departmentId;
  form.groupId = row.groupId;

  if (form.hospitalId) {
    await fetchDepartmentsForForm(form.hospitalId);
    form.departmentId = row.departmentId;
  } else {
    formDepartments.value = [];
  }

  if (form.departmentId) {
    await fetchGroupsForForm(form.departmentId);
    form.groupId = row.groupId;
  } else {
    formGroups.value = [];
  }

  dialogVisible.value = true;
};

const resetForm = () => {
  formRef.value?.resetFields();
  form.name = '';
  form.phone = '';
  form.password = '';
  form.role = '';
  form.hospitalId = null;
  form.departmentId = null;
  form.groupId = null;
  formDepartments.value = [];
  formGroups.value = [];
};

const buildSubmitPayload = () => {
  const payload = {
    name: form.name,
    phone: form.phone,
    role: form.role,
    hospitalId: null,
    departmentId: null,
    groupId: null,
  };

  if (!isEdit.value) {
    payload.password = form.password;

    if (form.role === 'SYSTEM_ADMIN') {
      return payload;
    }

    payload.hospitalId = form.hospitalId;

    if (form.role === 'DIRECTOR') {
      payload.departmentId = form.departmentId;
      return payload;
    }

    if (form.role === 'LEADER' || form.role === 'DOCTOR') {
      payload.departmentId = form.departmentId;
      payload.groupId = form.groupId;
      return payload;
    }

    return payload;
  }

  if (form.role === 'SYSTEM_ADMIN') {
    return payload;
  }

  payload.hospitalId = form.hospitalId;

  if (form.role === 'DOCTOR') {
    payload.departmentId = form.departmentId;
    payload.groupId = form.groupId;
    return payload;
  }

  if (form.role === 'DIRECTOR') {
    payload.departmentId = form.departmentId;
    payload.groupId = null;
    return payload;
  }

  if (form.role === 'LEADER') {
    payload.departmentId = form.departmentId;
    payload.groupId = form.groupId;
    return payload;
  }

  delete payload.departmentId;
  delete payload.groupId;
  return payload;
};

const handleSubmit = async () => {
  if (!canManageUsers.value) {
    ElMessage.warning('当前角色仅支持查看，不可提交用户变更');
    return;
  }

  if (!formRef.value) return;

  await formRef.value.validate(async (valid) => {
    if (!valid) return;

    submitLoading.value = true;
    try {
      const payload = buildSubmitPayload();
      if (!payload) {
        return;
      }
      if (isEdit.value) {
        await updateUser(currentId.value, payload);
        ElMessage.success('更新成功');
      } else {
        await createUser(payload);
        ElMessage.success('创建成功');
      }
      dialogVisible.value = false;
      await fetchCommonData();
      await fetchData();
    } finally {
      submitLoading.value = false;
    }
  });
};

const handleDelete = (row) => {
  if (!canManageUsers.value) {
    ElMessage.warning('当前角色仅支持查看，不可删除用户');
    return;
  }

  ElMessageBox.confirm(`确定要删除用户 "${row.name}" 吗？`, '警告', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning',
  })
    .then(async () => {
      await deleteUser(row.id);
      ElMessage.success('删除成功');
      await fetchData();
    })
    .catch(() => {});
};

const openAssignDialog = (row) => {
  currentAssignUser.value = row;
  assignHospitalId.value = row.hospitalId || null;
  assignDialogVisible.value = true;
};

const handleAssignSubmit = async () => {
  if (!Number.isInteger(assignHospitalId.value)) {
    ElMessage.warning('请选择医院');
    return;
  }

  submitLoading.value = true;
  try {
    await assignEngineerHospital(
      currentAssignUser.value.id,
      assignHospitalId.value,
    );
    ElMessage.success('分配成功');
    assignDialogVisible.value = false;
    await fetchCommonData();
    await fetchData();
  } finally {
    submitLoading.value = false;
  }
};

const openPatientRecords = (row) => {
  router.push({
    path: '/patients',
    query: {
      doctorId: String(row.id),
      doctorName: row.name || '',
    },
  });
};

watch(
  () => form.role,
  async (role) => {
    if (!role) {
      form.hospitalId = null;
      form.departmentId = null;
      form.groupId = null;
      formDepartments.value = [];
      formGroups.value = [];
      return;
    }

    if (role === 'SYSTEM_ADMIN') {
      form.hospitalId = null;
      form.departmentId = null;
      form.groupId = null;
      formDepartments.value = [];
      formGroups.value = [];
      return;
    }

    if (!needDepartment.value) {
      form.departmentId = null;
      form.groupId = null;
      formGroups.value = [];
    }

    if (!needGroup.value) {
      form.groupId = null;
    }
  },
);

watch(
  () => form.hospitalId,
  async (hospitalId, oldHospitalId) => {
    if (!dialogVisible.value || hospitalId === oldHospitalId) {
      return;
    }
    if (!needDepartment.value) {
      return;
    }
    await fetchDepartmentsForForm(hospitalId);
  },
);

watch(
  () => form.departmentId,
  async (departmentId, oldDepartmentId) => {
    if (!dialogVisible.value || departmentId === oldDepartmentId) {
      return;
    }
    if (!needGroup.value) {
      formGroups.value = [];
      return;
    }
    await fetchGroupsForForm(departmentId);
  },
);

onMounted(async () => {
  await fetchCommonData();
  await fetchData();

  if (canManageUsers.value && route.query.action === 'create') {
    await openCreateDialog();
    if (route.query.hospitalId) {
      form.hospitalId = Number(route.query.hospitalId);
      await fetchDepartmentsForForm(form.hospitalId);
    }
    if (route.query.departmentId) {
      form.departmentId = Number(route.query.departmentId);
      await fetchGroupsForForm(form.departmentId);
    }
  }
});

const canDeleteUser = (row) => {
  if (!canManageUsers.value) {
    return false;
  }

  if (userStore.role === 'SYSTEM_ADMIN') {
    return true;
  }

  return row.role !== 'SYSTEM_ADMIN' && row.role !== 'HOSPITAL_ADMIN';
};

const canViewPatientRecords = (row) => {
  return (
    (isDirector.value && ['DOCTOR', 'LEADER'].includes(row.role)) ||
    (isLeader.value && row.role === 'DOCTOR')
  );
};
</script>

<style scoped>
.users-container {
  padding: 0;
}

.header-actions {
  margin-bottom: 20px;
}

.pagination-container {
  margin-top: 20px;
  display: flex;
  justify-content: flex-end;
}
</style>
