<template>
  <tiny-form ref="createData" class="create-form" label-position="left" label-width="20%">
    <tiny-form-item label="名称">
      <tiny-input v-model="state.createData.name" placeholder="只能包含数字字母及下划线"></tiny-input>
      <div v-if="errorMessage" class="error-tip">{{ errorMessage }}</div>
    </tiny-form-item>

    <tiny-form-item label="描述">
      <tiny-input v-model="state.createData.description" placeholder="请输入"></tiny-input>
    </tiny-form-item>

    <tiny-form-item label="请求地址">
      <div class="textarea-warp">
        <tiny-input
          v-model="state.createData.options.url"
          type="textarea"
          resize="none"
          placeholder="请输入"
        ></tiny-input>
      </div>
    </tiny-form-item>

    <tiny-form-item label="请求方式">
      <tiny-button-group v-model="state.createData.options.method" :data="state.requestData"></tiny-button-group>
    </tiny-form-item>
  </tiny-form>

  <div class="create-config">
    <div>
      <div class="title">请求参数</div>
      <monaco-editor
        ref="paramsEditor"
        class="monaco-editor"
        :value="JSON.stringify(state.createData.options.params, null, 2)"
        :options="state.options"
      />
    </div>
    <div>
      <div class="title">启用服务</div>
      <tiny-switch v-model="state.createData.options.isSync" class="send-request"></tiny-switch>
      <span class="use-service"><span>* </span> 页面初始化时是否加载该服务</span>
    </div>
    <div class="send-service">
      <tiny-button type="info">发送请求</tiny-button>
      <div class="use-service">
        <meta-description type="warning">
          <template #content>
            <div>
              <span>* </span>
              完善以上信息,点击按钮编辑器将自动发送该服务,服务响应的数据将填充至下面的编辑器中,否则需要手动将响应数据填充至下面的编辑器中
            </div>
          </template>
        </meta-description>
      </div>
    </div>
    <div>
      <div class="data-wrap title">
        <div>数据处理</div>
        <tiny-popover placement="bottom-start" trigger="hover" popperClass="data-source-popper data-remote-popper">
          <template #reference>
            <span class="icon">
              <icon-plus class="icon-plus"></icon-plus>
            </span>
          </template>

          <ul>
            <li v-for="(item, index) in state.datapool" :key="index" @click="addFunction(item)">
              {{ item.name }}
            </li>
          </ul>
        </tiny-popover>
      </div>

      <create-function
        v-if="isFetchShow"
        ref="fetchEditor"
        :name="state.datapool[0].name"
        :value="state.createData.options.didFetch?.source"
        @remove="removeFunction(state.datapool[0])"
      />
      <create-function
        v-if="isFitShow"
        ref="fitEditor"
        :name="state.datapool[1].name"
        :value="state.createData.options.fit?.source"
        @remove="removeFunction(state.datapool[1])"
      />
    </div>
  </div>
</template>

<script lang="ts">
/* metaService: engine.plugins.state.CreateRemoteAPI */
import { getCurrentInstance, reactive } from 'vue'
import type { Component } from 'vue'
import { ButtonGroup, Form, FormItem, Input, Popover, Switch, Button } from '@opentiny/vue'
import { VueMonaco as MonacoEditor, MetaDescription } from '@opentiny/tiny-engine-common'
import { iconPlus } from '@opentiny/vue-icon'
import CreateFunction from './CreateRemoteFunction.vue'

