<template>
  <a-page-header
    :title="isUpdate ? '表单设计' : '新增表单'"
    @back="() => $router.go(-1)"
  >
    <div class="ele-cell ele-cell-align-top">
      <!-- 设计画布 -->
      <div class="body ele-cell-content ele-bg-white">
        <a-card>
          <a-form
            ref="formRef"
            :model="form"
            :rules="rules"
            labelAlign="left"
            :label-col="
              styleResponsive ? { md: 4, sm: 5, xs: 24 } : { flex: '90px' }
            "
            :wrapper-col="
              styleResponsive ? { md: 18, sm: 19, xs: 24 } : { flex: '1' }
            "
          >
            <a-form-item label="表单名称" name="name">
              <a-input
                allow-clear
                :maxlength="100"
                placeholder="请输入表单名称"
                v-model:value="form.name"
              />
            </a-form-item>
            <a-form-item label="表单说明">
              <a-textarea
                :rows="4"
                :maxlength="1000"
                show-count
                placeholder="请输入表单说明"
                v-model:value="form.comments"
              />
            </a-form-item>
            <a-form-item
              label="提交次数"
              name="submitNumber"
              extra="设置每位用户可以提交表单的次数"
            >
              <a-radio-group v-model:value="form.submitNumber">
                <a-radio :value="1">1次</a-radio>
                <a-radio :value="0">不限</a-radio>
              </a-radio-group>
            </a-form-item>
            <a-form-item label="顶部图片" name="photo">
              <a-space direction="vertical" style="padding-top: 5px">
                <a-radio-group v-model:value="form.hidePhoto">
                  <a-radio :value="1">隐藏</a-radio>
                  <a-radio :value="0">顶部图片</a-radio>
                </a-radio-group>
                <template v-if="form.hidePhoto == 0">
                  <SelectFile
                    :placeholder="`请选择图片`"
                    :limit="1"
                    :data="photo"
                    @done="chooseFile"
                    @del="onDeleteItem"
                  />
                  <div class="ele-text-placeholder"
                    >请上传jpg、png格式的图片，图片尺寸：750px*460px</div
                  >
                </template>
              </a-space>
            </a-form-item>
            <a-form-item label="视频文件" name="video">
              <a-space direction="vertical" style="padding-top: 5px">
                <a-radio-group v-model:value="form.hideVideo">
                  <a-radio :value="1">隐藏</a-radio>
                  <a-radio :value="0">视频文件</a-radio>
                </a-radio-group>
                <template v-if="form.hideVideo == 0">
                  <SelectFile
                    :placeholder="`请选择视频文件`"
                    :limit="1"
                    :data="video"
                    :type="`video`"
                    @done="chooseVideo"
                    @del="onDeleteVideoItem"
                  />
                  <div class="ele-text-placeholder"
                    >请上传mp4格式的视频文件，大小200M以内</div
                  >
                </template>
              </a-space>
            </a-form-item>
            <a-form-item label="背景图片" name="background">
              <a-space direction="vertical" style="padding-top: 5px">
                <a-radio-group
                  v-model:value="form.hideBackground"
                  name="submitNumber"
                >
                  <a-radio :value="1">隐藏</a-radio>
                  <a-radio :value="0">自定义</a-radio>
                </a-radio-group>
                <template v-if="form.hideBackground == 0">
                  <SelectFile
                    :placeholder="`请选择图片`"
                    :limit="1"
                    :data="background"
                    @done="chooseFile2"
                    @del="onDeleteItem2"
                  />
                  <div class="ele-text-placeholder"
                    >请上传jpg、png格式的图片，图片尺寸：750px*1624px</div
                  >
                </template>
              </a-space>
            </a-form-item>
            <a-form-item
              label="背景透明度"
              name="opacity"
              v-if="form.hideBackground == 0"
            >
              <a-input-number
                style="width: 140px"
                :step="0.1"
                :max="1"
                :min="0.1"
                placeholder="设置背景透明度"
                v-model:value="form.opacity"
              />
            </a-form-item>
            <a-form-item label="表单内容" name="content">
              <div class="demo-drag-list">
                <vue-draggable
                  v-model="formData"
                  item-key="id"
                  :animation="300"
                  handle=".sort-handle"
                >
                  <template #item="{ element, index }">
                    <a-form-item>
                      <div class="demo-drag-list-item ele-cell">
                        <drag-outlined class="sort-handle" />
                        <div class="ele-cell-content">
                          <a-space class="ele-cell">
                            <a-input
                              v-model:value="element.name"
                              style="width: 500px"
                            >
                              <template #addonBefore>
                                <a-select
                                  v-model:value="element.type"
                                  style="width: 120px"
                                  @change="onSelect(element, index)"
                                >
                                  <a-select-option value="text"
                                    >单行文本</a-select-option
                                  >
                                  <a-select-option value="textarea"
                                    >多行文本</a-select-option
                                  >
                                  <a-select-option value="radio"
                                    >单选</a-select-option
                                  >
                                  <a-select-option value="checkbox"
                                    >多选</a-select-option
                                  >
                                  <a-select-option value="phone"
                                    >手机号码</a-select-option
                                  >
                                  <a-select-option value="email"
                                    >邮箱</a-select-option
                                  >
                                  <a-select-option value="time"
                                    >时间</a-select-option
                                  >
                                  <a-select-option value="date"
                                    >日期</a-select-option
                                  >
                                  <a-select-option value="image"
                                    >图片上传</a-select-option
                                  >
                                </a-select>
                              </template>
                            </a-input>
                            <a-checkbox v-model:checked="element.checked"
                              >必填</a-checkbox
                            >
                            <a
                              v-if="element.type == 'radio'"
                              @click="openRadioForm(element)"
                              >设置</a
                            >
                            <a
                              v-if="element.type == 'checkbox'"
                              @click="openCheckboxForm(element)"
                              >设置</a
                            >
                            <a-button
                              @click="removeItem(index)"
                              danger
                              style="margin-left: 10px"
                              >删除</a-button
                            >
                          </a-space>
                        </div>
                      </div>
                    </a-form-item>
                  </template>
                </vue-draggable>
                <a @click="addItem"
                  ><PlusCircleOutlined style="margin-right: 4px" />新增</a
                >
              </div>
            </a-form-item>
            <a-form-item label="操作">
              <a-space>
                <a-button
                  type="primary"
                  class="ele-bg-warning ele-border-warning"
                  @click="save1"
                  >保存草稿</a-button
                >
                <a-button type="primary" @click="save2">保存并发布</a-button>
              </a-space>
            </a-form-item>
          </a-form>
        </a-card>
      </div>
      <!-- 中间间隙 -->
      <div style="width: 500px"></div>
      <!-- 设计工具 -->
      <div class="phone-layout">
        <div class="phone-header-black ele-fluid">
          <div class="title ele-fluid"> {{ form.name }} </div>
        </div>
        <div
          class="phone-body-bg ele-fluid"
          :style="{
            background:
              form.hideBackground == 0 ? `url(${form.background})` : 'none',
            backgroundRepeat: 'no-repeat',
            opacity: form.opacity,
            backgroundPosition: 'center'
          }"
        >
        </div>
        <div class="phone-body" style="overflow-y: auto; overflow-x: hidden">
          <a-image
            :src="form.photo"
            :preview="false"
            v-if="form.hidePhoto == 0"
          />
          <div class="comments" v-html="form.comments"></div>
          <div class="form-data ele-fluid">
            <a-form ref="formRef2" :rules="rules2" layout="vertical">
              <template v-for="(item, index) in formData" :key="index">
                <a-form-item v-if="item.name" :name="item.type">
                  <template #label>
                    <a-space>
                      <span>{{ item.name }}</span>
                      <span v-if="item.checked" class="ele-text-danger">*</span>
                    </a-space>
                  </template>
                  <template v-if="item.type == 'text'">
                    <a-input
                      allow-clear
                      :maxlength="200"
                      :placeholder="`${
                        item.placeholder ? `请填写${item.name}` : '请输入'
                      }`"
                      v-model:value="item.value"
                    />
                  </template>
                  <template v-if="item.type == 'textarea'">
                    <a-textarea
                      :rows="4"
                      :maxlength="200"
                      show-count
                      :placeholder="`请输入${item.name}`"
                      v-model:value="item.value"
                    />
                  </template>
                  <template v-if="item.type == 'radio'">
                    <a-radio-group v-model:value="item.radio">
                      <template
                        v-for="(radio, radioIndex) in item.options"
                        :key="radioIndex"
                      >
                        <a-radio :value="radio">{{ radio }}</a-radio>
                      </template>
                    </a-radio-group>
                  </template>
                  <template v-if="item.type == 'checkbox'">
                    <a-checkbox-group
                      v-model:value="item.checkedList"
                      :options="item.options"
                    />
                  </template>
                  <template v-if="item.type == 'phone'">
                    <a-input
                      allow-clear
                      :maxlength="11"
                      :placeholder="`${
                        item.placeholder ? `请填写${item.name}` : '请输入'
                      }`"
                      v-model:value="item.value"
                    />
                  </template>
                  <template v-if="item.type == 'email'">
                    <a-input
                      allow-clear
                      :maxlength="11"
                      :placeholder="`${
                        item.placeholder ? `请填写${item.name}` : '请输入'
                      }`"
                      v-model:value="item.value"
                    />
                  </template>
                  <template v-if="item.type == 'time'">
                    <a-time-picker
                      v-model:value="timeItem"
                      format="HH:mm"
                      @change="onTimeItem(index)"
                    />
                  </template>
                  <template v-if="item.type == 'date'">
                    <a-date-picker
                      v-model:value="item.value"
                      value-format="YYYY-MM-DD"
                    />
                  </template>
                  <template v-if="item.type == 'image'">
                    <ele-image-upload
                      v-model:value="imageItem"
                      :limit="1"
                      :upload-handler="uploadHandlerItem"
                      @click="onClickItem(index)"
                      @upload="onUploadItem"
                    />
                  </template>
                  <template v-if="item.type == 'video'"></template>
                </a-form-item>
              </template>
              <div class="submit-btn">
                <a-button type="primary" size="large" block>提交</a-button>
              </div>
            </a-form>
          </div>
        </div>
      </div>
    </div>
    <!-- 弹窗 -->
    <RadioForm
      v-model:visible="showRadioForm"
      :data="current"
      @done="doneRadio"
    />
    <CheckboxForm
      v-model:visible="showCheckboxForm"
      :data="current"
      @done="doneCheckbox"
    />
  </a-page-header>
</template>

<script lang="ts" setup>
  import { reactive, ref, unref, watch } from 'vue';
  import { useRouter } from 'vue-router';
  import { useThemeStore } from '@/store/modules/theme';
  import { storeToRefs } from 'pinia';
  import useFormData from '@/utils/use-form-data';
  import { addForm, getForm, updateForm } from '@/api/cms/form';
  import { Form as FormModel } from '@/api/cms/form/model';
  import { message } from 'ant-design-vue';
  import { FormInstance, RuleObject } from 'ant-design-vue/es/form';
  import { getSiteInfo } from '@/api/layout';
  import { uuid } from 'ele-admin-pro';
  import { Website } from '@/api/cms/website/model';
  import { ItemType } from 'ele-admin-pro/es/ele-image-upload/types';
  import { uploadFile } from '@/api/system/file';
  import { PlusCircleOutlined, DragOutlined } from '@ant-design/icons-vue';
  import VueDraggable from 'vuedraggable';
  import { toDateString } from 'ele-admin-pro';
  import { Dayjs } from 'dayjs';
  import { FileRecord } from '@/api/system/file/model';
  import RadioForm from './components/radio-form.vue';
  import CheckboxForm from './components/checkbox-form.vue';
  import {push} from "echarts/types/src/component/dataZoom/history";
  import {openUrl} from "@/utils/common";
  // 是否开启响应式布局
  const themeStore = useThemeStore();

  // 表格选中数据
  const formRef = ref<FormInstance | null>(null);
  const { currentRoute } = useRouter();
  const { query } = unref(currentRoute);
  const { styleResponsive } = storeToRefs(themeStore);
  const { screenWidth, tabs } = storeToRefs(themeStore);
  const spinning = ref(true);
  const siteInfo = ref<Website>();
  const formId = ref<number>(0);
  const isUpdate = ref<boolean>(false);
  const currentItemIndex = ref<number>(0);
  const showRadioForm = ref<boolean>(false);
  const showCheckboxForm = ref<boolean>(false);
  const current = ref<any>();
  // 顶部图片
  const photo = ref<ItemType[]>([]);
  // 视频文就
  const video = ref<ItemType[]>([]);
  // 背景图片
  const background = ref<ItemType[]>([]);
  // 表单数据里的图片
  const imageItem = ref<ItemType[]>([]);
  // 时间
  const timeItem = ref<Dayjs>();

  const formData = ref<any[]>([
    { id: uuid(4), type: 'text', name: '姓名', checked: true },
    { id: uuid(4), type: 'phone', name: '手机号码', checked: true },
    { id: uuid(4), type: 'date', name: '日期', checked: false }
  ]);

  // 表单数据
  const { form, resetFields, assignFields } = useFormData<FormModel>({
    formId: undefined,
    name: '',
    photo: '',
    background: '',
    video: '',
    submitNumber: 1,
    layout: '',
    userId: 0,
    status: 0,
    comments: '',
    sortNumber: 100,
    hidePhoto: 1,
    hideBackground: 1,
    hideVideo: 1,
    opacity: 1.0,
    clearCache: undefined
  });

  // 表单验证规则
  const rules = reactive({
    name: [
      {
        required: true,
        type: 'string',
        message: '请填写表单名称',
        trigger: 'blur'
      }
    ],
    submitNumber: [
      {
        required: true,
        type: 'number',
        message: '请设置提交次数限制',
        trigger: 'blur'
      }
    ],
    content: [
      {
        required: true,
        type: 'string',
        trigger: 'blur',
        validator: async (_rule: RuleObject, value: string) => {
          if (formData.value.length === 0) {
            return Promise.reject('请配置表单内容');
          }
          return Promise.resolve();
        }
      }
    ]
  });

  const rules2 = reactive({
    name: [
      {
        required: true,
        type: 'string',
        message: '请填写表单名称',
        trigger: 'blur'
      }
    ],
    path: [
      {
        required: true,
        type: 'string',
        message: '请填写路由地址',
        trigger: 'blur'
      }
    ],
    component: [
      {
        required: true,
        type: 'string',
        message: '请填写组件路径',
        trigger: 'blur'
      }
    ]
  });

  const openRadioForm = (row: any) => {
    current.value = row ?? null;
    showRadioForm.value = true;
  };

  const openCheckboxForm = (row: any) => {
    current.value = row ?? null;
    showCheckboxForm.value = true;
  };

  const doneRadio = (item: any) => {
    formData.value.map((d) => {
      if (d.id == item.id) {
        d.options = item.options;
      }
    });
  };

  const doneCheckbox = (item: any) => {
    formData.value.map((d) => {
      if (d.id == item.id) {
        d.options = item.options;
      }
    });
  };
  const addItem = () => {
    formData.value.push({
      id: uuid(4),
      type: 'text',
      placeholder: '请填写',
      value: undefined
    });
  };

  const removeItem = (index: number) => {
    formData.value.splice(index, 1);
  };

  /* 上传事件 */
  const uploadHandlerItem = (file: File) => {
    const item: ItemType = {
      file,
      uid: (file as any).uid,
      name: file.name
    };
    if (file.type.startsWith('video')) {
      if (file.size / 1024 / 1024 > 200) {
        message.error('大小不能超过 200MB');
        return;
      }
    }
    if (file.type.startsWith('image')) {
      if (file.size / 1024 / 1024 > 5) {
        message.error('大小不能超过 5MB');
        return;
      }
    }
    onUploadItem(item);
  };

  const onUploadItem = (item: any) => {
    const { file } = item;
    if (currentItemIndex.value > 0) {
      uploadFile(file)
        .then((data) => {
          // console.log(data);
          // console.log(formData.value[currentItemIndex.value])
          formData.value[currentItemIndex.value].image = data.path;
          imageItem.value.push({
            uid: data.id,
            url: data.path,
            status: 'done'
          });
          currentItemIndex.value = 0;
        })
        .catch((e) => {
          message.error(e.message);
        });
    }
  };

  const onClickItem = (index: number) => {
    currentItemIndex.value = index;
  };

  const onSelect = (item: any, index: number) => {
    // console.log(item);
    // console.log(index)
    if (item.type == 'checkbox') {
      formData.value[index].checkedList = ['aaa'];
      formData.value[index].options = ['aaa', 'bbb'];
    }
    if (item.type == 'radio') {
      formData.value[index].radio = 'A';
      formData.value[index].options = ['A', 'B', 'C', 'D'];
    }
  };

  const chooseFile = (data: FileRecord) => {
    photo.value.push({
      uid: data.id,
      url: data.downloadUrl,
      status: 'done'
    });
    form.photo = data.downloadUrl;
  };

  const onDeleteItem = (index: number) => {
    photo.value.splice(index, 1);
    form.photo = '';
  };

  const chooseVideo = (data: FileRecord) => {
    video.value.push({
      uid: data.id,
      url: data.downloadUrl,
      status: 'done'
    });
    form.video = data.downloadUrl;
  };

  const onDeleteVideoItem = (index: number) => {
    video.value.splice(index, 1);
    form.video = '';
  };

  const chooseFile2 = (data: FileRecord) => {
    background.value.push({
      uid: data.id,
      url: data.path,
      status: 'done'
    });
    form.background = data.path;
  };

  const onDeleteItem2 = (index: number) => {
    background.value.splice(index, 1);
    form.background = '';
  };

  /* 保存编辑 */
  const save = () => {
    if (!formRef.value) {
      return;
    }
    formRef.value
      .validate()
      .then(() => {
        const saveData = {
          ...form,
          layout: JSON.stringify(formData.value)
        };
        const saveOrUpdate = isUpdate.value ? updateForm : addForm;
        saveOrUpdate(saveData)
          .then((msg) => {
            message.success('保存成功');
            openUrl(`/website/form`);
          })
          .catch((e) => {
            message.error(e.message);
          });
      })
      .catch(() => {});
  };

  const save1 = () => {
    form.clearCache = undefined;
    save();
  };

  const save2 = () => {
    form.clearCache = 1;
    save();
  };

  const { contentWidth } = storeToRefs(themeStore);
  // 使用 watch 监听 contentWidth 改变
  watch(contentWidth, (e) => {
    console.log(e);
  });

  const onTimeItem = (index: number) => {
    formData.value[index].value = toDateString(timeItem.value, 'HH:mm');
  };

  /**
   * 加载数据
   */
  const reload = () => {
    // 加载网站信息
    getSiteInfo().then((data) => {
      siteInfo.value = data;
    });
    getForm(formId.value).then((data) => {
      if (data) {
        spinning.value = false;
        isUpdate.value = true;
        if (data.layout) {
          // layout.value = JSON.parse(data.layout);
        }
        assignFields(data);
        photo.value = [];
        background.value = [];
        formData.value = [];
        if (data.photo) {
          photo.value.push({
            uid: 1,
            url: data.photo,
            status: 'done'
          });
        }
        if (data.background) {
          background.value.push({
            uid: 2,
            url: data.background,
            status: 'done'
          });
        }
        if (data.layout) {
          formData.value = JSON.parse(data.layout);
          formData.value.map((d) => {
            if (d.type == 'image') {
              imageItem.value = [];
              imageItem.value.push({
                uid: uuid(),
                url: d.image,
                status: 'done'
              });
            }
            if (d.type == 'time') {
              // timeItem.value = dayjs(d.value);
            }
          });
        }
      }
    });
  };

  watch(
    currentRoute,
    (route) => {
      const { params, query } = unref(route);
      if(query.id){
        formId.value = Number(query.id);
        return reload();
      }
      const { id } = params;
      if (id) {
        formId.value = Number(id);
        return reload();
      }
      resetFields();
    },
    { immediate: true }
  );

  // watch(
  //   () => query.id,
  //   (id) => {
  //     console.log(id);
  //     if (id) {
  //       isUpdate.value = true;
  //       formId.value = Number(id);
  //       reload();
  //     } else {
  //       isUpdate.value = false;
  //       resetFields();
  //       formRef.value?.clearValidate();
  //     }
  //   },
  //   { immediate: true }
  // );
</script>

<script lang="ts">
  export default {
    name: 'FormDetail'
  };
</script>

<style lang="less" scoped>
  .phone-layout {
    position: fixed;
    right: 16px;
    width: 390px;
    height: 844px;
    background: url('@/assets/img/app-ui.png');
    background-repeat: no-repeat;
    background-position: top;
    background-size: 100%;
    //position: relative;
    padding: 0 16px;
    .phone-header-black {
      height: 99px;
      border-radius: 20px 20px 0 0;
      background-size: 100%;
      .title {
        height: 99px;
        font-size: 16px;
        display: flex;
        justify-content: center;
        align-items: end;
        padding-bottom: 13px;
      }
    }
    .phone-body-bg {
      padding: 0 16px;
      height: 680px;
      border-radius: 0 0 44px 44px;
      overflow: hidden;
    }
    .phone-body {
      width: 360px;
      margin-left: 16px;
      height: 674px;
      padding: 0;
      position: absolute;
      top: 98px;
      left: 0;
      z-index: 999;
      .comments {
        padding: 20px;
        word-break: break-all;
      }
      .form-data {
        padding: 10px 20px;
        .submit-btn {
          padding: 30px 0;
        }
      }
    }
  }
  .demo-drag-list {
  }

  .demo-drag-list-item {
    padding: 0 16px 12px 0;
  }

  .demo-drag-list-item + .demo-drag-list-item {
    //border-top: 1px solid hsla(0, 0%, 60%, 0.2);
  }

  .demo-drag-list-item.sortable-chosen {
    background: hsla(0, 0%, 60%, 0.1);
  }

  .demo-drag-list-item .sort-handle {
    cursor: move;
    font-size: 16px;
  }
</style>
