import { computed, onMounted, ref } from "vue";
import { ElMessage, ElMessageBox } from "element-plus";
import { api } from "@/api/doc";
import { PermCode } from "@/utils/perm";
import {
  type ButtonsCallBackParams,
  type PlusColumn,
  useTable
} from "plus-pro-components";
import { YesOrNoEnum } from "@/model/enums";
import { hasPerms } from "@/utils/auth";

export function useDocList() {
  const tabsData = ref<Array<any>>([
    {
      id: "",
      appName: ""
    }
  ]);

  const activeName = ref(0);
  const docAppId = ref(0);
  const loading = ref(false);

  // 表格对象
  const { tableData, buttons: actionButtons } = useTable<any[]>();

  const filterText = ref("");

  const tableRows = computed(() => {
    let search = filterText.value;
    if (!search) {
      return tableData.value;
    }
    search = search.toLowerCase();
    return searchRow(search, tableData.value, searchContent, isFolder);
  });

  const isFolder = row => {
    return row.isFolder === 1;
  };

  const searchContent = (searchText, row) => {
    return (
      (row.docName && row.docName.toLowerCase().indexOf(searchText) > -1) ||
      (row.docTitle && row.docTitle.toLowerCase().indexOf(searchText) > -1)
    );
  };

  // 按钮权限code
  const btnCode = PermCode.doc;
  // 表格字段定义
  const tableColumns: PlusColumn[] = [
    {
      label: "文档标题",
      prop: "docTitle"
    },
    {
      label: "接口名",
      prop: "docName"
    },
    {
      label: "版本号",
      prop: "docVersion",
      width: 80
    },
    {
      label: "描述",
      prop: "description"
    },
    {
      label: "发布状态",
      prop: "isPublish",
      valueType: "select",
      width: 100,
      options: [
        {
          label: "已发布",
          value: YesOrNoEnum.YES,
          color: "green"
        },
        {
          label: "未发布",
          value: YesOrNoEnum.NO,
          color: "red"
        }
      ],
      renderHTML: (value, { row }) => {
        if (row.isFolder) {
          return "";
        }
        return value
          ? `<div style="color:green;">已发布</div>`
          : `<div style="color:gray;">未发布</div>`;
      }
    },
    {
      width: 100,
      label: "添加人",
      prop: "addBy.showName"
    },
    {
      width: 100,
      label: "修改人",
      prop: "updateBy.showName"
    },
    {
      width: 120,
      label: "添加时间",
      prop: "addTime"
    },
    {
      width: 120,
      label: "修改时间",
      prop: "updateTime"
    }
  ];
  // 表格按钮定义
  actionButtons.value = [
    {
      text: "发布",
      confirm: {
        options: { draggable: false },
        popconfirmProps: { width: 300 },
        message: params => {
          const row = params.row;
          return `确定要发布[${row.docTitle}]下所有接口吗？`;
        }
      },
      props: (_: any) => ({
        type: "success"
      }),
      onConfirm(params: ButtonsCallBackParams) {
        const data = {
          id: params.row.id,
          isPublish: 1
        };
        api.publish(data).then(() => {
          ElMessage.success("保存成功");
          search();
        });
      },
      show: (row: any) => hasPerms(btnCode.publish) && row.isFolder === 1
    },
    {
      text: "下线",
      confirm: {
        options: { draggable: false },
        popconfirmProps: { width: 300 },
        message: params => {
          const row = params.row;
          const opt = "下线";
          return `确定要${opt}[${row.docTitle}]下所有接口吗？`;
        }
      },
      props: {
        type: "danger"
      },
      onConfirm(params: ButtonsCallBackParams) {
        const data = {
          id: params.row.id,
          isPublish: 0
        };
        api.publish(data).then(() => {
          ElMessage.success("下线成功");
          search();
        });
      },
      show: (row: any) => hasPerms(btnCode.offline) && row.isFolder === 1
    },
    {
      text: row => (row.isPublish ? "下线" : "发布"),
      confirm: {
        options: { draggable: false },
        popconfirmProps: { width: 300 },
        message: params => {
          const row = params.row;
          const opt = row.isPublish ? "下线" : "发布";
          return `确定要${opt}[${row.docTitle}]吗？`;
        }
      },
      props: (row: any) => ({
        type: row.isPublish === 1 ? "danger" : "success"
      }),
      onConfirm(params: ButtonsCallBackParams) {
        const data = {
          id: params.row.id,
          isPublish: params.row.isPublish === 1 ? 0 : 1
        };
        api.publish(data).then(() => {
          ElMessage.success("保存成功");
          search();
        });
      },
      show: (row: any) => {
        const perm = row.isPublish ? btnCode.offline : btnCode.publish;
        return hasPerms(perm) && row.isFolder === 0;
      }
    },
    {
      text: "同步",
      confirm: {
        options: { draggable: false },
        popconfirmProps: { width: 300 },
        message: params => {
          const row = params.row;
          return row.isFolder
            ? `确定要同步[${row.docTitle}]下所有接口吗？`
            : `确定要同步[${row.docTitle}]吗？`;
        }
      },
      props: (_: any) => ({
        type: "primary"
      }),
      onConfirm(params: ButtonsCallBackParams) {
        loading.value = true;
        api
          .syncDoc(params.row.id)
          .then(() => {
            loading.value = false;
            ElMessage.success("同步成功");
            search();
          })
          .catch(() => {
            loading.value = false;
          });
      },
      show: () => hasPerms(btnCode.sync)
    }
  ];

  // 点击查询按钮
  const handleSearch = () => {
    search();
  };

  // 查询
  const search = async () => {
    loadContent(docAppId.value);
  };

  function handleSyncApi() {
    ElMessageBox.confirm("确定要同步远程接口吗?", "提示", {
      confirmButtonText: "确定",
      cancelButtonText: "取消",
      type: "warning"
    })
      .then(() => {
        loading.value = true;
        api
          .syncAppDoc(docAppId.value)
          .then(() => {
            loading.value = false;
            ElMessage.success("同步成功");
            search();
          })
          .catch(() => {
            loading.value = false;
          });
      })
      .catch(() => {});
  }

  const handleClick = data => {
    const id = data.props.name;
    activeTab(id);
  };

  const activeTab = id => {
    docAppId.value = id;
    loadContent(id);
  };

  const handleAddApp = () => {
    ElMessageBox.prompt("请输入Torna应用token", "添加应用", {
      confirmButtonText: "确定",
      cancelButtonText: "取消",
      inputPattern: /\w+/,
      inputErrorMessage: "请输入Torna应用token"
    })
      .then(({ value }) => {
        const data = {
          tornaToken: value
        };
        api.addApp(data).then(resp => {
          ElMessage.success("添加成功");
          loadTabs(resp.data);
        });
      })
      .catch(() => {});
  };

  const loadTabs = docAppId => {
    api.listApp().then(resp => {
      tabsData.value = resp.data;
      const length = tabsData.value.length;
      if (length > 0) {
        let targetId;
        for (const id of tabsData.value) {
          if (id === docAppId) {
            targetId = id;
            break;
          }
        }
        if (!targetId) {
          targetId = tabsData.value[0].id;
        }
        activeName.value = targetId;
        activeTab(targetId);
      }
    });
  };

  const searchRow = (search, rows, searchHandler, folderHandler) => {
    if (!folderHandler) {
      folderHandler = isFolder;
    }
    const ret = [];
    for (const row of rows) {
      // 找到分类
      if (folderHandler(row)) {
        if (searchHandler(search, row)) {
          ret.push(row);
        } else {
          // 分类名字没找到，需要从子文档中找
          const children = row.children || [];
          const searchedChildren = searchRow(
            search,
            children,
            searchHandler,
            folderHandler
          );
          // 如果子文档中有
          if (searchedChildren && searchedChildren.length > 0) {
            const rowCopy = Object.assign({}, row);
            rowCopy.children = searchedChildren;
            ret.push(rowCopy);
          }
        }
      } else {
        // 不是分类且被找到
        if (searchHandler(search, row)) {
          ret.push(row);
        }
      }
    }
    return ret;
  };

  const loadContent = id => {
    const data = {
      docAppId: id
    };
    api.listDocTree(data).then(resp => {
      tableData.value = resp.data;
    });
  };

  onMounted(() => {
    loadTabs(0);
  });

  return {
    activeName,
    handleClick,
    handleAddApp,
    handleSyncApi,
    tabsData,
    actionButtons,
    tableColumns,
    tableRows,
    filterText,
    loading,
    handleSearch
  };
}
