<script setup>
import { computed, nextTick, onBeforeUnmount, onMounted, ref, watch } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import {
  Delete,
  Download,
  Edit,
  Grid,
  Plus,
  Printer,
  Search,
  Upload,
  View
} from '@element-plus/icons-vue'

const scopeSelect = ref('selected')
const districtSearch = ref('')
const treeRef = ref(null)

const treeData = ref([
  {
    id: '106',
    label: '106壶天镇',
    children: [
      {
        id: '203',
        label: '203大坪村',
        children: Array.from({ length: 12 }, (_, i) => {
          const no = String(i + 1).padStart(2, '0')
          return { id: `203-${no}`, label: `[${no}] 大坪第${i + 1}村民组`, children: [] }
        })
      },
      { id: '206', label: '206石狗村', children: [] },
      { id: '207', label: '207壶天村', children: [] },
      { id: '210', label: '210中石村', children: [] },
      { id: '214', label: '214光辉村', children: [] },
      { id: '218', label: '218直东村', children: [] },
      { id: '220', label: '220合东村', children: [] },
      { id: '222', label: '222南岳坪村', children: [] },
      { id: '224', label: '224上新桥村', children: [] },
      { id: '229', label: '229潭桥村', children: [] },
      { id: '230', label: '230双坪村', children: [] },
      { id: '235', label: '235山坪村', children: [] },
      { id: '238', label: '238大塘村', children: [] },
      { id: '239', label: '239山竹村', children: [] },
      { id: '242', label: '242渠溪村', children: [] },
      { id: '244', label: '244雄辉村', children: [] },
      { id: '247', label: '247井湾村', children: [] },
      { id: '248', label: '248背冲村', children: [] }
    ]
  },
  { id: '107', label: '107翻江镇', children: [] },
  { id: '110', label: '110月山镇', children: [] }
])

const treeProps = { children: 'children', label: 'label' }

const selectedNodeId = ref('')
const selectedSubtreeIds = ref(null)

function walkSubtreeIds(node, set) {
  if (!node) return
  set.add(node.id)
  const children = Array.isArray(node.children) ? node.children : []
  for (const child of children) walkSubtreeIds(child, set)
}

function filterTreeNode(value, data) {
  if (!value) return true
  if (scopeSelect.value === 'selected' && selectedSubtreeIds.value && !selectedSubtreeIds.value.has(data?.id)) {
    return false
  }
  return String(data?.label || '').includes(value)
}

function handleTreeNodeClick(data) {
  selectedNodeId.value = data?.id || ''
  const set = new Set()
  walkSubtreeIds(data, set)
  selectedSubtreeIds.value = set
  if (districtSearch.value) treeRef.value?.filter?.(districtSearch.value)
}

watch(districtSearch, (val) => treeRef.value?.filter?.(val))

const codeFilterOpen = ref(false)
const nameFilterOpen = ref(false)
const idNoFilterOpen = ref(false)
const leaderFilterOpen = ref(false)

const codeFilter = ref('')
const nameFilter = ref('')
const idNoFilter = ref('')
const leaderFilter = ref('')

const editEnabled = ref(false)

function buildRows() {
  const districts = [
    { id: '203-01', districtCode: '430381106203010001', districtName: '湘乡市壶天镇大坪村第一村民组' },
    { id: '203-02', districtCode: '430381106203010002', districtName: '湘乡市壶天镇大坪村第二村民组' },
    { id: '203-03', districtCode: '430381106203010003', districtName: '湘乡市壶天镇大坪村第三村民组' },
    { id: '203-04', districtCode: '430381106203010004', districtName: '湘乡市壶天镇大坪村第四村民组' },
    { id: '203-05', districtCode: '430381106203010005', districtName: '湘乡市壶天镇大坪村第五村民组' },
    { id: '206', districtCode: '430381106206000000', districtName: '湘乡市壶天镇石狗村' },
    { id: '222', districtCode: '430381106222000000', districtName: '湘乡市壶天镇南岳坪村' }
  ]

  const leaders = ['傅云初', '李益雄', '李端平', '李冬荣', '傅立荣', '罗建兵', '罗碧文', '周灿辉', '李崇佳', '李中方', '傅作良', '傅孟忠']
  const villages = ['大坪村', '石狗村', '南岳坪村', '上新桥村', '潭桥村']
  const groups = ['第一村民组', '第二村民组', '第三村民组', '第四村民组', '第五村民组', '第六村民组', '第七村民组', '第八村民组', '第九村民组', '第十村民组', '第十一村民组', '第十二村民组']

  return Array.from({ length: 38 }, (_, i) => {
    const no = String(i + 1).padStart(2, '0')
    const d = districts[i % districts.length]
    const leader = leaders[i % leaders.length]
    const village = villages[i % villages.length]
    const group = groups[i % groups.length]
    const signed = i % 4 !== 0
    return {
      id: i + 1,
      districtId: d.id,
      districtCode: d.districtCode,
      districtName: d.districtName,
      fbfCode: `430381106203${no}01`,
      fbfName: `湘乡市壶天镇${village}${group}发包方`,
      idNo: `43032219${String(620220000000 + i * 38761).slice(0, 10)}`.slice(0, 18),
      address: `湘乡市壶天镇${village}${group}`,
      leaderName: leader,
      signed
    }
  })
}

