<script setup lang="ts">
import { computed, nextTick, ref, watch } from 'vue';
import { PRODUCT_MANAGER_ROLE_CODE } from '@/constants/business';
import { RDMS_OBJECT_DIRECTION_DICT_CODE } from '@/constants/dict';
import { fetchCreateProductWithTeam, fetchGetProduct, fetchGetRoleSimpleList, fetchUpdateProduct } from '@/service/api';
import { useForm, useFormRules } from '@/hooks/common/form';
import BusinessFormDialog from '@/components/custom/business-form-dialog.vue';
import DictSelect from '@/components/custom/dict-select.vue';
import ProductCreateBaseForm, {
  type ProductCreateBaseForm as ProductCreateBaseFormModel
} from './product-create-base-form.vue';
import ProductCreateTeamStep from './product-create-team-step.vue';

defineOptions({ name: 'ProductOperateDialog' });

interface Props {
  managerUserOptions: Api.SystemManage.UserSimple[];
  rowData?: Api.Product.Product | null;
}

const props = defineProps<Props>();

interface Emits {
  (e: 'submitted', productId?: string): void;
}

const emit = defineEmits<Emits>();

const visible = defineModel<boolean>('visible', { default: false });

// === 编辑模式（单步） ===
interface EditModel {
  code: string;
  directionCode: string;
  name: string;
  managerUserId: string | null;
  description: string;
}

const { formRef: editFormRef, validate: editValidate } = useForm();
const { createRequiredRule } = useFormRules();

const editModel = ref<EditModel>(createEditModel());
const editLoading = ref(false);
const submitting = ref(false);

const isEditMode = computed(() => Boolean(props.rowData?.id));
const dialogTitle = computed(() => (isEditMode.value ? '编辑产品' : '新增产品'));

const editRules = {
  directionCode: [createRequiredRule('请选择产品方向')],
  name: [createRequiredRule('请输入产品名称')],
  managerUserId: [createRequiredRule('请选择产品经理')]
} satisfies Record<string, App.Global.FormRule[]>;

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

const managerDisplayName = computed(() => {
  const managerUserId = editModel.value.managerUserId;

  if (!managerUserId) {
    return '';
  }

  return managerLabelMap.value.get(String(managerUserId)) || String(managerUserId);
});

function createEditModel(): EditModel {
  return { code: '', directionCode: '', name: '', managerUserId: null, description: '' };
}

function getNullableText(value?: string | null) {
  return value?.trim() || null;
}

function closeDialog() {
  visible.value = false;
}

async function handleEditSubmit() {
  await editValidate();

  const managerUserId = editModel.value.managerUserId;

  if (!managerUserId || !props.rowData?.id) {
    return;
  }

  submitting.value = true;

  const { error } = await fetchUpdateProduct({
    id: props.rowData.id,
    code: getNullableText(editModel.value.code),
    directionCode: editModel.value.directionCode,
    name: editModel.value.name.trim(),
    managerUserId,
    description: getNullableText(editModel.value.description)
  });

  submitting.value = false;

  if (error) {
    return;
  }

  window.$message?.success('产品编辑成功');
  closeDialog();
  emit('submitted', props.rowData.id);
}

// === 新增模式（两步向导） ===
const baseFormRef = ref<InstanceType<typeof ProductCreateBaseForm> | null>(null);
const teamStepRef = ref<InstanceType<typeof ProductCreateTeamStep> | null>(null);
const currentStep = ref<1 | 2>(1);

// === 新增模式:角色列表(父级加载,下发给 team-step 与批量弹层) ===
const roleOptions = ref<Api.SystemManage.RoleSimple[]>([]);
const roleLoading = ref(false);
const managerRoleError = ref('');

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

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

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

  roleLoading.value = false;
  roleOptions.value = data ?? [];

  if (!managerRole.value) {
    managerRoleError.value = '未找到产品经理角色,请联系管理员';
  }
}

const createBaseModel = ref<ProductCreateBaseFormModel>(createBaseInfo());
const draftMembers = ref<Api.Product.CreateProductMemberParams[]>([]);

function createBaseInfo(): ProductCreateBaseFormModel {
  return { code: '', name: '', directionCode: '', managerUserId: null, description: '' };
}

