<script setup lang="ts">
import type { AreaSecurityUserDisplay } from '../data';

import type { OpsAreaApi } from '#/api/ops/area';

import { computed, ref } from 'vue';

import { useVbenModal } from '@vben/common-ui';

import {
  Button,
  Card,
  Col,
  Empty,
  message,
  Modal,
  Row,
  Spin,
} from 'ant-design-vue';

import { getAreaTree } from '#/api/ops/area';
import {
  getAreaSecurityUserList,
  unbindAreaSecurityUser,
} from '#/api/ops/area-security';

import AreaTree from '../../components/AreaTree.vue';
import { computeFullSecurityList } from '../data';
import BindStaffModal from './bind-staff-modal.vue';
import StaffCard from './staff-card.vue';

// ========== Area tree ==========
const areaTreeRef = ref<InstanceType<typeof AreaTree>>();
const selectedArea = ref<null | OpsAreaApi.BusArea>(null);
const selectedAreaPath = ref('');

/** 区域平铺列表（用于继承计算） */
const areaFlatList = ref<OpsAreaApi.BusArea[]>([]);

async function loadAreaFlatList() {
  try {
    areaFlatList.value = await getAreaTree({ isActive: true });
  } catch {
    areaFlatList.value = [];
  }
}

loadAreaFlatList();

function handleAreaSelect(area: null | OpsAreaApi.BusArea) {
  if (area && area.id !== null && area.id !== undefined) {
    selectedArea.value = area;
    selectedAreaPath.value =
      areaTreeRef.value?.getAreaPath(area.id) || area.areaName;
    fetchStaffList(area.id);
  } else {
    selectedArea.value = null;
    selectedAreaPath.value = '';
    displayList.value = [];
  }
}

// ========== Staff list (direct + inherited) ==========
const displayList = ref<AreaSecurityUserDisplay[]>([]);
const loading = ref(false);

async function fetchStaffList(areaId: number) {
  loading.value = true;
  try {
    displayList.value = await computeFullSecurityList(
      areaId,
      areaFlatList.value,
      getAreaSecurityUserList,
    );
  } catch {
    displayList.value = [];
  } finally {
    loading.value = false;
  }
}

const directList = computed(() =>
  displayList.value.filter((s) => s.bindType === 'DIRECT'),
);

const inheritedList = computed(() =>
  displayList.value.filter((s) => s.bindType === 'INHERITED'),
);

function refreshList() {
  if (selectedArea.value?.id) {
    fetchStaffList(selectedArea.value.id);
  }
}

// ========== Bind modal ==========
const [BindModal, bindModalApi] = useVbenModal({
  connectedComponent: BindStaffModal,
});

function handleAddStaff() {
  if (!selectedArea.value?.id) {
    message.warning('请先选择一个区域');
    return;
  }
  bindModalApi.setData({
    areaId: selectedArea.value.id,
    areaPath: selectedAreaPath.value,
    boundUserIds: displayList.value.map((s) => s.userId),
  });
  bindModalApi.open();
}

// ========== Unbind ==========
function handleUnbind(item: AreaSecurityUserDisplay) {
  Modal.confirm({
    title: '确认解除绑定',
    content: `确定要解除安保人员「${item.userName}」在该区域的绑定吗？`,
    okText: '确定',
    cancelText: '取消',
    okButtonProps: { danger: true },
    async onOk() {
      await unbindAreaSecurityUser(item.id);
      message.success('已解除绑定');
      refreshList();
    },
  });
}

// ========== Go to source area ==========
function handleGoSource(item: AreaSecurityUserDisplay) {
  if (!item.sourceAreaId) return;
  const sourceArea: OpsAreaApi.BusArea = {
    id: item.sourceAreaId,
    areaName: item.sourceAreaName || '',
  };
  handleAreaSelect(sourceArea);
}
</script>

