<script setup lang="ts">
import { ref, reactive, onMounted, onUnmounted, computed, nextTick } from 'vue';
import { PlusOutlined } from '@ant-design/icons-vue';
import type { FormInstance } from 'ant-design-vue';
import type { UploadFile } from 'ant-design-vue/es/upload/interface';
import type { EducationModel } from '@/model/education.model';
import { getEducationDetailMethod, editEducationMethod } from '@/request/api/education.api';
import { searchTagsFromSelectableMethod } from '@/request/api/patient.api';
import { VxeUI } from 'vxe-pc-ui';
import { useRequest } from 'alova/client';
import { notification } from 'ant-design-vue';
import type { EditorProps } from '@/pages/editor';
import { Editor, EditorPreview } from '@/pages/editor';
import upload from '@/request/upload';

import { UploadIFile } from '@/request/api/follow.api';
import { list2Groups } from '@/tools/data';

const instance = useTemplateRef('editor');
const config = ref<EditorProps>({
  previewable: false,
  uploadPicture: {
    accept: 'image/*',
    handle: (file) => upload(file, true),
  },
  uploadVideo: {
    accept: 'video/*',
    handle: (file) => upload(file, true),
  },
});

const props = defineProps<{
  data?: EducationModel;
}>();

const emits = defineEmits<{
  submit: [data?: EducationModel];
  back: [];
}>();
// 获取用户标签
const { data: selectable, loading: tagsLoading } = useRequest(searchTagsFromSelectableMethod, { initialData: [] });
// 用户标签选项（分组）
const tagOptions = computed(() =>
  list2Groups(
    selectable.value.filter((tag: any) => !tag.disabled),
    'category',
    (key) => ({ 1: '系统标签', 2: '个人标签' })[key]!
  )
);
// 更新宣教
const { loading: updating, send: submitUpdate } = useRequest(editEducationMethod, { immediate: false });
const formRef = ref<FormInstance>();
const loading = ref<boolean>(false);
const formContentRef = ref<HTMLElement>();
const headerActionsRef = ref<HTMLElement>();
const offsetTop = ref<number>(0);

// 表单数据
const form = reactive<EducationModel>({
  id: '',
  title: '',
  briefImg: '',
  tagIds: [],
  content: '',
  createBy: '',
  createTime: '',
  status: '0',
  pushType: '0',
  isSwitch: true,
  tagNameStr: '',
  tagNames: [],
});

// 推送形式选项
const pushMethodOptions = [
  { label: '自动推送', value: '0' },
  { label: '仅通过通知管理推送', value: '1' },
];
// 图片上传相关
const imageFileList = ref<UploadFile[]>([]);
const uploadProps = reactive({ showRemoveIcon: true });
const previewVisible = ref(false);
const previewImage = ref('');

// 图片上传
const customUpload = (e: any) => {
  UploadIFile(e.file)
    .then((res: any) => {
      form.briefImg = res.url || res.data?.url || '';
      e.onSuccess(res, e);
    })
    .catch((err) => {
      e.onError(err);
    });
};

// 预览图片
const handleImagePreview = async (file: UploadFile) => {
  previewImage.value = file.response?.url ?? file.thumbUrl ?? '';
  previewVisible.value = true;
};

// 图片删除
const handleRemove = () => {
  form.briefImg = '';
  imageFileList.value = [];
};

// 检查富文本内容是否为空（去除 HTML 标签后检查文本内容）
const isContentEmpty = (html: string): boolean => {
  if (!html) return true;
  const tempDiv = document.createElement('div');
  tempDiv.innerHTML = html;
  const textContent = tempDiv.textContent || tempDiv.innerText || '';
  return textContent.trim().length === 0;
};