async function goNext() {
  const valid = await baseFormRef.value?.validate();

  if (!valid) {
    return;
  }

  currentStep.value = 2;
}

function goPrev() {
  currentStep.value = 1;
}

async function handleCreateSubmit() {
  const baseValid = await baseFormRef.value?.validate();

  if (!baseValid) {
    currentStep.value = 1;
    return;
  }

  const teamValid = await teamStepRef.value?.validate();

  if (!teamValid) {
    return;
  }

  submitting.value = true;

  const payload: Api.Product.CreateProductWithTeamParams = {
    product: {
      code: getNullableText(createBaseModel.value.code),
      name: createBaseModel.value.name.trim(),
      directionCode: createBaseModel.value.directionCode,
      managerUserId: createBaseModel.value.managerUserId as string,
      description: getNullableText(createBaseModel.value.description)
    },
    members: draftMembers.value
  };

  const { error, data } = await fetchCreateProductWithTeam(payload);

  submitting.value = false;

  if (error) {
    return;
  }

  window.$message?.success('产品新增成功');
  closeDialog();
  emit('submitted', data);
}

// === 公共：弹框可见性变化时重置 / 加载数据 ===
watch(visible, async value => {
  if (!value) {
    return;
  }

  submitting.value = false;
  currentStep.value = 1;

  if (!isEditMode.value || !props.rowData?.id) {
    editModel.value = createEditModel();
    createBaseModel.value = createBaseInfo();
    draftMembers.value = [];
    await nextTick();
    await loadRoles();
    editFormRef.value?.clearValidate();
    return;
  }

  editLoading.value = true;

  const { error, data } = await fetchGetProduct(props.rowData.id);

  editLoading.value = false;

  if (error || !data) {
    return;
  }

  editModel.value = {
    code: data.code || '',
    directionCode: data.directionCode || '',
    name: data.name || '',
    managerUserId: data.managerUserId || null,
    description: data.description || ''
  };

  await nextTick();
  editFormRef.value?.clearValidate();
});
</script>

