<!-- 通知模板 -->
<template>
  <PageContainer v-if="!visible" :pageHeaderRender="false" style="padding: 0 10px 10px 10px">
    <ProSearch :columns="searchFormSchema" target="notice-config" @search="handleSearch" />
    <FullPage style="min-height: calc(100vh - 186px)">
      <JTable
        ref="configRef"
        model="CARD"
        :columns="columns"
        :request="TemplateApi.list"
        :defaultParams="{
          column: 'createTime',
          order: 'desc',
          pageSize: 9
        }"
        :params="params"
        :gridColumn="3"
      >
        <template #headerTitle>
          <Space>
            <PermissionButton type="primary" @click="handleAdd">
              <template #icon><AIcon type="PlusOutlined" /></template>
              新增
            </PermissionButton>
            <Upload name="file" accept=".json" :showUploadList="false" :before-upload="beforeUpload">
              <PermissionButton type="primary">
                <template #icon><AIcon type="ImportOutlined" /></template>
                导入
              </PermissionButton>
            </Upload>
            <Popconfirm title="确认导出？" ok-text="确定" cancel-text="取消" @confirm="handleExport">
              <PermissionButton type="primary">
                <template #icon><AIcon type="ExportOutlined" /></template>
                导出
              </PermissionButton>
            </Popconfirm>
          </Space>
        </template>
        <template #card="slotProps">
          <CardBox :showStatus="false" :value="slotProps" :actions="getActions(slotProps, 'card')" :statusNames="{}">
            <template #img>
              <slot name="img">
                <img :src="getLogo(slotProps.type, slotProps.provider)" class="logo" />
              </slot>
            </template>
            <template #content>
              <h3 class="card-item-content-title">
                {{ slotProps.name }}
              </h3>
              <Row>
                <Col :span="12">
                  <div class="card-item-content-text"> 通知方式 </div>
                  <div>
                    {{ getMethodTxt(slotProps.type) }}
                  </div>
                </Col>
                <Col :span="12">
                  <div class="card-item-content-text"> 说明 </div>
                  <Ellipsis>
                    {{ slotProps.description }}
                  </Ellipsis>
                </Col>
              </Row>
            </template>
            <template #actions="item">
              <Tooltip v-bind="item.tooltip" :title="item.disabled && item.tooltip.title">
                <Dropdown placement="bottomRight" v-if="item.key === 'others'">
                  <Button>
                    <AIcon :type="item.icon" />
                    <span>{{ item.text }}</span>
                  </Button>
                  <template #overlay>
                    <Menu>
                      <MenuItem v-for="(o, i) in item.children" :key="i">
                        <PermissionButton type="link" @click="o.onClick">
                          <template #icon>
                            <AIcon :type="o.icon" />
                          </template>
                          <span>{{ o.text }}</span>
                        </PermissionButton>
                      </MenuItem>
                    </Menu>
                  </template>
                </Dropdown>
                <Popconfirm v-else-if="item.key === 'delete'" v-bind="item.popConfirm" :disabled="item.disabled">
                  <PermissionButton :disabled="item.disabled">
                    <template #icon>
                      <AIcon type="DeleteOutlined" />
                    </template>
                  </PermissionButton>
                </Popconfirm>
                <template v-else>
                  <PermissionButton :disabled="item.disabled" @click="item.onClick">
                    <template #icon>
                      <AIcon :type="item.icon" />
                    </template>
                    <span>{{ item.text }}</span>
                  </PermissionButton>
                </template>
              </Tooltip>
            </template>
          </CardBox>
        </template>
        <template #type="slotProps">
          <span> {{ getMethodTxt(slotProps.type) }}</span>
        </template>
        <template #provider="slotProps">
          <span>
            {{ getProviderTxt(slotProps.type, slotProps.provider) }}
          </span>
        </template>
        <template #description="slotProps">
          <Ellipsis>
            {{ slotProps.description }}
          </Ellipsis>
        </template>
        <template #action="slotProps">
          <Space :size="16">
            <template v-for="i in getActions(slotProps, 'table')" :key="i.key">
              <PermissionButton
                :danger="i.key === 'delete'"
                :disabled="i.disabled"
                :popConfirm="i.popConfirm"
                :tooltip="{
                  ...i.tooltip
                }"
                @click="i.onClick"
                type="link"
                style="padding: 0px"
              >
                <template #icon><AIcon :type="i.icon" /></template>
              </PermissionButton>
            </template>
          </Space>
        </template>
      </JTable>
    </FullPage>

    <Debug v-model:visible="debugVis" :data="currentConfig" />
    <Log v-model:visible="logVis" :data="currentConfig" />
  </PageContainer>
  <Detail v-if="visible" :id="id" @close="visible = false" />
</template>

