<!-- 用户编辑弹窗 -->
<template>
  <a-drawer
    width="75%"
    :visible="visible"
    :confirm-loading="loading"
    v-if="detail && data"
    :title="`工单详情(${detail.taskId})：${data.name}`"
    :maxable="true"
    :body-style="{ paddingBottom: '8px', backgroundColor: '#f3f3f3' }"
    @update:visible="updateVisible"
    @close="onClose"
    :footer="null"
  >
    <a-card class="task-card" :bordered="false">
      <a-steps
        :current="active"
        direction="horizontal"
        :responsive="styleResponsive"
      >
        <template v-for="item in taskProgressDict">
          <a-step :title="item.label" />
        </template>
      </a-steps>
    </a-card>
    <a-spin :spinning="loading" v-if="appId > 0">
      <a-collapse class="task-card" v-model:activeKey="activeKey" :bordered="false">
      <a-collapse-panel key="1" header="应用详情">
        <a-card
          :bordered="false"
          :body-style="{ padding: '16px' }"
        >
          <div class="content">
            <div class="app-item-list">
              <div class="ele-cell">
                <div class="ele-cell-content">
                  <div class="ele-cell-desc">AppID(应用ID)</div>
                  <div class="ele-cell-title">{{ appInfo.appId }}</div>
                </div>
              </div>
              <a-divider />
              <div class="ele-cell">
                <div class="ele-cell-content">
                  <div class="ele-cell-desc">小程序名称</div>
                  <div class="ele-cell-title">
                    {{ appInfo.appName }}
                  </div>
                </div>
              </div>
              <a-divider />
              <div class="ele-cell">
                <div class="ele-cell-content">
                  <div class="ele-cell-desc">小程序描述</div>
                  <div class="ele-cell-title">{{ appInfo.comments }}</div>
                </div>
              </div>
              <a-divider />
              <div class="ele-cell">
                <div class="ele-cell-content">
                  <div class="ele-cell-desc">小程序码</div>
                  <div class="ele-cell-title">
                    <a-image
                      :height="120"
                      :width="120"
                      :preview="false"
                      :src="appInfo.appQrcode"
                      fallback="https://file.wsdns.cn/20230218/550e610d43334dd2a7f66d5b20bd58eb.svg"
                    />
                  </div>
                </div>
              </div>
              <a-divider />
              <div class="ele-cell">
                <div class="ele-cell-content">
                  <div class="ele-cell-desc">应用图标</div>
                  <div class="ele-cell-title">
                    <a-image
                      :height="70"
                      :width="70"
                      :preview="false"
                      :src="appInfo.appIcon"
                      fallback="https://file.wsdns.cn/20230218/550e610d43334dd2a7f66d5b20bd58eb.svg"
                    />
                  </div>
                </div>
              </div>
              <div class="ele-cell">
                <div class="ele-cell-content">
                  <div class="ele-cell-desc">状态</div>
                  <div class="ele-cell-title">{{
                      appInfo.status === 1 ? '开发中' : '已上线'
                    }}</div>
                </div>
              </div>
            </div>
          </div>
        </a-card>
      </a-collapse-panel>
      <a-collapse-panel key="2" header="开发资料">
        <a-card
          :bordered="false"
          :body-style="{ padding: '16px' }"
        >
          <byte-md-viewer :value="appInfo.requirement" :plugins="plugins" />
        </a-card>
      </a-collapse-panel>
    </a-collapse>
    </a-spin>
    <a-spin :spinning="loading" v-if="detail">
      <!-- 回复列表 -->
      <a-card class="task-card replay-bg"
              :bordered="false"
              v-for="(item, index) in record"
              :key="index">
        <a-page-header
          :title="item.nickname"
          :sub-title="`${item.createTime}`"
          :avatar="{ src: item.avatar ? item.avatar : 'https://file.gxwebsoft.com/20230217/c8a5c699b3174866a36dd6d378a09bb9.jpg' }"
        >
          <template #extra>
            <a-button key="2" href="#bottom" @click="onReply(item)">回复</a-button>
            <template v-for="(role,index) in loginUser.roles" :key="index">
              <a-button key="1" v-if="role.roleCode === 'admin'" @click="remove(item)">删除</a-button>
            </template>

          </template>
          <div class="content">
            <template v-if="item.content">
              <byte-md-viewer :value="item.content" :plugins="plugins" />
            </template>
            <!-- 附件列表 -->
            <a-space v-if="item.files && item.files != '[]'">
              <template v-for="file in JSON.parse(item.files)">
                <a-button v-if="file.name && file.name != 'image'" :href="file.url">{{ file.name }}</a-button>
                <a-image v-else :height="120" :width="120" :src="file.url" />
              </template>
            </a-space>
            <!-- 二级回复 -->
            <template v-if="item.children">
              <a-card class="task-card replay-bg"
                      v-for="(item, index) in item.children"
                      :key="index">
                <a-page-header
                  :title="item.nickname"
                  :sub-title="`${item.createTime}`"
                  :avatar="{ src: item.avatar ? item.avatar : 'https://file.gxwebsoft.com/20230217/c8a5c699b3174866a36dd6d378a09bb9.jpg' }"
                >
                  <template #extra>
                    <template v-for="(role,index) in loginUser.roles" :key="index">
                      <a-button key="1" v-if="role.roleCode === 'admin'" @click="remove(item)">删除</a-button>
                    </template>
                  </template>
                  <div class="content">
                    <template v-if="item.content">
                      <byte-md-viewer :value="item.content" :plugins="plugins" />
                    </template>
                    <template v-if="item.children">
                      {{ item.children }}
                    </template>
                  </div>
                  <!-- 附件列表 -->
                  <a-space v-if="item.files && item.files != '[]'">
                    <template v-for="file in JSON.parse(item.files)">
                      <a-button v-if="file.name && file.name != 'image'" :href="file.url">{{ file.name }}</a-button>
                      <a-image v-else :height="120" :width="120" :src="file.url" />
                    </template>
                  </a-space>
                </a-page-header>
              </a-card>
            </template>
          </div>
        </a-page-header>
      </a-card>
      <!-- 操作按钮 -->
      <div class="task-btn" v-if="detail.status === 0">
        <a-space>
          <a-button type="primary" ghost size="large" @click="complete">
            已解决
          </a-button>
          <a-button
            type="primary"
            danger
            ghost
            size="large"
            href="#bottom"
            @click="showEdit"
          >
            我要回复
          </a-button>
          <a-button type="primary" ghost size="large" @click="completedTask">
            已完结
          </a-button>
          <a-button type="primary" ghost size="large" @click="closeTask">
            关单
          </a-button>
        </a-space>
      </div>
      <div class="task-btn" v-if="detail.status === 1">
        <a-button type="primary" ghost size="large" @click="openTask">
          开启工单
        </a-button>
      </div>
    </a-spin>
    <!-- 回复表单 -->
    <div id="bottom">
      <a-card :title="replyName ? `回复${replyName}` : `处理结果`" :bordered="false" v-if="openEdit">
        <a-space direction="vertical" style="width: 100%;">
          <!-- 编辑器 -->
          <byte-md-editor
            v-model:value="content"
            placeholder="请输入您的回复内容，图片请直接粘贴"
            :locale="zh_Hans"
            :plugins="plugins"
            height="300px"
            :editorConfig="{ lineNumbers: true }"
            contenteditable="true"
            @paste="onPaste"
          />
