<template>
  <a-page-header
    :title="title"
    :style="{ padding: screenWidth > 480 ? '16px 24px' : '0' }"
    @back="push('/oa/task')"
  >
    <a-row :gutter="16">
      <!--      左侧区域-->
      <a-col
        v-bind="
          styleResponsive
            ? { xl: 18, lg: 12, md: 12, sm: 24, xs: 24 }
            : { span: 12 }
        "
        class="gutter-row"
        :span="6"
      >
        <a-card :bordered="false" style="width: 100%; margin-bottom: 16px;" v-if="screenWidth > 480">
          <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-card :bordered="false" :class="screenWidth > 480 ? '' : 'transparent-bg'" style="width: 100%; margin-bottom: 16px" :body-style="{ padding: screenWidth > 480 ? '16px' : '0' }">
          <a-list item-layout="vertical" size="large" :data-source="taskRecord">
            <template #renderItem="{ item,index }">
              <a-list-item key="item.taskRecordId">
                <a-list-item-meta>
                  <template #title>
                    <a-space>
                      <a class="ele-text-heading" style="font-weight: 500;" v-if="item.userId == loginUserId">{{ item.nickname }}</a>
                      <a class="ele-text-heading" style="font-weight: 500;" v-else>{{ item.nickname }}</a>
                      <div class="ele-text-placeholder" style="font-size: 14px" >{{ timeAgo(item.createTime) }}</div>
                    </a-space>
                  </template>
                  <template #avatar><a-avatar :src="item.avatar ? item.avatar : 'https://file.gxwebsoft.com/20230217/c8a5c699b3174866a36dd6d378a09bb9.jpg'" /></template>
                  <template #description>
                    <a-card class="user-content" v-if="loginUserId === item.userId" :style="{maxWidth: screenWidth > 480 ? '80%' : '100%'}" :body-style="{ padding: '12px' }">
                      <byte-md-viewer :value="item.content" :plugins="plugins" />
                    </a-card>
                    <a-card class="admin-content" :style="{maxWidth: screenWidth > 480 ? '80%' : '100%'}" v-else :body-style="{ padding: '12px' }">
                      <byte-md-viewer :value="item.content" :plugins="plugins" />
                    </a-card>
                    <a-space class="files" v-if="item.confidential">
                      <a-alert
                        :message="`${hasRole('commander') ? decrypt(item.confidential) : '机密信息：****'}`"
                        type="warning"
                        :showIcon = false
                        banner
                      >
                      </a-alert>
                    </a-space>
                    <a-space class="files" 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 :width="80" :src="file.url" />
                      </template>
                    </a-space>
                    <template v-if="hasRole('admin') || hasRole('superAdmin') || (hasRole('commander') && item.userId == user.info?.userId)">
                      <template v-if="active != COMPLETED && active != CLOSED">
                        <div style="margin: 10px 0;">
                          <a class="ele-text-placeholder" @click="openEditRecord(item)">编辑</a>
                          <a-divider type="vertical" />
                          <a-popconfirm
                            title="确定要删除此记录吗？"
                            @confirm="removeRecord(item)"
                          >
                            <a class="ele-text-placeholder">删除</a>
                          </a-popconfirm>
                        </div>
                      </template>
                    </template>
                  </template>
                </a-list-item-meta>
              </a-list-item>
            </template>
            <template #loadMore>
              <div
                v-if="total > 100"
                :style="{
                  textAlign: 'center',
                  marginTop: '12px',
                  height: '32px',
                  lineHeight: '32px'
                }"
              >
                <a-pagination v-model:current="current" :total="total" @change="reload" />
              </div>
            </template>
          </a-list>
        </a-card>
        <!-- 回复表单 -->
        <div id="bottom" v-if="task">
          <a-form
            ref="formRef"
            :model="form"
            :label-col="{ md: { span: 7 }, sm: { span: 4 }, xs: { span: 24 } }"
            :wrapper-col="{ md: { span: 14 }, sm: { span: 24 }, xs: { span: 24 } }"
            layout="vertical"
          >
          <a-card
            :title="currentRecord ? `正在回复${currentRecord.nickname}:` : `处理结果`"
            :class="screenWidth > 480 ? '' : 'transparent-bg'"
            :bordered="false"
            v-if="hasRole('superAdmin') || hasRole('admin') || task.status == 0"
          >
            <template #extra>
              <a-space>
                <template v-if="hasRole('admin') || hasRole('superAdmin')">
                  <template v-if="active == CLOSED || active == COMPLETED">
                    <a-button @click="onClose">重开</a-button>
                  </template>
                  <template v-else>
                    <a-space>
                      <a-button @click="openUser">派单</a-button>
                      <a-button @click="onResolved">已解决</a-button>
                      <a-button @click="onClose">关单</a-button>
                      <a-button @click="openEdit">编辑</a-button>
                      <a-button @click="remove">删除</a-button>
                    </a-space>
                  </template>
                </template>
                <template v-if="hasRole('commander')">
                  <a-button @click="onResolved" :v-if="commander != loginUserId">已解决</a-button>
                  <a-button @click="onClose">{{ taskStatus ? '关单' : '重开' }}</a-button>
                </template>
                <template v-if="hasRole('promoter') || hasRole('user')">
                  <a-button @click="onConfirmCompleted" v-if="active != CLOSED && active != COMPLETED">确认完成</a-button>
                  <a-button @click="onClose" v-if="active != CLOSED && active != COMPLETED">关闭</a-button>
                </template>
                <a-button @click="openAppInfo(appId)" v-if="appId > 0">相关信息</a-button>
                <a-button @click="openQrcode">分享</a-button>
              </a-space>
            </template>
            <a-space direction="vertical" style="width: 100%">
              <!-- 编辑器 -->
              <byte-md-editor
                v-model:value="content"
                placeholder="请输入您的回复内容，图片请直接粘贴"
                :locale="zh_Hans"
                :plugins="plugins"
                mode="tab"
                height="300px"
                maxLength="500"
                :editorConfig="{ lineNumbers: true }"
                contenteditable="true"
                @paste="onPaste"
              />
              <a-row :gutter="16">
                <a-col
                  v-bind="styleResponsive ? { md: 24, sm: 12, xs: 24 } : { span: 8 }"
                >
                  <a-form-item label="机密信息（选填）" name="confidential">
                    <a-textarea :rows="3" v-model:value="confidential" placeholder="请在此处填写项目名、账号、密码等机密信息，提交后机密信息将做加密处理"></a-textarea>
                  </a-form-item>
                </a-col>
                <a-col
                  v-bind="styleResponsive ? { md: 12, sm: 12, xs: 24 } : { span: 8 }"
                >
                  <a-form-item label="上传附件（选填）" name="files">
                    <a-upload
                      v-model:file-list="fileList"
                      class="upload-list-inline"
                      list-type="picture"
                      :before-upload="onBeforeUpload"
                    >
                      <a-button>
                        <UploadOutlined />
                        上传附件
                      </a-button>
                    </a-upload>
                  </a-form-item>
                </a-col>
              </a-row>
              <div class="submit-btn">
                <a-button type="primary" size="large" block @click="save"
                >提交</a-button
                >
              </div>
            </a-space>
          </a-card>
          </a-form>
        </div>
      </a-col>
      <!--      右侧区域-->
      <a-col
        v-bind="
          styleResponsive
            ? { xl: 6, lg: 12, md: 12, sm: 24, xs: 24 }
            : { span: 12 }
        "
        class="gutter-row"
        :span="6"
        v-if="screenWidth > 500"
      >
        <Tools :appId="appId" />
        <Help />
        <Links />
      </a-col>
    </a-row>
    <!-- 指派人员 -->
    <Assign v-model:visible="showUser" @done="doneUser" />
    <!-- 工单二维码 -->
    <TaskQrcode v-model:visible="showQrcode" :data="task" @done="doneQrcode"/>
    <!-- 项目信息 -->
    <AppInfo v-model:visible="showAppInfo" :appId="appId" @done="doneQrcode"/>
    <!-- 编辑弹窗 -->
    <TaskEdit v-model:visible="showEdit" :data="task" @done="reload"/>
    <!-- 编辑弹窗 -->
    <TaskRecordEdit v-model:visible="showEditRecord" :data="currentRecord" @done="reload"/>
  </a-page-header>
