<template>
  <Modal
    centered
    :title="data.id ? '编辑' : '新增'"
    ok-text="确认"
    cancel-text="取消"
    :visible="true"
    width="700px"
    :confirm-loading="loading"
    @cancel="handleCancel"
    @ok="handleOk"
  >
    <Form class="form" layout="vertical" :model="formData" name="basic" autocomplete="off">
      <Row :gutter="[24, 0]">
        <Col :span="24">
          <FormItem label="名称" v-bind="validateInfos.name">
            <Input placeholder="请输入名称" v-model:value="formData.name"
          /></FormItem>
        </Col>
        <Col :span="24"
          ><FormItem label="所属产品" v-bind="validateInfos.productId">
            <Select
              v-model:value="formData.productId"
              :options="productOptions"
              placeholder="请选择所属产品"
              allowClear
              show-search
              :filter-option="filterOption"
            /> </FormItem
        ></Col>
        <Col :span="12"
          ><FormItem label="版本号" v-bind="validateInfos.version">
            <Input placeholder="请输入版本号" v-model:value="formData.version" /></FormItem
        ></Col>
        <Col :span="12"
          ><FormItem label="版本序号" v-bind="validateInfos.versionOrder">
            <InputNumber
              placeholder="请输入版本序号"
              style="width: 100%"
              :min="1"
              :max="99999"
              v-model:value="formData.versionOrder" /></FormItem
        ></Col>
        <Col :span="12"
          ><FormItem label="签名方式" v-bind="validateInfos.signMethod">
            <Select
              v-model:value="formData.signMethod"
              :options="[
                { label: 'MD5', value: 'md5' },
                { label: 'SHA256', value: 'sha256' }
              ]"
              placeholder="请选择签名方式"
              allowClear
              show-search
              :filter-option="filterOption"
              @change="changeSignMethod"
            />
          </FormItem>
        </Col>
        <Col :span="12"
          ><FormItem v-bind="validateInfos.sign">
            <template #label>
              签名
              <Tooltip title="请输入本地文件进行签名加密后的值">
                <JAIcon type="QuestionCircleOutlined" style="margin-left: 2px" />
              </Tooltip>
            </template>
            <Input placeholder="请输入签名" v-model:value="formData.sign" /></FormItem
        ></Col>
        <Col :span="24">
          <FormItem label="固件上传" v-bind="validateInfos.url">
            <FileUpload v-model:modelValue="formData.url" v-model:extraValue="extraValue" /> </FormItem
        ></Col>
        <Col :span="24">
          <FormItem label="其他配置" v-bind="validateInfos.properties">
            <Form
              :class="dynamicValidateForm.properties.length !== 0 && 'formRef'"
              ref="formRef"
              name="dynamic_form_nest_item"
              :model="dynamicValidateForm"
            >
              <div
                class="formRef-content"
                v-for="(propertie, index) in dynamicValidateForm.properties"
                :key="propertie.keyid"
              >
                <FormItem
                  :label="index === 0 && 'Key'"
                  class="formRef-form-item"
                  :name="['properties', index, 'id']"
                  :rules="{
                    required: true,
                    message: '请输入KEY'
                  }"
                >
                  <Input v-model:value="propertie.id" placeholder="请输入KEY" />
                </FormItem>
                <FormItem
                  :label="index === 0 && 'Value'"
                  class="formRef-form-item"
                  :name="['properties', index, 'value']"
                  :rules="{
                    required: true,
                    message: '请输入VALUE'
                  }"
                >
                  <Input v-model:value="propertie.value" placeholder="请输入VALUE" />
                </FormItem>
                <FormItem :label="index === 0 && '操作'" class="formRef-form-item" style="width: 10%">
                  <Popconfirm title="确认删除吗？" ok-text="确认" cancel-text="取消" @confirm="removeList(propertie)">
                    <JAIcon type="DeleteOutlined" />
                  </Popconfirm>
                </FormItem>
              </div>
              <FormItem class="formRef-form-item-add">
                <JButton type="dashed" block @click="addList">
                  <JAIcon type="PlusOutlined" />
                  添加
                </JButton>
              </FormItem>
            </Form>
          </FormItem>
        </Col>
        <Col :span="24">
          <FormItem label="说明" v-bind="validateInfos.description">
            <Textarea
              placeholder="请输入说明"
              v-model:value="formData.description"
              :maxlength="200"
              :rows="3"
              showCount
            /> </FormItem
        ></Col>
      </Row>
    </Form>
  </Modal>