<!--          <ele-image-upload-->
<!--            v-model:value="files"-->
<!--            :limit="9"-->
<!--            :drag="true"-->
<!--            :multiple="true"-->
<!--            :upload-handler="uploadHandler"-->
<!--            @upload="onUpload"-->
<!--          />-->
          <a-upload
            v-model:file-list="fileList"
            class="upload-list-inline"
            list-type="picture"
            :before-upload="beforeUpload"
          >
            <a-button>
              <UploadOutlined />
              上传附件
            </a-button>
          </a-upload>
          <a-button type="primary" style="margin-top: 20px" @click="save">提交</a-button>
        </a-space>
      </a-card>
    </div>
    <!-- 成员管理 -->
    <div id="users">
      <a-card title="移交给" :bordered="false" v-if="openUsers">
            <a-space style="margin-bottom: 15px">
              <SelectStaff v-model:value="commander" @done="onSelect" />
              <a-button
                type="primary"
                class="ele-btn-icon"
                @click="onUpdateTask"
              >
                <template #icon>
                  <plus-outlined />
                </template>
                <span>确定</span>
              </a-button>
            </a-space>
      </a-card>
    </div>
  </a-drawer>
</template>

<script lang="ts" setup>
import "bytemd/dist/index.min.css";
import { createVNode, reactive, ref, watch, nextTick, computed } from "vue";
import "github-markdown-css/github-markdown-light.css";
// // 链接、删除线、复选框、表格等的插件
import gfm from "@bytemd/plugin-gfm";
// // 插件的中文语言文件
import zh_HansGfm from "@bytemd/plugin-gfm/locales/zh_Hans.json";
// 中文语言文件
import zh_Hans from "bytemd/locales/zh_Hans.json";
import "bytemd/dist/index.min.css";
import highlight from "@bytemd/plugin-highlight-ssr";
import "highlight.js/styles/default.css";
import { Form, message, Modal, UploadProps } from "ant-design-vue";
import { storeToRefs } from "pinia";
import { useThemeStore } from "@/store/modules/theme";
import { uploadFile } from "@/api/system/file";
import type { Task } from "@/api/oa/task/model";
import { updateTask, getTask } from "@/api/oa/task";
import { RuleObject } from "ant-design-vue/es/form";
import { FILE_SERVER } from "@/config/setting";
import { getDictionaryOptions, isImage, openUrl } from "@/utils/common";
import { TaskRecord } from "@/api/oa/task-record/model";
import { App } from "@/api/app/model"
import { ItemType } from "ele-admin-pro/es/ele-image-upload/types";
import { addTaskRecord, listTaskRecord, removeTaskRecord } from "@/api/oa/task-record";
import SelectStaff from '@/components/SelectStaff/index.vue';
import { UploadOutlined } from '@ant-design/icons-vue';
// 当前用户信息
import { useUserStore } from '@/store/modules/user';
import { Notice } from "@/api/oa/notice/model";
import { messageLoading, toTreeData } from "ele-admin-pro";
import { removeNotice } from "@/api/oa/notice";
import { Menu } from "@/api/system/menu/model";
import { getApp, getAppSecret } from "@/api/app";
import {
  PlusOutlined,
  EyeOutlined,
  EyeInvisibleOutlined,
  UserOutlined,
  ExclamationCircleOutlined
} from '@ant-design/icons-vue';