const allRows = ref(buildRows())

const filteredByTree = computed(() => {
  if (scopeSelect.value === 'all') return allRows.value
  const ids = selectedSubtreeIds.value
  if (!ids || ids.size === 0) return allRows.value
  return allRows.value.filter((r) => ids.has(r.districtId) || ids.has(r.districtId?.split?.('-')?.[0]))
})

const filteredRows = computed(() => {
  const code = String(codeFilter.value || '').trim()
  const name = String(nameFilter.value || '').trim()
  const idNo = String(idNoFilter.value || '').trim()
  const leader = String(leaderFilter.value || '').trim()

  return filteredByTree.value.filter((r) => {
    if (code && !String(r.fbfCode || '').includes(code)) return false
    if (name && !String(r.fbfName || '').includes(name)) return false
    if (idNo && !String(r.idNo || '').includes(idNo)) return false
    if (leader && !String(r.leaderName || '').includes(leader)) return false
    return true
  })
})

const tableRef = ref(null)
const pageSize = ref(20)
const currentPage = ref(1)
const jumpPage = ref(1)

const total = computed(() => filteredRows.value.length)
const pageRows = computed(() => {
  const start = (currentPage.value - 1) * pageSize.value
  return filteredRows.value.slice(start, start + pageSize.value)
})

watch([pageSize, selectedNodeId, scopeSelect, codeFilter, nameFilter, idNoFilter, leaderFilter], () => {
  currentPage.value = 1
  jumpPage.value = 1
})

function doJump() {
  const maxPage = Math.max(1, Math.ceil(total.value / pageSize.value))
  const next = Math.min(Math.max(1, Number(jumpPage.value || 1)), maxPage)
  currentPage.value = next
}

const selectedRows = ref([])
function handleSelectionChange(rows) {
  selectedRows.value = rows || []
}

function handleExport() {
  ElMessage.success('导出任务已提交')
}

function handleImport() {
  ElMessage.success('导入任务已提交')
}

function handlePrint() {
  ElMessage.success('打印任务已提交')
}

async function handleDeleteSelected() {
  if (!selectedRows.value.length) {
    ElMessage.warning('请先勾选要删除的记录')
    return
  }
  try {
    await ElMessageBox.confirm(`确认删除选中的 ${selectedRows.value.length} 条记录？`, '提示', { type: 'warning' })
    const ids = new Set(selectedRows.value.map((r) => r.id))
    allRows.value = allRows.value.filter((r) => !ids.has(r.id))
    selectedRows.value = []
    ElMessage.success('已删除')
  } catch {
    //
  }
}

const editDialogOpen = ref(false)
const editForm = ref({
  id: null,
  fbfCode: '',
  fbfName: '',
  idNo: '',
  address: '',
  leaderName: ''
})

function openAdd() {
  editForm.value = {
    id: null,
    fbfCode: '',
    fbfName: '',
    idNo: '',
    address: '',
    leaderName: ''
  }
  editDialogOpen.value = true
}

function openEdit(row) {
  if (!editEnabled.value) {
    ElMessage.warning('请先开启编辑')
    return
  }
  editForm.value = {
    id: row.id,
    fbfCode: row.fbfCode,
    fbfName: row.fbfName,
    idNo: row.idNo,
    address: row.address,
    leaderName: row.leaderName
  }
  editDialogOpen.value = true
}