</template>
<script lang="ts" setup>
  import { ref, reactive, onMounted, watch } from 'vue';
  // @ts-ignore
  import {
    Select,
    Form,
    Button as JButton,
    AIcon as JAIcon,
    Modal,
    Row,
    Col,
    FormItem,
    Tooltip,
    Textarea,
    Popconfirm,
    Input,
    InputNumber
  } from 'linker-ui-components';
  import FileUpload from './FileUpload.vue';
  import { save, update, queryProduct, validateVersion } from '../../../../api/device/firmware';
  import type { FormInstance } from 'ant-design-vue';
  import type { Properties } from '../type';
  import { onlyMessage } from '@jdlinker/utils';

  const formRef = ref<FormInstance>();
  const dynamicValidateForm = reactive<{ properties: Properties[] }>({
    properties: []
  });

  const removeList = (item: Properties) => {
    let index = dynamicValidateForm.properties.indexOf(item);
    if (index !== -1) {
      dynamicValidateForm.properties.splice(index, 1);
    }
  };
  const addList = () => {
    dynamicValidateForm.properties.push({
      id: '',
      value: '',
      keyid: Date.now()
    });
  };

  const loading = ref(false);
  const useForm = Form.useForm;
  const productOptions = ref([]);

  const props = defineProps({
    data: {
      type: Object,
      default: () => {}
    }
  });

  const emit = defineEmits(['change']);

  const id = props.data.id;
  const VersionOrder = props.data.versionOrder;
  const VersionSign = props.data.sign;
  const VersionUrl = props.data.url;

  const formData: any = ref({
    name: '',
    productId: undefined,
    version: '',
    versionOrder: '',
    signMethod: undefined,
    sign: '',
    url: '',
    properties: [],
    description: ''
  });

  const extraValue: any = ref({});

  const validatorSign = async (_: Record<string, any>, value: string) => {
    const { signMethod, url } = formData.value;
    if (id && VersionSign === value && VersionUrl === url) {
      return Promise.resolve();
    } else {
      if (value && !!signMethod && !!url && !!extraValue.value) {
        return extraValue.value[signMethod] !== value
          ? Promise.reject('签名不一致，请检查文件是否上传正确')
          : Promise.resolve();
      }
    }
  };
  const validatorVersionOrder = async (_: Record<string, any>, value: string) => {
    if (id && VersionOrder === value) {
      return Promise.resolve();
    } else {
      const { signMethod, productId } = formData.value;
      if (value && !!signMethod && productId) {
        const res = await validateVersion(productId, value);
        if (res.code === 200) {
          return res.result ? Promise.reject('版本序号已存在') : Promise.resolve();
        }
      }
    }
  };

  const { resetFields, validate, validateInfos } = useForm(
    formData,
    reactive({
      name: [
        { required: true, message: '请输入名称' },
        { max: 64, message: '最多可输入64个字符' }
      ],
      productId: [{ required: true, message: '请选择所属产品' }],
      version: [
        { required: true, message: '请输入版本号' },
        { max: 64, message: '最多可输入64个字符', trigger: 'change' }
      ],
      versionOrder: [
        { required: true, message: '请输入版本序号' },
        { validator: validatorVersionOrder, trigger: 'blur' }
      ],
      signMethod: [{ required: true, message: '请选择签名方式' }],
      // sign: [{ required: true, message: '请输入签名' }, { validator: validatorSign }],
      sign: [{ required: true, message: '请输入签名' }],
      url: [{ required: true, message: '请上传文件' }],
      description: [{ max: 200, message: '最多可输入200个字符' }]
    })
  );

  const filterOption = (input: string, option: any) => {
    return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0;
  };

  const handleOk = async () => {
    const { properties }: any = await formRef.value?.validate();

    validate()
      .then(async (res: any) => {
        const product: any = productOptions.value.find((item: any) => item?.value === res.productId);
        const productName = product?.label || props.data?.url;
        const size = extraValue.value?.size || props.data?.size;

        const params = {
          ...toRaw(formData.value),
          properties: !!properties ? properties : [],
          productName,
          size
        };
        loading.value = true;
        const response = !id
          ? await save(params).catch(() => {})
          : await update({ ...props.data, ...params }).catch(() => {});
        if (response?.code === 200) {
          onlyMessage('操作成功', 'success');

          emit('change', true);
        }
        loading.value = false;
      })
      .catch((err) => {
        loading.value = false;
      });
  };

  const handleCancel = () => {
    emit('change', false);
  };

  const changeSignMethod = () => {
    formData.value.sign = '';
    formData.value.url = '';
  };

  onMounted(() => {
    queryProduct({
      paging: false,
      terms: [{ column: 'state', value: 1 }],
      sorts: [{ name: 'createTime', order: 'desc' }]
    }).then((resp: any) => {
      productOptions.value = resp.result.map((item: any) => ({
        value: item.id,
        label: item.name
      }));
    });
  });
  watch(
    () => props.data,
    (value) => {
      if (value.id) {
        formData.value = value;
        dynamicValidateForm.properties = value.properties;
      }
    },
    { immediate: true, deep: true }
  );
  watch(
    () => extraValue.value,
    () => validate('sign'),
    { deep: true }
  );
</script>

<style lang="less" scoped>
  .form {
    .form-radio-button {
      width: 148px;
      height: 80px;
      padding: 0;
      img {
        width: 100%;
        height: 100%;
      }
    }
    .form-url-button {
      margin-top: 10px;
    }
    .form-submit {
      background-color: @primary-color !important;
    }
  }
  .formRef {
    border: 1px dashed #d9d9d9;
    .formRef-title {
      display: flex;
      justify-content: space-between;
    }
    .formRef-content {
      padding: 10px;
      display: flex;
      margin-bottom: 10px;
      .formRef-form-item {
        width: 47%;
        padding-right: 10px;
      }
    }
    .formRef-form-item-add {
      margin-top: 20px;
    }
  }
</style>
