<script setup lang="ts">
import { computed, onMounted, ref, watch } from 'vue';
import { PROJECT_MANAGER_ROLE_CODE } from '@/constants/business';
import { fetchGetRoleSimpleList } from '@/service/api';
import { getProjectTeamTableHeight } from '@/views/project/project/setting/shared';
import ProjectCreateTeamMemberDialog from './project-create-team-member-dialog.vue';
import type { ProjectCreateBaseForm } from './project-create-base-form.vue';

defineOptions({ name: 'ProjectCreateTeamStep' });

interface DraftMember {
  /** 客户端临时主键，仅用于 v-for 稳定 */
  key: string;
  userId: string;
  roleId: string;
  remark: string;
  /** true 表示由项目经理自动派生的锁定行 */
  locked: boolean;
}

interface Props {
  baseInfo: ProjectCreateBaseForm;
  userOptions: Api.SystemManage.UserSimple[];
}

const props = defineProps<Props>();

const emit = defineEmits<{
  (e: 'update:members', members: Api.Project.CreateProjectMemberParams[]): void;
}>();

const roleOptions = ref<Api.SystemManage.RoleSimple[]>([]);
const roleLoading = ref(false);
const managerRoleError = ref('');
const members = ref<DraftMember[]>([]);

const memberDialogVisible = ref(false);
const memberDialogMode = ref<'create' | 'edit'>('create');
const editingKey = ref<string | null>(null);

const teamTableHeight = getProjectTeamTableHeight(5);

const userLabelMap = computed(() => new Map(props.userOptions.map(item => [String(item.id), item.nickname])));

const managerRole = computed(() => roleOptions.value.find(item => item.code === PROJECT_MANAGER_ROLE_CODE) ?? null);

// 弹框传入的禁选用户列表：新增时排除所有已选；编辑时排除自身以外的已选
const dialogDisabledUserIds = computed(() => {
  return members.value
    .filter(item => !editingKey.value || item.key !== editingKey.value)
    .map(item => item.userId)
    .filter(Boolean);
});

const dialogInitial = computed(() => {
  if (memberDialogMode.value === 'create' || !editingKey.value) {
    return null;
  }

  const target = members.value.find(item => item.key === editingKey.value);

  if (!target) {
    return null;
  }

  return { userId: target.userId, roleId: target.roleId, remark: target.remark };
});

function getUserNickname(userId: string) {
  return userLabelMap.value.get(String(userId)) || userId;
}

function getRoleName(roleId: string) {
  return roleOptions.value.find(item => item.id === roleId)?.name || '--';
}