</template>

<script lang="ts" setup>
import { createVNode, ref, unref, watch } from "vue";
import {
  StarOutlined,
  LikeOutlined,
  MessageOutlined, ExclamationCircleOutlined
} from "@ant-design/icons-vue";
  import 'bytemd/dist/index.min.css';
  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 { useRouter } from 'vue-router';
import { getTask, removeTask, updateTask } from "@/api/oa/task";
  import useFormData from '@/utils/use-form-data';
  import { useThemeStore } from '@/store/modules/theme';
  import { storeToRefs } from 'pinia';
  import { decrypt, encrypt, getVersion, isImage, openUrl } from "@/utils/common";
  import { Article } from '@/api/cms/article/model';
  import { TaskRecord } from '@/api/oa/task-record/model';
  import { addTaskRecord, pageTaskRecord, removeTaskRecord } from "@/api/oa/task-record";
  import { ItemType } from "ele-admin-pro/es/ele-image-upload/types";
  import { uploadOss } from "@/api/system/file";
  import { message, Modal } from "ant-design-vue";
  import { timeAgo } from "ele-admin-pro";
  import { toTreeData } from "ele-admin-pro/es";
  import { useParamsStore } from "@/store/modules/params";
  import Assign from './components/assign.vue'
  import AppInfo from './components/app-info.vue';
  import TaskEdit from './components/task-edit.vue';
  import TaskRecordEdit from './components/task-record-edit.vue';
  import TaskQrcode from './components/task-qrcode.vue'
  import Links from './components/links.vue'
  import Help from './components/Help.vue'
  import { Task } from "@/api/oa/task/model";
  import { CLOSED, COMPLETED, PENDING, PROCESSING, TOBEARRANGED, TOBECONFIRMED } from "@/api/oa/task/model/progress";
  import { useUserStore } from "@/store/modules/user";
  import Tools from "@/views/oa/task/components/tools.vue";
  import { ACTION_1, ACTION_2, ACTION_3, TASK_STATUS_1 } from "@/api/oa/task/model/task";
  import { hasRole } from "@/utils/permission";
  import {setPageTabTitle} from "@/utils/page-tab-util";
