<script lang="ts" setup>
import { ref, onMounted, reactive, watch, inject } from "vue";
import { useRouter, useRoute } from 'vue-router'
import { post, get } from "@/utils/request";
import { GET_STRUCT_BY_TABLE_NAME, ADD_OR_UPDATE_REPORT_FORM } from "../api"
import { generateSql, rangeGetSql } from "../function"
import { ElMessage, ElMessageBox } from 'element-plus'

import { VueDraggable } from 'vue-draggable-plus'

import rangeFilter from "./rangeFilter.vue";
import previewTable from "./previewTable.vue";
import { confirmAction } from "@/utils/tools";

interface collapseItemList {
  busObject: any,
  columnList: any[],
}

interface CollapseItem {
  data: {
    label: string;
  };
  list: collapseItemList;
}

const globalPopup = inject<GlobalPopup>('globalPopup')
const router = useRouter()
const route = useRoute()
const reportName = ref('')
const addEditData = JSON.parse(sessionStorage.getItem('reportJson') || '{}')
const activeNames = ref([])
const collapseList = ref<CollapseItem[]>([])

// 拖拽表格参数
const tableData = ref<any>([]);
const tableColumns = ref<any>([{}, {}, {}]);

// 全部Loading的Visable
const allLoading = reactive({
  collapseListLoading: false,
  saveLoading: false
})
const allVisable = reactive({
  previewTableVisable: false
})

// ref
const rangeFilterRef = ref<InstanceType<typeof rangeFilter> | null>(null);
const previewTableRef = ref<InstanceType<typeof previewTable> | null>(null);

// 保存预览的判断以及生成
function preMethod(): any {
  const rangeFilterData = rangeFilterRef.value?.getRangeData()
  if(!tableData.value.length) {
    ElMessage.warning('请选择列')
    return
  }
  if(rangeFilterData.length) {
    for(let i in rangeFilterData) {
      if(!rangeFilterData[i].twoDisable && !rangeFilterData[i].filterValueTwo) {
        ElMessage.warning('请选择第二个条件')
        return
      }
    }
  }

  const tabeName = tableData.value.map((item: any) => item.tableName)
  const tableNames = addEditData.mindMapJSON.selectNodes[0].data.tblName
  if(!tabeName.includes(tableNames)) {
    ElMessage.warning('请选择主表数据')
    return
  }

  const list = rangeFilterData.filter((item: any) => item.filterValueThree)
  const SQL = generateSql(tableData.value, rangeFilterData, addEditData)
  const rangeSQL = rangeGetSql(rangeFilterData, addEditData)
  const finalSql = `${SQL} ${list.length ? rangeSQL : 'where 1=1'}`

  return {
    finalSql,
    formTransConditionJson: '',
  }
}

// 保存页面
function saveReport() {
  const rangeFilterData = rangeFilterRef.value?.getRangeData()
  
  const { finalSql } = preMethod()

  // 需要转存的 JSON
  const formJson = {
    addEditData,
    tableData: tableData.value,
    rangeFilterData: rangeFilterData,
  }

  const formFieldHead = tableData.value.map((item: any) => {
    return {
      tableName: item.tableName,
      columnName: item.columnName,
      columnVal: item.columnComment
    }
  })

  const { reportFormName, description, userAccessList = [], visibleRangeData = [], parentStoreId, privilege, id } = addEditData.addFormVal

  const formVal: any = {
    reportFormName,
    description,
    parentStoreId: parentStoreId ? parentStoreId : 0,
    privilege: privilege ? 1 : 2,
    executeSql: finalSql,
    userIds: visibleRangeData.filter((item: any) => item.isUser).map((item: any) => item.id).join(','),
    departmentIds: visibleRangeData.filter((item: any) => !item.isUser).map((item: any) => item.id).join(','),
    formJson: JSON.stringify(formJson),
    formFieldHead: JSON.stringify(formFieldHead),
  }

  if(id) {
    formVal.id = id
  }
  
  allLoading.saveLoading = true
  post(ADD_OR_UPDATE_REPORT_FORM, { ...formVal }).then(_res => {
    globalPopup?.showSuccess('保存成功')
    sessionStorage.removeItem('reportJson');
    sessionStorage.removeItem('editReportJson');
    router.go(-2)
  }).finally(() => {
    allLoading.saveLoading = false
  })
}

// 预览页面
function preview() {
  const rangeFilterData = rangeFilterRef.value?.getRangeData()

  const { finalSql } = preMethod()

  allVisable.previewTableVisable = true
  setTimeout(() => {
    previewTableRef.value?.initializedData(finalSql, rangeFilterData, tableData.value)
  }, 100)
}