<template>
  <Row :gutter="12" class="layout-row">
    <!-- Left: Area tree -->
    <Col :xs="24" :sm="24" :md="6" :lg="5" :xl="4" class="tree-col">
      <Card class="tree-card" title="业务区域">
        <AreaTree ref="areaTreeRef" @select="handleAreaSelect" />
      </Card>
    </Col>

    <!-- Right: Staff list -->
    <Col :xs="24" :sm="24" :md="18" :lg="19" :xl="20">
      <Spin :spinning="loading">
        <!-- Header -->
        <div class="content-header mb-3">
          <div class="content-header__left">
            <span class="content-title">
              {{ selectedAreaPath || '请选择区域' }}
            </span>
            <span v-if="selectedArea" class="content-subtitle">
              - 安保人员 ({{ displayList.length }})
            </span>
          </div>
          <Button v-if="selectedArea" type="primary" @click="handleAddStaff">
            + 新增绑定
          </Button>
        </div>

        <!-- Empty: no area selected -->
        <Card v-if="!selectedArea" class="empty-card">
          <Empty description="请在左侧选择一个区域以查看安保人员" />
        </Card>

        <!-- Empty: no staff -->
        <Card
          v-else-if="displayList.length === 0 && !loading"
          class="empty-card"
        >
          <Empty description="该区域暂无绑定安保人员">
            <Button type="primary" @click="handleAddStaff"> 新增绑定 </Button>
          </Empty>
        </Card>

        <!-- Staff cards -->
        <template v-else>
          <!-- Direct -->
          <div v-if="directList.length > 0" class="section">
            <div class="section__title">直接绑定 ({{ directList.length }})</div>
            <Row :gutter="[12, 12]">
              <Col
                v-for="item in directList"
                :key="item.id"
                :xs="24"
                :sm="12"
                :md="12"
                :lg="8"
                :xl="6"
              >
                <StaffCard :item="item" @unbind="handleUnbind" />
              </Col>
            </Row>
          </div>

          <!-- Inherited -->
          <div v-if="inheritedList.length > 0" class="section">
            <div class="section__title">
              继承人员 ({{ inheritedList.length }})
              <span class="section__hint">
                — 来自父级区域，如需修改请前往对应源区域
              </span>
            </div>
            <Row :gutter="[12, 12]">
              <Col
                v-for="item in inheritedList"
                :key="`${item.id}-${item.sourceAreaId}`"
                :xs="24"
                :sm="12"
                :md="12"
                :lg="8"
                :xl="6"
              >
                <StaffCard :item="item" @go-source="handleGoSource" />
              </Col>
            </Row>
          </div>
        </template>
      </Spin>
    </Col>
  </Row>

  <!-- Modal -->
  <BindModal @success="refreshList" />
</template>

<style scoped lang="scss">
@media (max-width: 768px) {
  .layout-row {
    flex-direction: column;
  }

  .tree-col {
    margin-bottom: 12px;
  }

  .tree-card {
    :deep(.ant-card-body) {
      max-height: 200px;
    }
  }
}

.layout-row {
  display: flex;
  flex-wrap: wrap;
}

.tree-col {
  display: flex;
}

.tree-card {
  display: flex;
  flex-direction: column;
  width: 100%;
  border-radius: 8px;

  :deep(.ant-card-head) {
    min-height: 44px;
    padding: 0 16px;

    .ant-card-head-title {
      padding: 12px 0;
      font-size: 14px;
      font-weight: 600;
    }
  }

  :deep(.ant-card-body) {
    flex: 1;
    padding: 12px 16px;
    overflow-y: auto;
  }

  :deep(.ant-tree) {
    background: transparent;
  }
}

.content-header {
  display: flex;
  align-items: center;
  justify-content: space-between;

  &__left {
    display: flex;
    gap: 8px;
    align-items: baseline;
  }
}

.content-title {
  font-size: 16px;
  font-weight: 600;
  color: #262626;
}

.content-subtitle {
  font-size: 13px;
  color: #8c8c8c;
}

.empty-card {
  border-radius: 8px;

  :deep(.ant-card-body) {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 300px;
  }
}

.section {
  margin-bottom: 20px;

  &__title {
    margin-bottom: 12px;
    font-size: 14px;
    font-weight: 600;
    color: #262626;
  }

  &__hint {
    font-size: 12px;
    font-weight: 400;
    color: #8c8c8c;
  }
}

html.dark {
  .content-title {
    color: rgb(255 255 255 / 85%);
  }

  .content-subtitle {
    color: rgb(255 255 255 / 45%);
  }

  .section__title {
    color: rgb(255 255 255 / 85%);
  }

  .section__hint {
    color: rgb(255 255 255 / 45%);
  }
}
</style>