const props = defineProps<{
  // 弹窗是否打开
  visible: boolean;
  // 修改回显的数据
  data?: Task | null;
}>();

const emit = defineEmits<{
  (e: "done"): void;
  (e: "update:visible", visible: boolean): void;
}>();

/* 更新visible */
const updateVisible = (value: boolean) => {
  emit("update:visible", value);
};

// 插件
const plugins = ref([
  gfm({
    locale: zh_HansGfm
  }),
  highlight()
]);

// 表单数据
const form = reactive<TaskRecord>({
  taskRecordId: undefined,
  taskId: 0,
  content: '',
  files: "",
  userId: 0
});
const useForm = Form.useForm;
// 表单验证规则
const rules = reactive({
  content: [
    {
      required: true,
      type: "string",
      message: "请输入工单内容",
      trigger: "blur",
      validator: async (_rule: RuleObject, value: string) => {
        if (content.value == "") {
          return Promise.reject("请输入文字内容");
        }
        return Promise.resolve();
      }
    }
  ]
});
// 是否开启响应式布局
const themeStore = useThemeStore();
const { styleResponsive } = storeToRefs(themeStore);
const userStore = useUserStore();
const loginUser = computed(() => userStore.info ?? {});
// 请求状态
const loading = ref(true);
const detail = ref<Task | null>(null);
const appId = ref<number>(0);
const appInfo = ref<App | null>({});
const taskId = ref(0);
const parentId = ref<any>(0);
const replyName = ref<string>();
const activeKey = ref([]);
const showAppSecret = ref(false);
const taskProgressDict = getDictionaryOptions("taskProgress");
const record = ref<TaskRecord[] | undefined>([]);
const content = ref('');
const files = ref<ItemType[]>([]);
const fileList = ref<ItemType[]>([]);
const openEdit = ref(false);
const openUsers = ref(false);
const showAddUserForm = ref(false);
const developerId = ref();
const commander = ref<any>();
// 选中步骤
const active = ref(0);