<script setup lang="ts">
  import TemplateApi from '../../../api/notice/template';
  import type { ActionsType } from '../../device/Instance/typings';
  import { NOTICE_METHOD, MSG_TYPE } from '../const';
  import Debug from './Debug/index.vue';
  import Log from './Log/index.vue';
  import { downloadObject, onlyMessage } from '@jdlinker/utils';
  import Detail from './Detail/index.vue';
  import { ref } from 'vue';
  import JTable from '../../../components/UI/Table/index';
  import { FormSchema, JSearch as ProSearch, FullPage, PermissionButton, CardBox } from '@jdlinker/ui';
  // @ts-ignore
  import {
    PageContainer,
    AIcon,
    Button,
    Tooltip,
    Dropdown,
    Menu,
    MenuItem,
    Space,
    Popconfirm,
    Ellipsis,
    Row,
    Col,
    Upload
  } from 'linker-ui-components';

  const visible = ref<boolean>(false);
  const id = ref<any>('');

  let providerList: any = [];
  Object.keys(MSG_TYPE).forEach((key) => {
    providerList = [...providerList, ...MSG_TYPE[key]];
  });

  const configRef = ref<Record<string, any>>({});
  const params = ref<Record<string, any>>({});
  const searchFormSchema: FormSchema[] = [
    {
      label: '模板名称',
      field: 'name',
      component: 'Input'
    },
    {
      field: 'type',
      label: '通知方式',
      component: 'Select',
      componentProps: {
        options: NOTICE_METHOD
      }
    },
    {
      field: 'provider',
      label: '类型',
      component: 'Select',
      componentProps: {
        options: providerList
      }
    }
  ];
  const columns = [
    {
      title: '模板名称',
      dataIndex: 'name',
      key: 'name',
      align: 'center',
      search: {
        type: 'string'
      }
    },
    {
      title: '通知方式',
      dataIndex: 'type',
      key: 'type',
      scopedSlots: true,
      align: 'center',
      search: {
        type: 'select',
        options: NOTICE_METHOD,
        handleValue: (v: any) => {
          return v;
        }
      }
    },
    {
      title: '类型',
      dataIndex: 'provider',
      key: 'provider',
      scopedSlots: true,
      align: 'center',
      search: {
        type: 'select',
        options: providerList,
        handleValue: (v: any) => {
          return v;
        }
      }
    },
    {
      title: '说明',
      dataIndex: 'description',
      key: 'description',
      scopedSlots: true,
      ellipsis: true,
      search: {
        type: 'string'
      }
    },
    {
      title: '操作',
      key: 'action',
      fixed: 'right',
      width: 250,
      scopedSlots: true
    }
  ];

  /**
   * 搜索
   * @param params
   */
  const handleSearch = (e: any) => {
    params.value = e;
  };

  /**
   * 根据通知方式展示对应logo
   */
  const getLogo = (type: string, provider: string) => {
    return MSG_TYPE[type].find((f: any) => f.value === provider)?.logo;
  };
  /**
   * 通知方式字段展示对应文字
   */
  const getMethodTxt = (type: string) => {
    return NOTICE_METHOD.find((f) => f.value === type)?.label;
  };
  /**
   * 根据类型展示对应文案
   * @param type
   * @param provider
   */
  const getProviderTxt = (type: string, provider: string) => {
    return MSG_TYPE[type].find((f: any) => f.value === provider)?.label;
  };

  /**
   * 新增
   */
  const handleAdd = () => {
    visible.value = true;
    id.value = undefined;
  };

  /**
   * 导入
   */
  const beforeUpload = (file: any) => {
    const reader = new FileReader();
    reader.readAsText(file);
    reader.onload = async (result) => {
      const text: any = result.target?.result;
      console.log('text: ', text);
      if (!file.type.includes('json')) {
        onlyMessage('请上传json格式文件', 'error');
        return false;
      }
      try {
        const data = JSON.parse(text || '{}');
        const { success } = await TemplateApi.update(data);
        if (success) {
          onlyMessage('操作成功', 'success');
          configRef.value.reload();
        }
        return true;
      } catch {
        onlyMessage('请上传json格式文件', 'error');
      }
      return true;
    };
    return false;
  };

  /**
   * 导出
   */
  const handleExport = () => {
    downloadObject(configRef.value._dataSource, `通知模板数据`);
  };

  // const syncVis = ref(false);
  const debugVis = ref(false);
  const logVis = ref(false);
  const currentConfig = ref<Partial<Record<string, any>>>();
  const getActions = (data: Partial<Record<string, any>>, type: 'card' | 'table'): ActionsType[] => {
    if (!data) return [];
    const actions: any = [
      {
        key: 'update',
        text: '编辑',
        tooltip: {
          title: '编辑'
        },
        icon: 'EditOutlined',
        onClick: () => {
          visible.value = true;
          id.value = data.id;
        }
      },
      {
        key: 'debug',
        text: '调试',
        tooltip: {
          title: '调试'
        },
        icon: 'BugOutlined',
        onClick: () => {
          debugVis.value = true;
          currentConfig.value = data;
        }
      },
      {
        key: 'delete',
        text: '删除',
        popConfirm: {
          title: '确认删除?',
          onConfirm: async () => {
            const resp = await TemplateApi.del(data.id);
            if (resp) {
              onlyMessage('操作成功！', 'success');
              configRef.value?.reload();
            } else {
              onlyMessage('操作失败！', 'error');
            }
          }
        },
        icon: 'DeleteOutlined'
      }
    ];

    const others: any = {
      key: 'others',
      text: '其他',
      icon: 'EllipsisOutlined',
      children: [
        {
          key: 'export',
          text: '导出',
          tooltip: {
            title: '导出'
          },
          icon: 'ArrowDownOutlined',
          onClick: () => {
            downloadObject(data, `${data.name}`);
          }
        },
        {
          key: 'log',
          text: '通知记录',
          tooltip: {
            title: '通知记录'
          },
          icon: 'BarsOutlined',
          onClick: () => {
            logVis.value = true;
            currentConfig.value = data;
          }
        }
      ]
    };

    type === 'card'
      ? actions.splice(actions.length - 1, 0, others)
      : actions.splice(actions.length - 1, 0, ...others.children);
    return actions;
  };
</script>

<style lang="less" scoped>
  .logo {
    width: 88px;
    height: 88px;
  }
  :deep(.card .card-warp .card-content) {
    padding: 28px 12px 28px 30px;
  }
  :deep(.jtable-card) {
    min-height: 597px;
  }
  :deep(.ant-pagination-options) {
    display: none;
  }
</style>