function submitEdit() {
  const f = editForm.value
  if (!String(f.fbfCode || '').trim() || !String(f.fbfName || '').trim()) {
    ElMessage.warning('请完善发包方编码和名称')
    return
  }
  if (f.id == null) {
    const nextId = Math.max(0, ...allRows.value.map((r) => Number(r.id) || 0)) + 1
    const districtId = selectedNodeId.value || allRows.value?.[0]?.districtId || '203-01'
    allRows.value = [
      {
        id: nextId,
        districtId,
        districtCode: '430381106203010001',
        districtName: '湘乡市壶天镇大坪村第一村民组',
        fbfCode: String(f.fbfCode).trim(),
        fbfName: String(f.fbfName).trim(),
        idNo: String(f.idNo || '').trim(),
        address: String(f.address || '').trim(),
        leaderName: String(f.leaderName || '').trim(),
        signed: false
      },
      ...allRows.value
    ]
  } else {
    allRows.value = allRows.value.map((r) =>
      r.id === f.id
        ? {
            ...r,
            fbfCode: String(f.fbfCode).trim(),
            fbfName: String(f.fbfName).trim(),
            idNo: String(f.idNo || '').trim(),
            address: String(f.address || '').trim(),
            leaderName: String(f.leaderName || '').trim()
          }
        : r
    )
  }
  editDialogOpen.value = false
  ElMessage.success('已保存')
}

const signDialogOpen = ref(false)
const signViewRow = ref(null)
function openSign(row) {
  signViewRow.value = row || null
  signDialogOpen.value = true
}

function handleIconAction(name) {
  ElMessage.success(name)
}

const contentWrapEl = ref(null)
let resizeObserver = null
function ensureTableLayout() {
  nextTick(() => tableRef.value?.doLayout?.())
}

onMounted(async () => {
  await nextTick()
  const defaultNode = treeData.value?.[0]?.children?.find?.((v) => v.id === '203') || treeData.value?.[0]
  handleTreeNodeClick(defaultNode)
  treeRef.value?.setCurrentKey?.(defaultNode?.id)
  ensureTableLayout()
  if (contentWrapEl.value && !resizeObserver) {
    resizeObserver = new ResizeObserver(() => ensureTableLayout())
    resizeObserver.observe(contentWrapEl.value)
  }
})

onBeforeUnmount(() => {
  resizeObserver?.disconnect?.()
  resizeObserver = null
})

</script>