export default {
  components: {
    MonacoEditor,
    CreateFunction,
    TinyForm: Form,
    TinyFormItem: FormItem,
    TinyInput: Input,
    TinySwitch: Switch,
    TinyButtonGroup: ButtonGroup as Component,
    TinyPopover: Popover as Component,
    IconPlus: iconPlus(),
    TinyButton: Button as Component,
    MetaDescription
  },
  props: {
    createData: {
      type: Object,
      default: () => ({ options: {} })
    },
    errorMessage: {
      type: String
    },
    isFitShow: {
      type: Boolean
    },
    isFetchShow: {
      type: Boolean
    }
  },
  setup(props, { emit }) {
    const instance = getCurrentInstance()

    const state = reactive({
      createData: props.createData,
      options: {
        language: 'javascript',
        minimap: { enabled: false }
      },
      requestData: [
        { text: 'JSONP', value: 'JSONP' },
        { text: 'GET', value: 'GET' },
        { text: 'POST', value: 'POST' },
        { text: 'PUT', value: 'PUT' },
        { text: 'DELETE', value: 'DELETE' }
      ],
      datapool: [
        {
          id: 'didFetch',
          name: '请求完成回调函数(didFetch)'
        },
        {
          id: 'fit',
          name: '请求返回时的数据适配(fit)'
        }
      ]
    })

    const addFunction = (item) => {
      emit('addFunction', item)
    }

    const removeFunction = (item) => {
      emit('removeFunction', item)
    }

    const getParamsEditor = () => {
      return instance.refs.paramsEditor
    }

    const getFitEditor = () => {
      return instance.refs.fitEditor?.getEditor()
    }

    const getFetchEditor = () => {
      return instance.refs.fetchEditor?.getEditor()
    }

    return {
      state,
      addFunction,
      removeFunction,
      getParamsEditor,
      getFitEditor,
      getFetchEditor
    }
  }
}
</script>

<style lang="less" scoped>
.create-form {
  padding: 12px;

  .error-tip {
    color: var(--te-state-common-error-color);
    margin-top: 4px;
    font-size: 12px;
  }

  .textarea-warp {
    display: flex;
    justify-content: flex-start;
    align-items: center;
  }

  .tiny-button-group {
    width: 100%;
  }

  :deep(.tiny-group-item) {
    display: flex;
    width: 100%;
    button {
      position: relative;
      min-width: inherit;
      padding: 0 4px;
      margin: 0;
      width: 100%;
    }
    li {
      flex: 1 1 0;
      &:not(:last-child) {
        button:before {
          content: '';
          display: inline-block;
          width: 1px;
          height: 100%;
          position: absolute;
          top: 0;
          right: 0;
          z-index: 99;
        }
      }
    }
  }
}

.create-config {
  .title {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 8px 12px;
    background: var(--te-state-tip-bg-color);
    border-top: 1px solid var(--te-state-common-border-color);
    border-bottom: 1px solid var(--te-state-common-border-color);
    color: var(--te-state-common-label-text-color);
  }

  .use-service {
    color: var(--te-state-common-label-text-color);
    font-size: 12px;
    margin-top: 10px;

    span {
      color: var(--te-state-common-error-color);
    }
  }

  .send-service {
    text-align: right;
    border-top: 1px solid var(--te-state-common-border-color);
    padding: 20px 10px;
    margin-bottom: 10px;

    .use-service {
      text-align: left;
      padding-top: 5px;

      div {
        margin-bottom: 5px;
      }
    }

    .title {
      margin-bottom: 10px;
    }
  }

  .send-request {
    margin: 12px;
  }

  .data-wrap {
    display: flex;
    justify-content: space-between;
    align-items: center;

    & > span {
      line-height: 1;
    }

    .icon-plus {
      cursor: pointer;
      color: var(--te-state-remote-icon-color);
      outline: none;
    }

    .icon {
      width: 20px;
      height: 20px;
      color: var(--te-state-common-label-text-color);
      font-size: 16px;
      border-radius: 2px;
      margin-right: 8px;
      cursor: pointer;
      display: inline-flex;
      justify-content: center;
      align-items: center;
      transition: 0.3s;

      &:hover {
        color: var(--te-state-common-icon-color-hover);
        background: var(--te-state-common-bg-color-hover);
      }
    }
  }

  .monaco-editor {
    height: 80px;
    margin-top: 8px;
  }
}
</style>