<template>
  <div class="personnel-page">
    <!-- 地图容器结构对齐 SelectAreaDialog：map-wrap > map-el -->
    <div v-loading="mapLoading" class="map-wrap">
      <div ref="mapRef" class="map-el"></div>
    </div>

    <div v-show="!showSubjectPanel" class="page-float">
      <el-button class="btn-add" type="warning" @click="handleAdd">
        + 新增主体
      </el-button>
    </div>

    <div v-show="!showSubjectPanel" class="ownership-panel">
      <div class="panel-header">
        <span class="panel-title">权属列表</span>
        <el-input v-model="keyword" class="panel-search" clearable placeholder="请搜索姓名">
          <template #prefix>
            <el-icon class="panel-search__icon">
              <Search />
            </el-icon>
          </template>
        </el-input>
      </div>

      <div class="panel-filters">
        <div v-for="tab in tabs" :key="tab.value" class="panel-filters__item"
          :class="{ 'is-active': activeTab === tab.value }" @click="activeTab = tab.value">
          {{ tab.label }}
        </div>
      </div>

      <div class="panel-list">
        <div
          v-for="item in filteredList"
          :key="item.id"
          class="person-card"
          :class="{ 'is-selected': selectedId === item.id }"
          @click="selectedId = item.id"
        >
          <div class="person-card__head">
            <el-avatar :size="36" class="person-card__avatar" :src="item.avatar">
              {{ item.name?.slice(0, 1) }}
            </el-avatar>
            <div class="person-card__info">
              <div class="person-card__name-row">
                <span class="person-card__name">{{ item.name }}</span>
                <span class="person-card__role">{{ item.roleLabel }}</span>
              </div>
              <div class="person-card__phone">电话: {{ item.phone }}</div>
            </div>
            <el-icon class="person-card__edit" @click.stop="handleEdit(item)">
              <Edit />
            </el-icon>
          </div>

          <div class="person-card__body">
            <div class="info-row">
              <span class="info-row__label">负责区域：</span>
              <span class="info-row__value">
                {{ item.areas }}
                <span class="link" @click.prevent="handleViewArea(item)">查看区域</span>
              </span>
            </div>
            <div class="info-row">
              <span class="info-row__label">区域面积：</span>
              <span class="info-row__value">{{ item.areaSize }}</span>
            </div>
            <div class="info-row">
              <span class="info-row__label">执行类别：</span>
              <span class="info-row__value">{{ item.categories }}</span>
            </div>
            <div class="info-row">
              <span class="info-row__label">负责农机：</span>
              <span class="info-row__value">{{ item.machines }}</span>
            </div>
            <div class="info-row">
              <span class="info-row__label">常驻位置：</span>
              <span class="info-row__value">{{ item.location }}</span>
            </div>
          </div>

          <div class="person-card__foot">
            <div class="person-card__actions">
              <div class="btn-action" @click="handleDownload(item)">下载责任书</div>
              <div class="btn-action" @click.stop="handleSign(item)">签署责任书</div>
            </div>
            <div class="btn-action btn-permission" @click="handlePermission(item)">设置权限</div>
          </div>
        </div>

        <el-empty v-if="!filteredList.length" description="暂无数据" :image-size="80" />
      </div>
    </div>

    <AddSubjectPanel
      v-model="showSubjectPanel"
      :mode="subjectMode"
      :person="editPerson"
      @save="handleSubjectSave"
    />
    <SignResponsibilityDialog
      v-model="showSignDialog"
      :person="signPerson"
      @submit="handleSignSubmit"
    />
  </div>
</template>

<script setup>
import { computed, getCurrentInstance, nextTick, onBeforeUnmount, onMounted, ref } from "vue";
import { Edit, Search } from "@element-plus/icons-vue";
import { ElMessage } from "element-plus";
import PersonnelMap, { DEFAULT_LOCATION } from "./map/personnelMap";
import AddSubjectPanel from "./components/AddSubjectPanel.vue";
import SignResponsibilityDialog from "./components/SignResponsibilityDialog.vue";

const DEFAULT_FARM_ID = 101532;

const { proxy } = getCurrentInstance();
const mapRef = ref(null);
const mapLoading = ref(false);
let personnelMap = null;

