<script setup lang="ts">
import { computed, nextTick, ref, watch } from 'vue';
import { useResizeObserver } from '@vueuse/core';
import dayjs from 'dayjs';
import { fetchSubmitProductRequirementReview } from '@/service/api';
import { useAuthStore } from '@/store/modules/auth';
import { useForm, useFormRules } from '@/hooks/common/form';
import BusinessAttachmentUploader from '@/components/custom/business-attachment-uploader.vue';
import BusinessFormDialog from '@/components/custom/business-form-dialog.vue';
import BusinessFormSection from '@/components/custom/business-form-section.vue';
import BusinessRichTextEditor from '@/components/custom/business-rich-text-editor.vue';
import ReadonlyField from '@/components/custom/readonly-field.vue';
import AttendeeUserPicker from '@/components/custom/attendee-user-picker.vue';

defineOptions({ name: 'RequirementReviewDialog' });

interface Props {
  productId: string;
  requirement: Api.Product.Requirement | null;
  memberOptions: Api.Product.ProductMember[];
}

const props = defineProps<Props>();

interface Emits {
  (e: 'submitted'): void;
}

const emit = defineEmits<Emits>();

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

const authStore = useAuthStore();
const { formRef, validate } = useForm();
const { createRequiredRule } = useFormRules();

const attachmentUploaderRef = ref<InstanceType<typeof BusinessAttachmentUploader> | null>(null);
const richTextEditorRef = ref<InstanceType<typeof BusinessRichTextEditor> | null>(null);

interface Model {
  conclusion: Api.Product.RequirementReviewConclusion;
  attendees: Api.Product.RequirementReviewAttendeeItem[];
  requirementEstimatedHours: number | null;
  reviewTime: string | null;
  reviewContent: string | null;
  attachments: Api.Project.AttachmentItem[];
}

const model = ref<Model>(createDefaultModel());
const submitting = ref(false);

const memberUserOptions = computed(() => props.memberOptions.filter(item => item.status === 0));

const reviewConclusionOptions = [
  { label: '通过评审', value: 0 as Api.Product.RequirementReviewConclusion },
  { label: '不通过评审', value: 1 as Api.Product.RequirementReviewConclusion }
];

const rules = {
  conclusion: [createRequiredRule('请选择评审结论')],
  attendees: [createRequiredRule('请选择参会人')]
} satisfies Record<string, App.Global.FormRule[]>;

const leftColRef = ref<HTMLElement>();
const editorHeight = ref<string>('45vh');

const ATTACHMENT_SECTION_RESERVE_PX = 140;

useResizeObserver(leftColRef, entries => {
  const height = entries[0]?.contentRect.height;

  if (height && height > 120) {
    editorHeight.value = `${Math.max(height - 60 - ATTACHMENT_SECTION_RESERVE_PX, 200)}px`;
  }
});

function createDefaultModel(): Model {
  return {
    conclusion: 0,
    attendees: [],
    requirementEstimatedHours: null,
    reviewTime: dayjs().format('YYYY-MM-DD'),
    reviewContent: null,
    attachments: []
  };
}

function isEmptyRichText(html: string | null | undefined) {
  if (!html) {
    return true;
  }

  const text = html
    .replace(/<[^>]+>/g, '')
    .replace(/&nbsp;/g, '')
    .trim();

  if (text) {
    return false;
  }

  return !/<img\b/i.test(html);
}

async function handleSubmit() {
  await validate();

  if (!props.productId || !props.requirement?.id) {
    return;
  }

  if (!authStore.userInfo.userId) {
    window.$message?.warning('未获取到当前登录用户信息');
    return;
  }

  if (attachmentUploaderRef.value?.hasUploading) {
    window.$message?.warning('附件正在上传中，请稍候');
    return;
  }

  const payload: Api.Product.RequirementReviewSubmitParams = {
    productId: props.productId,
    requirementId: props.requirement.id,
    operatorId: authStore.userInfo.userId,
    conclusion: model.value.conclusion,
    reviewContent: isEmptyRichText(model.value.reviewContent) ? null : (model.value.reviewContent ?? null),
    requirementEstimatedHours: model.value.requirementEstimatedHours,
    attendees: [...model.value.attendees],
    attachments: [...model.value.attachments],
    reviewTime: model.value.reviewTime
  };

  submitting.value = true;

  const result = await fetchSubmitProductRequirementReview(payload);

  submitting.value = false;

  if (result.error) {
    return;
  }

  await Promise.all([attachmentUploaderRef.value?.commit(), richTextEditorRef.value?.commit()]);

  window.$message?.success('评审提交成功');
  visible.value = false;
  emit('submitted');
}