// 表单验证规则
const rules: any = {
  title: [{ required: true, message: '请输入标题', trigger: 'blur' }],
  status: [{ required: true, message: '请选择启用状态', trigger: 'change' }],
  pushType: [{ required: true, message: '请选择推送形式', trigger: 'change' }],
  briefImg: [{ required: true, message: '请上传文章主图', trigger: 'change' }],
  content: [
    {
      validator: (_rule: any, value: string) => {
        if (isContentEmpty(value)) {
          return Promise.reject(new Error('请填写宣教内容'));
        }
        return Promise.resolve();
      },
      trigger: 'blur',
    },
  ],
};
// 保存
const handleSave = async () => {
  try {
    // 保存前同步编辑器内容到表单数据
    const value = instance.value?.save();
    if (value) {
      form.content = encodeURIComponent(value?.html);
    }
    await formRef.value?.validateFields(['content']);
    // 验证所有字段
    await formRef.value?.validate();
    updating.value = true;
    const tagNames = form.tagIds.map((id: string) => selectable.value.find((option: any) => option.id === id)?.name || '') as any[];
    // 在提交前，先将其值同步到 status 字段
    const status = form.isSwitch ? '0' : '1';
    // 创建提交数据，排除不需要的字段，但保留原 form 对象不变
    const submitData = { ...form };
    submitData.status = status;
    delete submitData.patientMatchRule && delete submitData.isSwitch;
    console.log(submitData, 'submitData===submitData');
    submitUpdate({
      ...submitData,
      tagNameStr: tagNames.join(',') || '',
      tagNames: tagNames,
    }).then(() => {
      // 保存成功后，同步更新 form 的 status，保持 isSwitch 不变
      form.status = status;
      notification.success({
        message: '保存成功',
      });
      emits('submit', { ...form });
    });
  } catch (error) {
    console.error('表单验证失败', error);
  } finally {
    loading.value = false;
  }
};

// 返回
const handleBack = () => {
  emits('back');
  VxeUI.modal.close(`education-modal`);
};
// 获取宣教详情
const getEducationDetail = async (id?: string) => {
  const res: any = await getEducationDetailMethod(id || '');
  if (res) {
    Object.assign(form, res);
    form.isSwitch = form.status === '0' ? true : false;
    if (form.briefImg) {
      imageFileList.value = [
        {
          uid: '-1',
          name: 'image.png',
          status: 'done',
          url: form.briefImg,
        } as UploadFile,
      ];
    }
    // 如果有内容，设置编辑器内容
    if (form.content) {
      form.content = decodeURIComponent(form.content);
    }
    // 如果标签为空，则清空标签
    if (!form.tagIds || form.tagIds.length === 0) {
      form.tagIds = [];
      form.tagNames = [];
      form.tagNameStr = '';
    }
  }
};

// 获取滚动容器（用于 a-affix 的 target）
const getScrollTarget = (): HTMLElement | Window => {
  return formContentRef.value || window;
};

// 计算 offset-top 高度（按钮区域的底部位置）
const calculateOffsetTop = () => {
  if (!headerActionsRef.value || !formContentRef.value) return;
  const headerActions = (headerActionsRef.value as any)?.$el || headerActionsRef.value;
  if (!headerActions) return;

  // 获取滚动容器的位置
  const containerRect = formContentRef.value.getBoundingClientRect();
  // 获取按钮区域的位置
  const headerRect = headerActions.getBoundingClientRect();

  // offset-top 应该是按钮区域底部距离滚动容器顶部的距离
  offsetTop.value = headerRect.bottom - containerRect.top;
};

onMounted(() => {
  if (props.data && props.data.id) {
    getEducationDetail(props.data.id);
  }

  // 等待 DOM 渲染完成后计算 offset-top
  nextTick(() => {
    calculateOffsetTop();
    // 监听窗口大小变化，重新计算 offset-top
    window.addEventListener('resize', calculateOffsetTop);
  });
});

onUnmounted(() => {
  // 清理事件监听
  window.removeEventListener('resize', calculateOffsetTop);
});
</script>