const keyword = ref("");
const activeTab = ref("all");
const selectedId = ref(null);
const showSubjectPanel = ref(false);
/** add | edit */
const subjectMode = ref("add");
const editPerson = ref(null);
const showSignDialog = ref(false);
const signPerson = ref(null);
const tabs = [
  { label: "全部", value: "all" },
  { label: "权属人", value: "owner" },
  { label: "区域服务人员", value: "staff" },
];

const list = ref([
  {
    id: 1,
    name: "张扬",
    role: "owner",
    roleLabel: "权属人",
    phone: "13939159356",
    avatar: "",
    areas: "2区、3区",
    areaSize: "180亩",
    categories: "类别一、类别一、类别一、类别一",
    machines: "农机一、农机一、农机一、农机一",
    location: "位置位置位置位置位置位置位置位置",
  },
  {
    id: 2,
    name: "张扬",
    role: "owner",
    roleLabel: "权属人",
    phone: "13939159356",
    avatar: "",
    areas: "2区、3区",
    areaSize: "180亩",
    categories: "类别一、类别一、类别一、类别一",
    machines: "农机一、农机一、农机一、农机一",
    location: "位置位置位置位置位置位置位置位置",
  },
  {
    id: 3,
    name: "张扬",
    role: "staff",
    roleLabel: "区域服务人员",
    phone: "13939159356",
    avatar: "",
    areas: "2区、3区",
    areaSize: "180亩",
    categories: "类别一、类别一、类别一、类别一",
    machines: "农机一、农机一、农机一、农机一",
    location: "位置位置位置位置位置位置位置位置",
  },
]);

const filteredList = computed(() => {
  const kw = keyword.value.trim();
  return list.value.filter((item) => {
    const matchTab = activeTab.value === "all" || item.role === activeTab.value;
    const matchKw = !kw || item.name.includes(kw);
    return matchTab && matchKw;
  });
});

/** 等地图容器有实际宽高后再初始化（对齐弹窗 @opened 时机） */
const waitForMapEl = () =>
  new Promise((resolve) => {
    const tick = (n = 0) => {
      const el = mapRef.value;
      if (el && el.clientWidth > 0 && el.clientHeight > 0) {
        resolve(el);
        return;
      }
      if (n > 60) {
        resolve(el);
        return;
      }
      requestAnimationFrame(() => tick(n + 1));
    };
    tick();
  });

/**
 * 对齐 SelectAreaDialog.handleOpened：
 * nextTick → init(PersonnelMap) → loadRegions → updateSize
 */
const handleOpened = async () => {
  await nextTick();
  const el = await waitForMapEl();
  if (!el) return;

  if (!personnelMap) {
    personnelMap = new PersonnelMap();
  }
  await personnelMap.init(el, DEFAULT_LOCATION);
  // 先校正尺寸，再 fit，避免容器尺寸为 0 时适配导致黑边碎块
  personnelMap.updateSize();
  await loadRegions();
  personnelMap.updateSize();
};

/** 对齐 SelectAreaDialog.loadRegions */
const loadRegions = async () => {
  mapLoading.value = true;
  try {
    const res = await proxy.VE_API.farm.blueRegionList({
      farmId: DEFAULT_FARM_ID,
      regionId: "",
    });
    const regionList = Array.isArray(res?.data) ? res.data : [];
    personnelMap?.setRegions(regionList);
    if (!regionList.length && res?.msg) {
      ElMessage.warning(res.msg);
    }
  } catch (e) {
    console.error(e);
    ElMessage.error("区域数据加载失败");
  } finally {
    mapLoading.value = false;
    await nextTick();
    personnelMap?.updateSize();
    personnelMap?.fitToRegions();
  }
};

const destroyMap = () => {
  personnelMap?.destroy();
  personnelMap = null;
};

const handleAdd = () => {
  subjectMode.value = "add";
  editPerson.value = null;
  showSubjectPanel.value = true;
};

const handleEdit = (item) => {
  selectedId.value = item.id;
  subjectMode.value = "edit";
  editPerson.value = item;
  showSubjectPanel.value = true;
};

