/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import {
  defineComponent,
  PropType,
  toRefs,
  watch,
  onMounted,
  ref,
  Ref
} from 'vue'
import { NSelect, NInput } from 'naive-ui'
import { isFunction } from 'lodash'
import Modal from '@/components/modal'
import Form from '@/components/form'
import { useI18n } from 'vue-i18n'
import { useForm } from './use-form'
import { useDetail } from './use-detail'
import getElementByJson from '@/components/form/get-elements-by-json'
import type { IRecord, FormRules, IFormItem } from './types'

interface IElements extends Omit<Ref, 'value'> {
  value: IFormItem[]
}

const props = {
  show: {
    type: Boolean as PropType<boolean>,
    default: false
  },
  currentRecord: {
    type: Object as PropType<IRecord>,
    default: {}
  }
}
const DetailModal = defineComponent({
  name: 'DetailModal',
  props,
  emits: ['cancel', 'update'],
  setup(props, ctx) {
    const { t } = useI18n()

    const rules = ref<FormRules>({})
    const elements = ref<IFormItem[]>([]) as IElements

    const {
      meta,
      state,
      setDetail,
      initForm,
      resetForm,
      getFormValues,
      changePlugin
    } = useForm()

    const { status, createOrUpdate } = useDetail(getFormValues)

    const onCancel = () => {
      resetForm()
      rules.value = {}
      elements.value = []
      ctx.emit('cancel')
    }

    const onSubmit = async () => {
      await state.detailFormRef.validate()
      const res = await createOrUpdate(props.currentRecord, state.json)
      if (res) {
        onCancel()
        ctx.emit('update')
      }
    }
    const onChangePlugin = changePlugin

    watch(
      () => props.show,
      async () => {
        props.show && props.currentRecord && setDetail(props.currentRecord)
      }
    )
    watch(
      () => state.json,
      () => {
        if (!state.json?.length) return
        state.json.forEach((item) => {
          const mergedItem = isFunction(item) ? item() : item
          mergedItem.name = t(
            'security.alarm_instance' + '.' + mergedItem.field
          )
        })
        const { rules: fieldsRules, elements: fieldsElements } =
          getElementByJson(state.json, state.detailForm)
        rules.value = fieldsRules
        elements.value = fieldsElements
      }
    )

    onMounted(() => {
      initForm()
    })

    return {
      t,
      ...toRefs(state),
      ...toRefs(status),
      meta,
      rules,
      elements,
      onChangePlugin,
      onSubmit,
      onCancel
    }
  },
  render(props: { currentRecord: IRecord }) {
    const {
      show,
      t,
      meta,
      rules,
      elements,
      detailForm,
      uiPlugins,
      pluginsLoading,
      loading,
      saving,
      onChangePlugin,
      onCancel,
      onSubmit
    } = this
    const { currentRecord } = props
    return (
      <Modal
        show={show}
        title={`${t(
          currentRecord?.id
            ? 'security.alarm_instance.edit'
            : 'security.alarm_instance.create'
        )} ${t('security.alarm_instance.alarm_instance')}`}
        onConfirm={onSubmit}
        confirmLoading={saving || loading}
        onCancel={() => void onCancel()}
      >
        {{
          default: () => (
            <Form
              ref='detailFormRef'
              loading={loading || pluginsLoading}
              meta={{
                ...meta,
                rules: {
                  ...meta.rules,
                  ...rules
                },
                elements: [
                  {
                    path: 'instanceName',
                    label: t('security.alarm_instance.alarm_instance_name'),
                    widget: (
                      <NInput
                        v-model={[detailForm.instanceName, 'value']}
                        placeholder={t(
                          'security.alarm_instance.alarm_instance_name_tips'
                        )}
                      />
                    )
                  },
                  {
                    path: 'pluginDefineId',
                    label: t('security.alarm_instance.select_plugin'),
                    widget: (
                      <NSelect
                        v-model={[detailForm.pluginDefineId, 'value']}
                        options={uiPlugins}
                        disabled={!!currentRecord?.id}
                        placeholder={t(
                          'security.alarm_instance.select_plugin_tips'
                        )}
                        on-update:value={onChangePlugin}
                      />
                    )
                  },
                  ...elements
                ]
              }}
              layout={{
                cols: 24
              }}
            />
          )
        }}
      </Modal>
    )
  }
})

export default DetailModal