<template>
  <div class="h-full w-full flex overflow-hidden bg-white">
    <div class="w-72 border-r border-gray-200 bg-white flex flex-col">
      <div class="p-2 border-b border-gray-200">
        <el-select v-model="scopeSelect" size="small" class="w-full" placeholder="选中的节点中搜索">
          <el-option label="选中的节点中搜索" value="selected" />
          <el-option label="全部" value="all" />
        </el-select>
        <el-input v-model="districtSearch" size="small" class="w-full mt-2" clearable placeholder="搜索" />
      </div>
      <el-scrollbar class="flex-1">
        <div class="p-2">
          <el-tree
            ref="treeRef"
            :data="treeData"
            node-key="id"
            :props="treeProps"
            :filter-node-method="filterTreeNode"
            default-expand-all
            highlight-current
            :expand-on-click-node="false"
            @node-click="handleTreeNodeClick"
          />
        </div>
      </el-scrollbar>
    </div>

    <div ref="contentWrapEl" class="flex-1 overflow-hidden">
      <div class="h-full flex flex-col">
        <div class="flex items-center justify-between px-3 py-2 border-b border-gray-200">
          <div class="flex items-center gap-2">
            <el-button type="primary" size="small" :icon="Plus" @click="openAdd">新增</el-button>
            <el-button type="danger" size="small" :icon="Delete" @click="handleDeleteSelected">删除</el-button>
            <el-button type="primary" size="small" :icon="Download" @click="handleExport">导出发包方清单</el-button>
            <el-button type="primary" size="small" :icon="Upload" @click="handleImport">导入发包方清单</el-button>
            <el-checkbox v-model="editEnabled" class="ml-2">开启编辑</el-checkbox>
          </div>
          <div class="flex items-center gap-2">
            <el-button :icon="Grid" circle size="small" @click="handleIconAction('已切换显示')" />
            <el-button :icon="Download" circle size="small" @click="handleExport" />
            <el-button :icon="Printer" circle size="small" @click="handlePrint" />
          </div>
        </div>

        <div class="flex-1 p-3 overflow-hidden">
          <div class="h-full border border-gray-200 flex flex-col">
            <div class="flex-1 overflow-hidden">
              <el-table
                ref="tableRef"
                :data="pageRows"
                height="100%"
                border
                stripe
                @selection-change="handleSelectionChange"
              >
                <el-table-column type="selection" width="46" align="center" />
                <el-table-column label="#" width="56" align="center">
                  <template #default="{ $index }">
                    {{ (currentPage - 1) * pageSize + $index + 1 }}
                  </template>
                </el-table-column>

                <el-table-column prop="fbfCode" label="发包方编码" min-width="170" show-overflow-tooltip>
                  <template #header>
                    <div class="flex items-center justify-between gap-2">
                      <span>发包方编码</span>
                      <el-popover v-model:visible="codeFilterOpen" trigger="click" placement="bottom" width="260">
                        <template #reference>
                          <el-button :icon="Search" circle size="small" />
                        </template>
                        <div class="space-y-2">
                          <el-input v-model="codeFilter" size="small" clearable placeholder="输入编码关键字" @keyup.enter="codeFilterOpen = false" />
                          <div class="flex justify-end gap-2">
                            <el-button size="small" @click="codeFilter = ''">清空</el-button>
                            <el-button size="small" type="primary" @click="codeFilterOpen = false">确定</el-button>
                          </div>
                        </div>
                      </el-popover>
                    </div>
                  </template>
                </el-table-column>

                <el-table-column prop="fbfName" label="发包方名称" min-width="240" show-overflow-tooltip>
                  <template #header>
                    <div class="flex items-center justify-between gap-2">
                      <span>发包方名称</span>
                      <el-popover v-model:visible="nameFilterOpen" trigger="click" placement="bottom" width="260">
                        <template #reference>
                          <el-button :icon="Search" circle size="small" />
                        </template>
                        <div class="space-y-2">
                          <el-input v-model="nameFilter" size="small" clearable placeholder="输入名称关键字" @keyup.enter="nameFilterOpen = false" />
                          <div class="flex justify-end gap-2">
                            <el-button size="small" @click="nameFilter = ''">清空</el-button>
                            <el-button size="small" type="primary" @click="nameFilterOpen = false">确定</el-button>
                          </div>
                        </div>
                      </el-popover>
                    </div>
                  </template>
                </el-table-column>

                <el-table-column prop="idNo" label="证件号码" min-width="190" show-overflow-tooltip>
                  <template #header>
                    <div class="flex items-center justify-between gap-2">
                      <span>证件号码</span>
                      <el-popover v-model:visible="idNoFilterOpen" trigger="click" placement="bottom" width="260">
                        <template #reference>
                          <el-button :icon="Search" circle size="small" />
                        </template>
                        <div class="space-y-2">
                          <el-input v-model="idNoFilter" size="small" clearable placeholder="输入证件号码" @keyup.enter="idNoFilterOpen = false" />
                          <div class="flex justify-end gap-2">
                            <el-button size="small" @click="idNoFilter = ''">清空</el-button>
                            <el-button size="small" type="primary" @click="idNoFilterOpen = false">确定</el-button>
                          </div>
                        </div>
                      </el-popover>
                    </div>
                  </template>
                </el-table-column>

                <el-table-column prop="address" label="发包方地址" min-width="220" show-overflow-tooltip />

                <el-table-column prop="leaderName" label="负责人姓名" width="140" show-overflow-tooltip>
                  <template #header>
                    <div class="flex items-center justify-between gap-2">
                      <span>负责人姓名</span>
                      <el-popover v-model:visible="leaderFilterOpen" trigger="click" placement="bottom" width="260">
                        <template #reference>
                          <el-button :icon="Search" circle size="small" />
                        </template>
                        <div class="space-y-2">
                          <el-input v-model="leaderFilter" size="small" clearable placeholder="输入负责人姓名" @keyup.enter="leaderFilterOpen = false" />
                          <div class="flex justify-end gap-2">
                            <el-button size="small" @click="leaderFilter = ''">清空</el-button>
                            <el-button size="small" type="primary" @click="leaderFilterOpen = false">确定</el-button>
                          </div>
                        </div>
                      </el-popover>
                    </div>
                  </template>
                </el-table-column>

                <el-table-column label="发包方签名" width="120" align="center">
                  <template #default="{ row }">
                    <el-tag v-if="row.signed" type="warning">已签名</el-tag>
                    <el-tag v-else type="info">未签名</el-tag>
                  </template>
                </el-table-column>

                <el-table-column label="操作" width="210" align="center" fixed="right">
                  <template #default="{ row }">
                    <div class="flex items-center justify-center gap-2">
                      <el-button size="small" type="success" :icon="Edit" :disabled="!editEnabled" @click="openEdit(row)">修改</el-button>
                      <el-button size="small" type="primary" :icon="View" @click="openSign(row)">查看发包方签名</el-button>
                    </div>
                  </template>
                </el-table-column>
              </el-table>
            </div>

            <div class="h-12 px-2 border-t border-gray-200 flex items-center justify-between">
              <el-pagination
                v-model:current-page="currentPage"
                v-model:page-size="pageSize"
                :page-sizes="[10, 20, 50, 100]"
                :total="total"
                layout="prev, pager, next"
                background
                small
              />
              <div class="flex items-center gap-2 text-sm text-gray-700">
                <div>到第</div>
                <el-input-number v-model="jumpPage" :min="1" :max="Math.max(1, Math.ceil(total / pageSize))" size="small" controls-position="right" class="!w-24" />
                <div>页</div>
                <el-button size="small" type="primary" @click="doJump">确定</el-button>
                <div class="ml-2">共 {{ total }} 条</div>
                <el-select v-model="pageSize" size="small" class="!w-24">
                  <el-option :label="`10条/页`" :value="10" />
                  <el-option :label="`20条/页`" :value="20" />
                  <el-option :label="`50条/页`" :value="50" />
                  <el-option :label="`100条/页`" :value="100" />
                </el-select>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>

    <el-dialog v-model="editDialogOpen" :title="editForm.id == null ? '新增发包方' : '修改发包方'" width="640px" append-to-body>
      <el-form label-width="110px">
        <el-form-item label="发包方编码">
          <el-input v-model="editForm.fbfCode" placeholder="请输入发包方编码" />
        </el-form-item>
        <el-form-item label="发包方名称">
          <el-input v-model="editForm.fbfName" placeholder="请输入发包方名称" />
        </el-form-item>
        <el-form-item label="证件号码">
          <el-input v-model="editForm.idNo" placeholder="请输入证件号码" />
        </el-form-item>
        <el-form-item label="发包方地址">
          <el-input v-model="editForm.address" placeholder="请输入发包方地址" />
        </el-form-item>
        <el-form-item label="负责人姓名">
          <el-input v-model="editForm.leaderName" placeholder="请输入负责人姓名" />
        </el-form-item>
      </el-form>
      <template #footer>
        <div class="flex justify-end gap-2">
          <el-button @click="editDialogOpen = false">取消</el-button>
          <el-button type="primary" @click="submitEdit">确定</el-button>
        </div>
      </template>
    </el-dialog>

    <el-dialog v-model="signDialogOpen" title="发包方签名" width="640px" append-to-body>
      <div class="space-y-3">
        <div class="text-sm text-gray-700">
          <span class="mr-2">发包方：</span>
          <span class="font-medium">{{ signViewRow?.fbfName || '-' }}</span>
        </div>
        <div class="border border-gray-200 rounded p-3 bg-gray-50">
          <div class="h-52 flex items-center justify-center">
            <div v-if="signViewRow?.signed" class="text-2xl font-semibold text-gray-700 tracking-widest">
              {{ signViewRow?.leaderName || '签名' }}
            </div>
            <div v-else class="text-gray-500">暂无签名</div>
          </div>
        </div>
      </div>
      <template #footer>
        <div class="flex justify-end">
          <el-button type="primary" @click="signDialogOpen = false">关闭</el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<style scoped>
:deep(.el-tree-node__content) {
  height: 26px;
}
</style>