const { resetFields, validate, validateInfos } = useForm(form, rules);

/* 图片上传事件 */
const uploadHandler = (file: File) => {
  const item: ItemType = {
    file,
    uid: (file as any).uid,
    name: file.name
  };
  if (!file.type.startsWith("image")) {
    message.error("只能选择图片");
    return;
  }
  if (file.size / 1024 / 1024 > 2) {
    message.error("大小不能超过 2MB");
    return;
  }
  onUpload(item);
};

// 文件上传事件
const beforeUpload = (file: File) => {
  const item: ItemType = {
    file,
    uid: (file as any).uid,
    name: file.name
  }
  if (!file.type.startsWith("image")) {
    if (file.size / 1024 / 1024 > 100) {
      message.error("大小不能超过 100MB");
      return;
    }
  }
  onUpload(item);
  return false;
};

const onUpload = (d: ItemType) => {
  uploadFile(<File>d.file)
    .then((result) => {
      files.value.push({
        uid: result.id,
        url: FILE_SERVER + result.path,
        name: isImage(result.path) ? 'image' : result.name,
        status: "done"
      });
      console.log(files.value);
      message.success("上传成功");
    })
    .catch((e) => {
      message.error(e.message);
    });
};

const complete = () => {
  Modal.confirm({
    title: "提示",
    content: "确定问题已解决？",
    icon: createVNode(ExclamationCircleOutlined),
    maskClosable: true,
    onOk: () => {
      updateTask({ taskId: taskId.value, progress: 3 }).then((res) => {
        message.success(res);
        updateVisible(false);
        emit("done");
      });
    }
  });
};

const closeTask = () => {
  Modal.confirm({
    title: "提示",
    content: "确定关闭工单吗？",
    icon: createVNode(ExclamationCircleOutlined),
    maskClosable: true,
    onOk: () => {
      updateTask({ taskId: taskId.value, status: 1, progress: 5 }).then((res) => {
        message.success(res);
        updateVisible(false);
        emit("done");
      });
    }
  });
}

const completedTask = () => {
  Modal.confirm({
    title: "提示",
    content: "确定工单已完接了吗？",
    icon: createVNode(ExclamationCircleOutlined),
    maskClosable: true,
    onOk: () => {
      updateTask({ taskId: taskId.value, status: 1, progress: 4 }).then((res) => {
        message.success(res);
        updateVisible(false);
        emit("done");
      });
    }
  });
}

const openTask = () => {
  Modal.confirm({
    title: "提示",
    content: "重新开启后可以继续追加内容，需要重新开启工单吗？",
    icon: createVNode(ExclamationCircleOutlined),
    maskClosable: true,
    onOk: () => {
      updateTask({ taskId: taskId.value, status: 0, progress: 2 }).then((res) => {
        message.success(res);
        updateVisible(false);
        emit("done");
      });
    }
  });
}

const showEdit = () => {
  replyName.value = '';
  parentId.value = 0;
  openEdit.value = true;
  openUsers.value = false;
};
const showUsers = () => {
  openUsers.value = true;
  openEdit.value = false;
}

const onReply = (row: TaskRecord) => {
  parentId.value = row.taskRecordId;
  replyName.value = row.nickname;
  openEdit.value = true;
}

/* 删除单个 */
const remove = (row: TaskRecord) => {
  removeTaskRecord(row.taskRecordId)
    .then((msg) => {
      message.success(msg);
      // 加载工单明细
      reload();
    })
    .catch((e) => {
      message.error(e.message);
    });
};

// 指派工单
const onUpdateTask = () => {
  updateTask({
    commander: commander.value,
    taskId: taskId.value,
    progress: 1
  }).then(() => {
    message.success("操作成功");
    updateVisible(false);
    emit('done');
  }).catch(err => {
    message.error(err.message)
  })
};

// 选择用户
const onSelect = (userId) => {
  commander.value = userId;
};