watch(
  () => visible.value,
  async value => {
    if (!value) {
      return;
    }

    model.value = createDefaultModel();

    await nextTick();
    attachmentUploaderRef.value?.initSession();
    richTextEditorRef.value?.initSession();
    formRef.value?.clearValidate();
  }
);
</script>

<template>
  <BusinessFormDialog
    v-model="visible"
    title="评审需求"
    width="1100px"
    max-body-height="78vh"
    :confirm-loading="submitting"
    @confirm="handleSubmit"
  >
    <ElForm ref="formRef" :model="model" :rules="rules" label-position="top" :validate-on-rule-change="false">
      <div class="requirement-review-dialog__grid">
        <div ref="leftColRef" class="requirement-review-dialog__col-left">
          <BusinessFormSection title="评审信息">
            <ElFormItem label="需求名称">
              <ReadonlyField :value="requirement?.title || '--'" />
              <!-- <ElInput :model-value="requirement?.title || ''" readonly placeholder="&#45;&#45;" />-->
            </ElFormItem>

            <ElFormItem label="评审结论" prop="conclusion">
              <ElRadioGroup v-model="model.conclusion">
                <ElRadio
                  v-for="item in reviewConclusionOptions"
                  :key="item.value"
                  :value="item.value"
                  border
                  style="width: 165px"
                >
                  {{ item.label }}
                </ElRadio>
              </ElRadioGroup>
            </ElFormItem>

            <ElFormItem label="参会人" prop="attendees">
              <AttendeeUserPicker
                v-model="model.attendees"
                :team-options="memberUserOptions"
                team-tab-label="产品团队"
                :show-dept-tab="true"
              />
            </ElFormItem>

            <ElFormItem label="需求预估工时">
              <ElInputNumber
                v-model="model.requirementEstimatedHours"
                class="w-full"
                :min="0"
                :step="0.5"
                :precision="1"
                placeholder="请输入需求预估工时"
              />
            </ElFormItem>

            <ElFormItem label="实际评审日期">
              <ElDatePicker
                v-model="model.reviewTime"
                type="date"
                value-format="YYYY-MM-DD"
                placeholder="请选择实际评审日期"
                class="requirement-review-dialog__date-picker"
              />
            </ElFormItem>
          </BusinessFormSection>
        </div>

        <div class="requirement-review-dialog__col-right">
          <BusinessFormSection title="评审内容">
            <ElFormItem class="requirement-review-dialog__desc-item">
              <BusinessRichTextEditor
                ref="richTextEditorRef"
                v-model="model.reviewContent"
                :height="editorHeight"
                upload-directory="requirement-review"
                placeholder="请输入评审内容"
              />
            </ElFormItem>
          </BusinessFormSection>

          <BusinessFormSection title="会议资料">
            <ElFormItem class="requirement-review-dialog__attachment-item">
              <BusinessAttachmentUploader
                ref="attachmentUploaderRef"
                v-model="model.attachments"
                directory="requirement-review"
              />
            </ElFormItem>
          </BusinessFormSection>
        </div>
      </div>
    </ElForm>
  </BusinessFormDialog>
</template>

<style scoped>
.requirement-review-dialog__grid {
  display: grid;
  grid-template-columns: 360px 1fr;
  gap: 24px;
  align-items: start;
}

.requirement-review-dialog__col-left,
.requirement-review-dialog__col-right {
  min-width: 0;
}

.requirement-review-dialog__col-right {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.requirement-review-dialog__desc-item,
.requirement-review-dialog__attachment-item {
  margin-bottom: 0;
}

@media (width <= 1024px) {
  .requirement-review-dialog__grid {
    grid-template-columns: 1fr;
  }
}

:deep(.requirement-review-dialog__date-picker.el-date-editor.el-input) {
  width: 100%;
}
</style>