<template>
  <!-- 编辑模式：单步表单（与改造前一致） -->
  <BusinessFormDialog
    v-if="isEditMode"
    v-model="visible"
    :title="dialogTitle"
    preset="sm"
    :loading="editLoading"
    :confirm-loading="submitting"
    @confirm="handleEditSubmit"
  >
    <ElForm ref="editFormRef" :model="editModel" :rules="editRules" label-position="top">
      <ElRow :gutter="16">
        <ElCol :span="24">
          <ElFormItem label="产品编码" prop="code">
            <ElInput
              :model-value="editModel.code"
              readonly
              class="product-operate-dialog__readonly-input"
              placeholder="未获取到产品编码"
            />
          </ElFormItem>
        </ElCol>
        <ElCol :span="24">
          <ElFormItem label="产品名称" prop="name">
            <ElInput v-model="editModel.name" clearable maxlength="128" placeholder="请输入产品名称" />
          </ElFormItem>
        </ElCol>
        <ElCol :span="24">
          <ElFormItem label="产品方向" prop="directionCode">
            <DictSelect
              v-model="editModel.directionCode"
              :dict-code="RDMS_OBJECT_DIRECTION_DICT_CODE"
              filterable
              placeholder="请选择产品方向"
            />
          </ElFormItem>
        </ElCol>
        <ElCol :span="24">
          <ElFormItem>
            <template #label>
              <span class="business-form-label-with-tip">
                <ElTooltip
                  content="如需调整产品经理，请到产品内的团队管理处处理。"
                  popper-class="business-form-label-tooltip"
                  placement="top-start"
                >
                  <span class="business-form-label-tip">
                    <icon-fe:question />
                  </span>
                </ElTooltip>
                <span>产品经理</span>
              </span>
            </template>
            <ElInput
              :model-value="managerDisplayName"
              readonly
              class="product-operate-dialog__readonly-input"
              placeholder="未配置产品经理"
            />
          </ElFormItem>
        </ElCol>
        <ElCol :span="24">
          <ElFormItem label="产品描述" prop="description">
            <ElInput
              v-model="editModel.description"
              type="textarea"
              :rows="4"
              maxlength="500"
              show-word-limit
              placeholder="请输入产品描述"
            />
          </ElFormItem>
        </ElCol>
      </ElRow>
    </ElForm>
  </BusinessFormDialog>

  <!-- 新增模式:两步向导(复合内容特例,1080px,左侧概念区 + 右侧步骤面板) -->
  <ElDialog
    v-else
    v-model="visible"
    class="product-create-dialog"
    :title="dialogTitle"
    :close-on-click-modal="false"
    destroy-on-close
    align-center
    width="1080px"
  >
    <div class="product-create-dialog__split">
      <aside class="product-create-dialog__guide">
        <div class="product-create-dialog__guide-hero">
          <div class="product-create-dialog__guide-hero-icon">
            <icon-ep:box />
          </div>
          <div class="product-create-dialog__guide-hero-text">
            <div class="product-create-dialog__guide-hero-title">产品</div>
            <div class="product-create-dialog__guide-hero-sub">需求 · 项目 · 迭代 的承载单元</div>
          </div>
        </div>

        <p class="product-create-dialog__guide-lead">
          产品与需求池管理,提供多维度的需求规划工具,打通客户、业务团队和产研团队之间的协作。
        </p>

        <section class="product-create-dialog__guide-section">
          <h4>包含</h4>
          <p>需求、变更、迭代、模块、文档、状态、统计报表。</p>
        </section>

        <section class="product-create-dialog__guide-section">
          <h4>参与人</h4>
          <p>产品经理(必填,创建后锁定) · 团队角色(业务专员 / 游客 / 关注人)。</p>
        </section>

        <section class="product-create-dialog__guide-section">
          <h4>命名建议</h4>
          <p>建议使用业务团队约定俗成的简短名称,产品创建后不再轻易调整,会影响下游引用。</p>
        </section>
      </aside>

      <div class="product-create-dialog__main">
        <div class="product-create-dialog__stepbar">
          <div
            class="product-create-dialog__step"
            :class="{ 'is-active': currentStep === 1, 'is-done': currentStep > 1 }"
          >
            <span class="product-create-dialog__step-index">1</span>
            <span class="product-create-dialog__step-text">
              <strong>基础资料</strong>
            </span>
          </div>
          <div class="product-create-dialog__step" :class="{ 'is-active': currentStep === 2 }">
            <span class="product-create-dialog__step-index">2</span>
            <span class="product-create-dialog__step-text">
              <strong>初始化团队</strong>
            </span>
          </div>
        </div>

        <div class="product-create-dialog__body">
          <div v-show="currentStep === 1" class="product-create-dialog__panel">
            <ProductCreateBaseForm
              ref="baseFormRef"
              v-model="createBaseModel"
              :manager-user-options="managerUserOptions"
            />
          </div>
          <div v-show="currentStep === 2" class="product-create-dialog__panel">
            <ProductCreateTeamStep
              ref="teamStepRef"
              :base-info="createBaseModel"
              :user-options="managerUserOptions"
              :role-options="roleOptions"
              :role-loading="roleLoading"
              :manager-role-error="managerRoleError"
              @update:members="draftMembers = $event"
            />
          </div>
        </div>
      </div>
    </div>

    <template #footer>
      <div class="product-create-dialog__footer">
        <span class="product-create-dialog__footer-meta">第 {{ currentStep }} 步,共 2 步</span>
        <ElSpace :size="10">
          <ElButton @click="closeDialog">取消</ElButton>
          <ElButton v-if="currentStep === 2" @click="goPrev">上一步</ElButton>
          <ElButton v-if="currentStep === 1" type="primary" @click="goNext">下一步</ElButton>
          <ElButton v-if="currentStep === 2" type="primary" :loading="submitting" @click="handleCreateSubmit">
            确定
          </ElButton>
        </ElSpace>
      </div>
    </template>
  </ElDialog>
</template>

<style scoped>
:deep(.product-operate-dialog__readonly-input .el-input__wrapper) {
  background: linear-gradient(180deg, rgb(241 245 249 / 98%), rgb(226 232 240 / 94%)), rgb(241 245 249);
  box-shadow: 0 0 0 1px rgb(203 213 225 / 96%) inset;
  cursor: default;
}