<template>
  <div class="education-form-container">
    <!-- 表单内容 -->
    <div class="form-content" ref="formContentRef">
      <!-- 顶部按钮 -->
      <div class="header-actions" ref="headerActionsRef">
        <editor-preview v-if="!config.previewable" :content="form.content">
          <template #default="{ toggle }">
            <a-button @click="toggle()">预览</a-button>
          </template>
          <template #preview-header></template>
          <template #preview-content></template>
          <template #preview-footer></template>
        </editor-preview>
        <vxe-button type="primary" content="返回" @click="handleBack"></vxe-button>
        <vxe-button type="submit" status="primary" content="保存" @click="handleSave" :loading="updating"></vxe-button>
      </div>
      <a-form ref="formRef" :model="form" :rules="rules" layout="horizontal" :label-col="{ span: 4 }" :wrapper-col="{ span: 20 }">
        <div class="form-row">
          <!-- 标题 -->
          <a-form-item label="标题" name="title" required class="form-row-item">
            <a-input v-model:value="form.title" placeholder="请输入" />
          </a-form-item>

          <!-- 启用状态 -->
          <a-form-item label="启用" name="status" required class="form-row-item">
            <a-switch v-model:checked="form.isSwitch" />
          </a-form-item>
        </div>
        <!-- 推送形式 -->
        <a-form-item label="推送形式" name="pushType" required class="form-row-item">
          <a-radio-group v-model:value="form.pushType">
            <a-radio v-for="option in pushMethodOptions" :key="option.value" :value="option.value">
              {{ option.label }}
            </a-radio>
          </a-radio-group>
        </a-form-item>

        <!-- 用户标签 -->
        <a-form-item label="用户标签" name="tagIds" class="form-row-item">
          <vxe-select
            v-model="form.tagIds"
            :options="tagOptions"
            placeholder="请选择"
            style="width: 100%"
            multiple
            filterable
            clearable
            :optionProps="{ value: 'id', label: 'name' }"
            :optionGroupProps="{ options: 'groups' }"
          />
        </a-form-item>

        <!-- 文章主图 -->
        <a-form-item label="文章主图" name="briefImg" required class="form-row-item">
          <a-upload
            :show-upload-list="uploadProps"
            v-model:file-list="imageFileList"
            list-type="picture-card"
            @preview="handleImagePreview"
            @remove="handleRemove"
            :max-count="1"
            :custom-request="customUpload"
            accept="image/*"
          >
            <div v-if="imageFileList.length < 1">
              <PlusOutlined />
              <div style="margin-top: 8px">上传</div>
            </div>
          </a-upload>
        </a-form-item>

        <!-- 宣教内容 -->
        <a-affix :target="getScrollTarget" :offset-top="offsetTop" :z-index="10">
          <a-form-item label="宣教内容" name="content" required class="form-row-item">
            <div class="flex flex-col" style="height: 600px">
              <editor ref="editor" class="flex-auto" v-bind="config" v-model:content="form.content">
                <template #preview-header>test:header</template>
                <template #preview-footer>test:footer</template>
              </editor>
            </div>
          </a-form-item>
        </a-affix>
      </a-form>

      <!-- 图片预览 -->
      <a-modal v-model:open="previewVisible" :footer="null" centered>
        <img alt="preview" style="width: 100%" :src="previewImage" />
      </a-modal>
    </div>
  </div>
</template>

<style scoped lang="scss">
.education-form-container {
  padding: 24px;
  background: #fff;
  height: 100%;
  display: flex;
  flex-direction: column;
}

.header-actions {
  position: sticky;
  top: 0;
  z-index: 20;
  background: #fff;
  display: flex;
  justify-content: flex-end;
  gap: 12px;
  margin-bottom: 24px;
  padding-bottom: 16px;
  border-bottom: 1px solid #f0f0f0;
}

.form-content {
  flex: 1;
  overflow: auto;
  position: relative;
}

.form-row {
  display: flex;
  gap: 16px;
  align-items: flex-start;
  // margin-bottom: 24px;
}

.form-row-item {
  flex: 1;
  margin-bottom: 0;
}

.form-row-item :deep(.ant-form-item) {
  margin-bottom: 0;
  display: flex;
  flex-direction: column;
}

.form-row-item :deep(.ant-form-item-label) {
  flex: 0 0 auto;
  width: auto;
  min-width: 80px;
  text-align: left;
  padding-right: 8px;
  padding-bottom: 0;
}

.form-row-item :deep(.ant-form-item-control) {
  flex: 1;
  width: 100%;
}

:deep(.ant-form-item-label > label.ant-form-item-required:not(.ant-form-item-required-mark-optional)) {
  &::before {
    display: inline-block;
    margin-right: 4px;
    color: #ff4d4f;
    font-size: 14px;
    font-family: SimSun, sans-serif;
    line-height: 1;
    content: '*';
  }
}

:deep(.ant-form-item) {
  margin-bottom: 24px;
}

:deep(.ant-input),
:deep(.ant-select-selector) {
  border-color: #d9d9d9;
}

:deep(.ant-radio-group) {
  display: flex;
  gap: 16px;
}
</style>