/* 保存编辑 */
const save = () => {
  if(content.value == ''){
    message.error('请填写回复内容！');
    return false;
  }
  validate()
    .then(() => {
      loading.value = true;
      const data = {
        ...form,
        taskId: taskId.value,
        parentId: parentId.value,
        // 处理工单内容
        content: content.value,
        files: JSON.stringify(files.value)
      };
      // 转字符串
      addTaskRecord(data)
        .then((msg) => {
          loading.value = false;
          message.success(msg);
          files.value = [];
          content.value = '';
          fileList.value = [];
          // 加载工单明细
          reload();
        })
        .catch((e) => {
          loading.value = false;
          message.error(e.message);
        });
    })
    .catch(() => {
    });
};

const onClose = () => {
  emit("done");
}

/* 粘贴图片上传服务器并插入编辑器 */
const onPaste = (e) => {
  const items = (e.clipboardData || e.originalEvent.clipboardData).items;
  let hasFile = false;
  for (let i = 0; i < items.length; i++) {
    if (items[i].type.indexOf('image') !== -1) {
      let file = items[i].getAsFile();
      const item: ItemType = {
        file,
        uid: (file as any).lastModified,
        name: file.name
      };
      uploadFile(<File>item.file)
        .then((result) => {
          const addPath = '!['+result.name+']('+FILE_SERVER + result.path+')\n\r';
          content.value = content.value + addPath
        })
        .catch((e) => {
          message.error(e.message);
        });
      hasFile = true;
    }
  }
  if (hasFile) {
    e.preventDefault();
  }
}

const reload = () => {
  // 加载工单明细
  listTaskRecord({ taskId: taskId.value }).then((data) => {
    record.value = toTreeData({
      data: data.map((d) => {
        return { ...d, key: d.taskRecordId, value: d.taskRecordId };
      }),
      idField: 'taskRecordId',
      parentIdField: 'parentId'
    });
    loading.value = false;
  });
  // 加载应用信息
  if (appId.value) {
    getApp(appId.value).then(result => {
      appInfo.value = result;
    })
  }
}

// 查看秘钥
const onAppSecret = (appId) => {
  getAppSecret({ appId }).then((res) => {
    showAppSecret.value = !showAppSecret.value;
  });
};

watch(
  () => props.visible,
  (visible) => {
    if (visible) {
      if (props.data) {
        detail.value = props.data;
        appId.value = Number(props.data.appId);
        active.value = Number(props.data.progress);
        taskId.value = Number(props.data.taskId);
        commander.value = props.data.commanderName;
        reload();
      }
    } else {
      resetFields();
    }
  }
);
</script>
<script lang="ts">
export default {
  name: "TaskDetailContent"
};
</script>
<style lang="less" scoped>
.content {
  background-color: #ffffff;
  padding: 10px 0;
  min-height: 40px;
  max-width: 80%;
  overflow: hidden;
  .edit-md {
    margin-top: 30px;
  }
}

.screenshot {
  margin: auto !important;
}

.task-card {
  background-color: var(--body-background);
  margin-bottom: 20px;
  //margin: 20px auto;

  .comment {
  }
}

.task-btn {
  display: flex;
  justify-content: center;
  margin: 20px;
}
.ant-page-header{
  padding: 0 !important;
}
.replay-bg{
  //box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
}
.upload-list-inline :deep(.ant-upload-list-item) {
  float: left;
  width: 200px;
  margin-right: 8px;
}
.upload-list-inline [class*='-upload-list-rtl'] :deep(.ant-upload-list-item) {
  float: right;
}
/* 应用详情字段列表 */
.app-item-list {
  & > .ele-cell {
    padding: 16px 8px;
    .ele-cell-content {
      .ele-cell-desc {
        margin-bottom: 15px;
      }
      .ele-cell-title {
        max-width: 900px;
      }
    }
  }

  .app-item-icon {
    color: #fff;
    padding: 8px;
    font-size: 26px;
    border-radius: 50%;

    &.anticon-qq {
      background: #3492ed;
    }

    &.anticon-wechat {
      background: #4daf29;
    }

    &.anticon-alipay {
      background: #1476fe;
    }
  }
}
</style>