// 关闭页面
function closePage() {
  ElMessageBox.confirm('要保存当前修改吗', '', {
    distinguishCancelAndClose: true,
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning',
  }).then(() => {
    saveReport()
  }).catch((action) => {
    if(action === 'cancel') {
      sessionStorage.removeItem('reportJson');
      sessionStorage.removeItem('editReportJson');
      router.go(-2)
    }
  })
}

// 分组
function grouping(index: number) {
  const val = tableData.value[index]?.singleColumnOperation?.grouping
  if(!tableData.value[index].singleColumnOperation) {
    tableData.value[index].singleColumnOperation = {}
    tableData.value[index].singleColumnOperation.grouping = val ? false : true
  } else {
    tableData.value[index].singleColumnOperation.grouping = val ? false : true
  }
}

// 统计
function statistics(index: number) {
  const val = tableData.value[index]?.singleColumnOperation?.statistics
  if(!tableData.value[index].singleColumnOperation) {
    tableData.value[index].singleColumnOperation = {}
    tableData.value[index].singleColumnOperation.statistics = val ? false : true
  } else {
    tableData.value[index].singleColumnOperation.statistics = val ? false : true
  }
}

// 修改名称
function changeName(index: number) {
  ElMessageBox.prompt('修改名称', '', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    inputPattern: /^.+$/,
    inputErrorMessage: '请输入',
  }).then(({ value }) => {
    tableData.value[index].columnComment = value
  })
}

// 删除列
function deleteColumn(index: number) {
  tableData.value.splice(index, 1);
}

// 添加列
function addTable(row: any) {
  const { tableName = '', columnName = '', dictCode = '', columnComment = '' } = row.data
  const index = row.newIndex;
  console.log(tableData.value, '<====== tableData.value')
  if (tableData.value.filter((item: any) => `${item.tableName}.${item.columnName}.${item.dictCode ? item.dictCode : ''}` === `${tableName}.${columnName}.${dictCode}`).length >= 2) {
    ElMessage.warning('该列已存在')
    tableData.value.splice(index, 1);
    return
  }

  if(tableData.value.filter((item: any) => item.columnComment === columnComment).length >= 2) {
    ElMessage.warning(`【${columnComment}】列名称已存在、请先修改列名称`)
    tableData.value.splice(index, 1);
    return
  }
}

function listOnClone(clonedItem: any) {
  clonedItem.prop = `col_${Date.now()}`; // 赋予唯一 key
}

async function getCollapseListData() {
  const { mindMapJSON = {} } = addEditData
  const selectNodes = mindMapJSON?.selectNodes
  allLoading.collapseListLoading = true
  for (let i in selectNodes) {
    console.log(selectNodes, '<===== selectNodes')
    const { dictCode = '', tblName = '' } = selectNodes[i].data
    const res = await post(GET_STRUCT_BY_TABLE_NAME, { tableName: tblName })

    res.data?.columnList.forEach((item: any) => {
      item.dictCode = dictCode
    });

    selectNodes[i].list = res.data
  }
  collapseList.value = selectNodes
  allLoading.collapseListLoading = false
}

function goBack() {
  router.go(-1)
}

function displayBackData() {
  const json = JSON.parse(sessionStorage.getItem('editReportJson') || '{}')
  const { rangeFilterData = [], tableData: tableDataList = [] } = json
  if(rangeFilterData.length) {
    setTimeout(() => {
      rangeFilterRef.value?.setRangeData(rangeFilterData, false)
    }, 300)
  }
  if(tableDataList.length) {
    setTimeout(() => {
      tableData.value = tableDataList
    }, 300)
  }
}

onMounted(() => {
  console.log(addEditData)
  const { reportFormName } = addEditData.addFormVal
  reportName.value = reportFormName
  getCollapseListData()
  displayBackData()
  setTimeout(() => {
    rangeFilterRef.value?.setIsItAnEditor()
  }, 100)
})
</script>