import {User} from "@/api/system/user/model";
  const ROUTE_PATH = '/oa/task/detail';

  const { currentRoute } = useRouter();
  // 选中步骤
  const active = ref(0);
  const { push } = useRouter();
  // 是否开启响应式布局
  const themeStore = useThemeStore();
  const param = useParamsStore();
  const user = useUserStore();
  const { styleResponsive, screenWidth } = storeToRefs(themeStore);
  const title = ref('');
  const version = ref<number>(0);
  const taskProgressDict = [{ label: "待分派", value: TOBEARRANGED },{ label: "待处理", value: PENDING },{ label: "处理中", value: PROCESSING },{ label: "待评价", value: TOBECONFIRMED },{ label: "已完成", value: COMPLETED },{ label: "已关闭", value: CLOSED }];
  const articleList = ref<Article[]>([]);
  const taskId = ref<Number>(0);
  const appId = ref<Number>(0);
  const loginUserId = ref(0);
  const commander = ref(0);
  const taskRecord = ref<TaskRecord[]>([]);
  const current = ref(1);
  const total = ref();
  const content = ref('');
  const confidential = ref<string>('');
  const currentRecord = ref<TaskRecord | any>();
  const taskStatus = ref(true);
  const loading = ref(false);
  const showUser = ref(false);
  const showQrcode = ref(false);
  const showAppInfo = ref(false);
  const showEdit = ref(false);
  const showEditRecord = ref(false);
  const fileList = ref<any[]>([]);
  const files = ref<any[]>([]);
  const task = ref<Task | any>();

  // 用户信息
  const { form, assignFields, resetFields } = useFormData<TaskRecord>({
    children: [],
    content: "",
    developerId: 0,
    files: "",
    parentId: 0,
    sortNumber: 0,
    status: "",
    toUser: {},
    userId: 0,
    taskRecordId: 0,
    taskId: 0,
    appId: 0,
    nickname: undefined,
    avatar: '',
    comments: ''
  });

  const actions: Record<string, any>[] = [
    { icon: StarOutlined, text: '156' },
    { icon: LikeOutlined, text: '156' },
    { icon: MessageOutlined, text: '回复' }
  ];

  const onReply = (item: TaskRecord) => {
    currentRecord.value = item;
    form.parentId = item.userId;
  }

  const openUser = () => {
    showUser.value = true;
  }

  const openAppInfo = (id:number) => {
    openUrl('/oa/app/detail/' + id)
    // showAppInfo.value = true;
  }

  const openQrcode = () => {
    showQrcode.value = true;
  }

  const openEdit = () => {
    showEdit.value = true;
  }

  /* 打开编辑弹窗 */
  const openEditRecord = (row?: TaskRecord) => {
    currentRecord.value = row ?? null;
    showEditRecord.value = true;
  };

  /* 删除单个 */
  const remove = () => {
    Modal.confirm({
      title: '操作提示',
      content: '确定要删除吗？',
      icon: createVNode(ExclamationCircleOutlined),
      maskClosable: true,
      onOk: () => {
        const hide = message.loading('请求中..', 0);
        removeTask(form.taskId)
          .then((msg) => {
            hide();
            message.success(msg);
            push('/oa/task')
          })
          .catch((e) => {
            hide();
            message.error(e.message);
          });
      }
    });
  };

  const removeRecord = (item) => {
    removeTaskRecord(item.taskRecordId)
      .then((msg) => {
        message.success(msg);
        reload();
      })
      .catch((e) => {
        message.error(e.message);
      });
  };

  /**
   * 指派人员
   * 状态变为：待处理
   * @param item
   */
  const doneUser = async (item: User) => {
    form.toUser = item
    const msg = await updateTask({ taskId: form.taskId, progress: PENDING, commander: item.userId, action: ACTION_1 })
    if(msg){
      active.value = PENDING
      const data: any = {
        taskId: form.taskId,
        content: `已指派给${item.nickname}(工号：${item.userId})`
      }
      await addTaskRecord(data)
      showUser.value = false;
      reload();
    }
  }

  /**
   * 工单二维码
   * @param item
   */
  const doneQrcode = async (item: Task) => {

  }

  /**
   * 技术人员已处理完
   * 状态变为：待评价
   */
  const onResolved = async () => {
    Modal.confirm({
      title: '操作提示',
      content: '请回复处理结果！确定要变更状态为已处理吗？',
      icon: createVNode(ExclamationCircleOutlined),
      maskClosable: true,
      onOk: () => {
        const hide = message.loading('请求中..', 0);
        const msg = updateTask({ taskId: form.taskId, progress: TOBECONFIRMED, status: TASK_STATUS_1, action: ACTION_2 }).then(async res => {
          const data: any = {
            taskId: form.taskId,
            content: '问题已处理,请查看并确认'
          }
          await addTaskRecord(data)
          setTimeout(() => {
            hide();
            active.value = TOBECONFIRMED;
            message.success("问题已处理，请查看并确认");
            push('/oa/task')
          }, 300)
        })
      }
    });
  }

  /**
   * 确认已完成
   */
  const onConfirmCompleted = () => {
    Modal.confirm({
      title: '操作提示',
      content: '感谢您的支持！请给技术人员评价！',
      icon: createVNode(ExclamationCircleOutlined),
      maskClosable: true,
      onOk: () => {
        updateTask({taskId: form.taskId,status: TASK_STATUS_1, progress: COMPLETED}).then(() => {
          message.success("操作成功");
          push('/oa/task')
        })
      }
    });

  }

  /**
   * 关闭工单
   */
  const onClose = () => {
    Modal.confirm({
      title: '操作提示',
      content: '确定要操作吗？',
      icon: createVNode(ExclamationCircleOutlined),
      maskClosable: true,
      onOk: () => {
        const hide = message.loading('请求中..', 0);
        const taskId = form.taskId
        const action = ACTION_3;
        // 关闭
        let status = 1;
        let progress = CLOSED;
        active.value = CLOSED;
        // 重开
        if(!taskStatus.value){
          status = 0;
          progress = PROCESSING;
          active.value = TOBECONFIRMED;
        }
        const msg = updateTask({ taskId, progress, status, action }).then(res => {
          setTimeout(() => {
            hide();
            message.success("操作成功");
            if (taskStatus.value) {
              push('/oa/task')
            }else {
              reload();
            }
          },300)
        })
      }
    });
  }

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