const handleSubjectSave = (payload) => {
  console.log(payload.mode === "edit" ? "编辑主体" : "新增主体", payload);
  ElMessage.success("保存成功");
};

const handleViewArea = () => { };
const handleDownload = () => { };

const handleSign = (item) => {
  signPerson.value = item;
  showSignDialog.value = true;
};

const handleSignSubmit = (payload) => {
  console.log("签署责任书", payload);
  ElMessage.success("提交成功");
};

const handlePermission = () => { };

onMounted(() => {
  handleOpened();
});

onBeforeUnmount(() => {
  destroyMap();
});
</script>

<style lang="scss" scoped>
$primary: $warning-color;

.personnel-page {
  position: absolute;
  inset: 0;
  overflow: hidden;
  background: #1a1a1a;

  .map-wrap {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    background: #1a1a1a;
    overflow: hidden;

    .map-el {
      width: 100%;
      height: 100%;
    }
  }

  .page-float {
    position: absolute;
    top: 16px;
    left: 16px;
    z-index: 10;

    .btn-add {
      height: 36px;
      padding: 0 16px;
      border: none;
      border-radius: 4px;
      font-size: 14px;
      background: $primary;
    }
  }

  .ownership-panel {
    position: absolute;
    top: 25px;
    right: 20px;
    bottom: 25px;
    z-index: 10;
    display: flex;
    flex-direction: column;
    width: 380px;
    box-sizing: border-box;
    padding: 20px;
    background: #fff;
    border-radius: 10px;

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

      .panel-title {
        font-size: 18px;
        font-weight: 500;
        color: #060606;
      }

      .panel-search {
        width: 150px;
      }
    }

    .panel-filters {
      display: flex;
      flex-wrap: wrap;
      gap: 8px;
      margin: 10px 0;

      &__item {
        padding: 5px 10px;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        font-size: 12px;
        color: rgba(0, 0, 0, 0.6);
        background: #F3F3F3;
        border: 1px solid transparent;
        border-radius: 4px;
        cursor: pointer;

        &.is-active {
          color: $primary;
          background: rgba($primary, 0.1);
          border-color: $primary;
        }
      }
    }

    .panel-list {
      overflow: auto;

      .person-card {
        padding: 12px;
        border: .5px solid #E5E6EB;
        border-radius: 8px;
        cursor: pointer;
        border: 1px solid transparent;

        &.is-selected {
          border: 1px solid $primary;
          box-shadow: 0 4px 6px rgba($primary, 0.2) inset;
        }

        &__head {
          display: flex;
          align-items: center;
          gap: 10px;
          padding-bottom: 10px;
          border-bottom: 1px solid rgba(0, 0, 0, 0.1);
          margin-bottom: 10px;
        }

        &__info {
          flex: 1;
        }

        &__name-row {
          display: flex;
          align-items: center;
          gap: 7px;
        }

        &__name {
          font-weight: 500;
          color: #060606;
        }

        &__role {
          padding: 1px 5px;
          font-size: 12px;
          color: #070707;
          background: rgba(100, 100, 100, 0.1);
          border-radius: 2px;
        }

        &__phone {
          margin-top: 4px;
          font-size: 12px;
          color: rgba(105, 105, 105, 0.5);
        }

        &__edit {
          font-size: 20px;
          color: $primary;
        }

        &__foot {
          display: flex;
          align-items: center;
          justify-content: space-between;
          gap: 6px;
          margin-top: 10px;
        }

        &__actions {
          display: flex;
          align-items: center;
          gap: 6px;
        }
      }

      .info-row {
        display: flex;
        margin-top: 6px;
        font-size: 13px;

        &__label {
          width: 66px;
          color: #6C6C6C;
        }

        &__value {
          flex: 1;
          color: #000;
        }

        .link {
          color: $primary;
          text-decoration: underline;
          cursor: pointer;
          margin-left: 6px;
        }
      }

      .btn-action {
        padding: 6px 10px;
        cursor: pointer;
        border-radius: 4px;
        color: $primary;
        background: rgba($primary, 0.12);
        font-size: 12px;
      }

      .btn-permission {
        color: #fff;
        background: #FB8E33;
      }

      .person-card+.person-card {
        margin-top: 10px;
      }
    }
  }
}
</style>