<template>
  <div class="dragEdit flex flex-row h-full bg-white rounded-md w-full">
    <div class="w-[15%] h-full overflow-auto scroll-bar p-4" v-loading="allLoading.collapseListLoading">
      <el-collapse v-model="activeNames">
        <el-collapse-item :title="item.data.newLabel || item.data.label" :name="index" v-for="(item, index) in (collapseList as any)" :key="index">
          <VueDraggable v-model="item.list.columnList" :animation="150"
            :group="{ name: 'people', pull: 'clone', put: false }" :sort="false"
            class="flex flex-col gap-2 p-4 w-300px bg-gray-500/5 rounded" @clone="listOnClone">
            <div v-for="listItem in item.list.columnList" class="cursor-all-scroll px-3 py-2 bg-white">
              {{ listItem.columnComment }}
            </div>
          </VueDraggable>
        </el-collapse-item>
      </el-collapse>
    </div>
    <div class="w-[85%] h-full">
      <div class="h-full w-full flex flex-col p-3 box-border">
        <div class="dragEdit-header">
          <div class="flex justify-between">
            <div><el-button @click="goBack()">返回上一级</el-button></div>
            <div class="text-[20px] font-bold">{{ reportName }}</div>
            <div>
              <el-button @click="closePage()">关闭</el-button>
              <el-button @click="preview()">预览</el-button>
              <el-button type="primary" @click="saveReport()" :loading="allLoading.saveLoading">保存</el-button>
            </div>
          </div>
          <div class="range mt-3 mb-3">
            <div class="flex items-center pb-3 font-bold text-[16px]">
              数据范围
            </div>
            <rangeFilter ref="rangeFilterRef" />
          </div>
        </div>
        <!-- 中间 -->
        <div class="flex justify-between items-center mb-3">
          <div class="flex items-center">
            <div class="font-bold text-[16px]">报表示例</div>
          </div>
          <div>点击顶部预览按钮可查看全部数据</div>
        </div>
        <!-- 表格 -->
        <div class="flex-1 relative border-2">
          <div class="table-container scroll-bar">
            <VueDraggable v-model="tableData" group="people" target=".sort-target" @add="addTable">
              <div class="absolute top-0 left-0 text-center text-[#999] w-full text-[20px] p-3" v-if="!tableData.length">
                <div class="border-2 border-dashed py-2">这里是表格头部区域，请将左侧字段拖入此区域生成报表</div>
              </div>
              <table class="table table-striped">
                <thead class="thead-dark">
                  <tr class="sort-target">
                    <th class="cursor-move" v-for="(header, headerIndex) in tableData" :key="header.value">
                      <div class="w-full flex justify-between items-center">
                        <div>{{ header.columnComment }}</div>
                        <el-dropdown>
                          <span class="el-dropdown-link">
                            <el-icon color="#075985">
                              <InfoFilled />
                            </el-icon>
                          </span>
                          <template #dropdown>
                            <el-dropdown-menu>
                              <el-dropdown-item v-if="['varchar', 'text'].includes(header.dataType)">
                                <el-text :underline="false" type="primary" @click="grouping(headerIndex)">
                                  {{ header?.singleColumnOperation?.grouping ? '取消分组' : '分组' }}
                                </el-text>
                              </el-dropdown-item>
                              <el-dropdown-item v-if="['decimal'].includes(header.dataType)">
                                <el-text :underline="false" type="primary" @click="statistics(headerIndex)">
                                  {{ header?.singleColumnOperation?.statistics ? '取消统计' : '统计' }}
                                </el-text>
                              </el-dropdown-item>
                              <el-dropdown-item>
                                <el-text :underline="false" type="primary" @click="changeName(headerIndex)">
                                  修改名称
                                </el-text>
                              </el-dropdown-item>
                              <el-dropdown-item>
                                <el-text :underline="false" type="danger"
                                  @click="deleteColumn(headerIndex)">删除列</el-text>
                              </el-dropdown-item>
                            </el-dropdown-menu>
                          </template>
                        </el-dropdown>
                      </div>
                    </th>
                  </tr>
                </thead>
                <tbody>
                  <tr v-for="item in tableColumns" :key="item.name">
                    <td v-for="header in tableData" :key="header.value">
                      示例数据
                    </td>
                  </tr>
                </tbody>
              </table>
            </VueDraggable>
          </div>
        </div>
      </div>
    </div>

    <!-- 全屏预览 -->
    <el-dialog v-model="allVisable.previewTableVisable" fullscreen top="40vh" width="70%" draggable>
      <previewTable ref="previewTableRef"></previewTable>
    </el-dialog>
  </div>
</template>

<style lang="scss" scoped>
.dragEdit {
  .table {
    display: table;
    width: 100%;
    font-size: 15px;
    border-collapse: collapse;
    margin: 0 0;
    overflow-x: auto;
  }

  tr {
    background-color: #fff;
    border-top: 1px solid #e2e2e3;
    transition: background-color .5s;
  }

  th {
    text-align: left;
    font-size: 14px;
    font-weight: 600;
    color: rgba(60, 60, 67, .78);
    background-color: #f6f6f7;
    border: 1px solid #e2e2e3;
    padding: 8px 16px;
    min-width: 240px;
  }

  td {
    padding: 8px 16px;
    font-size: 14px;
    min-width: 200px;
  }

  .cursor-move {
    cursor: move;
  }

  .table-container {
    overflow-x: auto;
    white-space: nowrap;
    width: 100%;
    height: 100%;
  }
}
</style>