// 文件上传事件
const onBeforeUpload = (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) => {
  uploadOss(<File>d.file)
    .then((result) => {
      files.value.push({
        uid: result.id,
        url: result.path,
        name: isImage(result.path) ? 'image' : result.name,
        status: "done"
      });
      message.success("上传成功");
    })
    .catch((e) => {
      message.error(e.message);
    });
};

  /* 粘贴图片上传服务器并插入编辑器 */
  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
        };
        uploadOss(<File>item.file)
          .then((result) => {
            const addPath = '!['+result.name+']('+ result.url+')\n\r';
            content.value = content.value + addPath
          })
          .catch((e) => {
            message.error(e.message);
          });
        hasFile = true;
      }
    }
    if (hasFile) {
      e.preventDefault();
    }
  }

  /* 保存编辑 */
  const save = () => {
    // 检查是否填写内容
    if (content.value == '') {
      message.error('请填写内容')
      return false;
    }
    loading.value = true;
    const data = {
      ...form,
      content: content.value,
      taskId: form.taskId,
      parentId: currentRecord.value?.taskRecordId,
      files: JSON.stringify(files.value),
      confidential: encrypt(confidential.value)
    };
    // 加密信息处理
    if(confidential.value != ''){
      data.confidential = encrypt(confidential.value)
    }else {
      data.confidential = undefined
    }
    addTaskRecord(data)
      .then((msg) => {
        loading.value = false;
        content.value = '';
        fileList.value = [];
        files.value = [];
        confidential.value = '';
        message.success('回复成功')
        reload();
      })
      .catch((e) => {
        loading.value = false;
        message.error(e.message);
      });
  };

  /**
   * 加载数据
   */
  const reload = () => {
    version.value = <number>getVersion();
    if (form.taskId) {
      const taskId = form.taskId;
      getTask(taskId).then((data) => {
        task.value = data;
        commander.value = Number(data.commander);
        active.value = Number(data.progress);
        appId.value = Number(data.appId);
        form.appId = Number(data.appId);
        title.value = `【${taskId}】${data.name}`
        setPageTabTitle(`${data.name}`)
        // 兼容小屏幕
        if (screenWidth.value < 480) {
          title.value = `工单号：${taskId}`
        }
        if(data.progress == CLOSED){
          taskStatus.value = false;
        }else{
          taskStatus.value = true;
        }
      });
      pageTaskRecord({ taskId ,page: current.value, limit: 100}).then((res) => {
        taskRecord.value = toTreeData({
          data: res?.list.map((d) => {
            return { ...d, key: d.taskRecordId, value: d.taskRecordId };
          }),
          idField: 'taskRecordId',
          parentIdField: 'parentId'
        });
        total.value = res?.count;
      });
    }
    if(user.info){
      const { userId } = user?.info
      loginUserId.value = Number(userId);
    }
  };

  watch(
    currentRoute,
    (route) => {
      const { params } = unref(route);
      const { id } = params;
      if (id) {
        form.taskId = Number(id);
        reload();
      }
    },
    { immediate: true }
  );
</script>

<script lang="ts">
  export default {
    name: 'TaskDetail'
  };
</script>

<style lang="less" scoped>
  .task-card {
    padding: 2px !important;
    margin-bottom: 16px;
  }
  .user-content {
    max-width: 100%;
    border-radius: 8px !important;
    background-color: #a2ec71;
    border: none;
  }
  .admin-content {
    border-radius: 8px !important;
    border: 3px solid #f1f1f1;
  }
  /deep/.markdown-body{
    background-color: transparent; /* 设置背景透明 */
  }
  /deep/.markdown-body img {
    max-width: 360px;
  }
  .files{
    margin-top: 10px;
  }
  #bottom{
    margin-bottom: 20px;
  }
  .transparent-bg{
    background-color: transparent; /* 设置背景透明 */
  }
  .submit-btn{
    margin: auto;
  }
</style>