:deep(.product-operate-dialog__readonly-input .el-input__wrapper:hover),
:deep(.product-operate-dialog__readonly-input.is-focus .el-input__wrapper) {
  box-shadow: 0 0 0 1px rgb(203 213 225 / 96%) inset;
}

:deep(.product-operate-dialog__readonly-input .el-input__inner) {
  color: rgb(51 65 85 / 96%);
  cursor: default;
  -webkit-text-fill-color: rgb(51 65 85 / 96%);
}

.product-create-dialog :deep(.el-dialog__body) {
  display: flex;
  flex-direction: column;
  padding: 0;
}

.product-create-dialog__split {
  display: grid;
  grid-template-columns: 280px 1fr;
  min-height: 0;
}

.product-create-dialog__guide {
  padding: 28px 24px;
  background: linear-gradient(180deg, #f7f9fc 0%, #fafbfc 100%);
  border-right: 1px solid rgb(229 233 242 / 96%);
  overflow-y: auto;
  max-height: min(720px, calc(100vh - 160px));
}

.product-create-dialog__guide-hero {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 24px;
  padding-bottom: 20px;
  border-bottom: 1px solid rgb(229 233 242 / 96%);
}

.product-create-dialog__guide-hero-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border-radius: 10px;
  background: var(--el-color-primary-light-9);
  color: var(--el-color-primary);
  font-size: 22px;
  flex-shrink: 0;
}

.product-create-dialog__guide-hero-text {
  min-width: 0;
}

.product-create-dialog__guide-hero-title {
  font-size: 15px;
  font-weight: 650;
  color: var(--el-text-color-primary);
  line-height: 1.4;
}

.product-create-dialog__guide-hero-sub {
  margin-top: 2px;
  font-size: 12px;
  color: var(--el-text-color-secondary);
  line-height: 1.4;
}

.product-create-dialog__guide-lead {
  margin: 0 0 24px;
  font-size: 13.5px;
  line-height: 1.8;
  color: var(--el-text-color-regular);
}

.product-create-dialog__guide-section + .product-create-dialog__guide-section {
  margin-top: 20px;
}

.product-create-dialog__guide-section h4 {
  margin: 0 0 6px;
  font-size: 12.5px;
  font-weight: 700;
  color: var(--el-text-color-primary);
  letter-spacing: 0.4px;
}

.product-create-dialog__guide-section p {
  margin: 0;
  font-size: 13px;
  line-height: 1.75;
  color: var(--el-text-color-regular);
}

.product-create-dialog__main {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.product-create-dialog__stepbar {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  padding: 14px 24px;
  border-bottom: 1px solid rgb(229 233 242 / 96%);
  background: #fbfcfe;
}

.product-create-dialog__step {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
}

.product-create-dialog__step-index {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  width: 28px;
  height: 28px;
  border: 1px solid rgb(215 222 235 / 96%);
  border-radius: 999px;
  background: #fff;
  color: rgb(119 129 150 / 96%);
  font-size: 13px;
  font-weight: 650;
}

.product-create-dialog__step.is-active .product-create-dialog__step-index,
.product-create-dialog__step.is-done .product-create-dialog__step-index {
  border-color: var(--el-color-primary);
  background: var(--el-color-primary);
  color: #fff;
}

.product-create-dialog__step-text {
  min-width: 0;
}

.product-create-dialog__step-text strong {
  display: block;
  font-size: 14px;
  font-weight: 650;
}

.product-create-dialog__step-text small {
  display: block;
  margin-top: 2px;
  color: rgb(119 129 150 / 96%);
  font-size: 12px;
}

.product-create-dialog__body {
  height: min(520px, calc(100vh - 240px));
  overflow: hidden;
}

.product-create-dialog__panel {
  height: 100%;
  padding: 24px;
  overflow: auto;
  box-sizing: border-box;
}

.product-create-dialog__footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
}

.product-create-dialog__footer-meta {
  color: rgb(119 129 150 / 96%);
  font-size: 13px;
}
</style>