function generateKey() {
  return `${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
}

async function loadRoles() {
  roleLoading.value = true;
  managerRoleError.value = '';

  const { data } = await fetchGetRoleSimpleList({ scopeType: 'object', objectType: 'project' });

  roleLoading.value = false;

  roleOptions.value = data ?? [];

  if (!managerRole.value) {
    managerRoleError.value = '未找到项目经理角色，请联系管理员';
    return;
  }

  refreshManagerRow();
}

function refreshManagerRow() {
  const managerUserId = props.baseInfo.managerUserId;

  if (!managerUserId || !managerRole.value) {
    members.value = members.value.filter(item => !item.locked);
    emitMembers();
    return;
  }

  const lockedIndex = members.value.findIndex(item => item.locked);
  const lockedRow: DraftMember = {
    key: lockedIndex >= 0 ? members.value[lockedIndex].key : generateKey(),
    userId: managerUserId,
    roleId: managerRole.value.id,
    remark: lockedIndex >= 0 ? members.value[lockedIndex].remark : '',
    locked: true
  };

  if (lockedIndex >= 0) {
    members.value[lockedIndex] = lockedRow;
  } else {
    members.value = [lockedRow, ...members.value];
  }

  emitMembers();
}

function openCreate() {
  memberDialogMode.value = 'create';
  editingKey.value = null;
  memberDialogVisible.value = true;
}

function openEdit(row: DraftMember) {
  memberDialogMode.value = 'edit';
  editingKey.value = row.key;
  memberDialogVisible.value = true;
}

function removeMember(key: string) {
  members.value = members.value.filter(item => item.key !== key);
  emitMembers();
}

function handleMemberSubmit(payload: { userId: string; roleId: string; remark: string }) {
  if (memberDialogMode.value === 'create') {
    members.value.push({
      key: generateKey(),
      userId: payload.userId,
      roleId: payload.roleId,
      remark: payload.remark,
      locked: false
    });
  } else if (editingKey.value) {
    const idx = members.value.findIndex(item => item.key === editingKey.value);

    if (idx >= 0) {
      members.value[idx] = {
        ...members.value[idx],
        roleId: payload.roleId,
        remark: payload.remark
      };
    }
  }

  memberDialogVisible.value = false;
  emitMembers();
}

function emitMembers() {
  emit(
    'update:members',
    members.value.map(item => ({
      userId: item.userId,
      roleId: item.roleId,
      remark: item.remark.trim() || null,
      previousManagerUserId: null,
      previousManagerRoleId: null
    }))
  );
}

async function runValidate(): Promise<boolean> {
  if (managerRoleError.value) {
    window.$message?.error(managerRoleError.value);
    return false;
  }

  for (const item of members.value) {
    if (!item.userId || !item.roleId) {
      window.$message?.error('请补全所有成员的用户和角色');
      return false;
    }
  }

  const userIdSet = new Set<string>();

  for (const item of members.value) {
    if (userIdSet.has(item.userId)) {
      window.$message?.error(`成员「${getUserNickname(item.userId)}」重复，请检查`);
      return false;
    }

    userIdSet.add(item.userId);
  }

  return true;
}

onMounted(loadRoles);

watch(
  () => props.baseInfo.managerUserId,
  () => {
    if (!managerRoleError.value && managerRole.value) {
      refreshManagerRow();
    }
  }
);

defineExpose({ validate: runValidate });
</script>

<template>
  <div v-loading="roleLoading" class="team-step">
    <div class="team-step__toolbar">
      <ElButton type="primary" plain :disabled="Boolean(managerRoleError)" @click="openCreate">新增成员</ElButton>
    </div>

    <ElAlert
      v-if="managerRoleError"
      :title="managerRoleError"
      type="error"
      :closable="false"
      show-icon
      class="team-step__alert"
    />

    <ElTable :data="members" :height="teamTableHeight" border row-key="key" empty-text="点击右上角“新增成员”添加">
      <ElTableColumn type="index" label="序号" width="64" align="center" />
      <ElTableColumn label="成员姓名" min-width="120">
        <template #default="{ row }">
          {{ getUserNickname(row.userId) }}
        </template>
      </ElTableColumn>
      <ElTableColumn label="当前角色" min-width="140">
        <template #default="{ row }">
          {{ getRoleName(row.roleId) }}
        </template>
      </ElTableColumn>
      <ElTableColumn label="备注" min-width="200" show-overflow-tooltip>
        <template #default="{ row }">
          {{ row.remark || '--' }}
        </template>
      </ElTableColumn>
      <ElTableColumn label="操作" width="150" fixed="right" align="center">
        <template #default="{ row }">
          <div class="team-step__actions">
            <ElButton link type="primary" :disabled="row.locked" @click="openEdit(row)">编辑</ElButton>
            <ElButton link type="danger" :disabled="row.locked" @click="removeMember(row.key)">移除</ElButton>
          </div>
        </template>
      </ElTableColumn>
    </ElTable>

    <ProjectCreateTeamMemberDialog
      v-model:visible="memberDialogVisible"
      :mode="memberDialogMode"
      :initial="dialogInitial"
      :user-options="userOptions"
      :role-options="roleOptions"
      :disabled-user-ids="dialogDisabledUserIds"
      @submit="handleMemberSubmit"
    />
  </div>
</template>

<style scoped>
.team-step {
  display: flex;
  flex-direction: column;
  gap: 14px;
  min-height: 0;
}

.team-step__toolbar {
  display: flex;
  justify-content: flex-end;
}

.team-step__alert {
  margin: 0;
}

.team-step__actions {
  display: inline-flex;
  align-items: center;
  gap: 12px;
}
</style>
