<template>
  <div class="dispatch-container">
    <!-- Top Filter Bar -->
    <div class="top-filter-bar glass-panel-sm">
      <div class="filter-left">
        <el-radio-group v-model="filters.orderType" size="default" fill="#2d8cf0">
          <el-radio-button label="all">全部</el-radio-button>
          <el-radio-button v-for="item in serviceOnOrderList" :key="item.id" :label="item.id">{{ item.name
          }}</el-radio-button>
        </el-radio-group>
      </div>
      <div class="filter-right">
        <el-cascader v-model="regionValue" :options="areaOptions" placeholder="省市区域" clearable
          style="width: 170px; margin-right: 10px" @change="handleAreaChange" />
        <el-select v-model="filters.station" placeholder="站点" clearable style="width: 170px">
          <el-option v-for="item in siteOptions" :key="item.value" :label="item.label" :value="item.value" />
        </el-select>
      </div>
    </div>

    <div class="main-content">
      <!-- Left: Real Baidu Map Area -->
      <div class="map-wrapper">
        <div id="baidu-map" class="map-view"></div>

        <!-- Bottom Left: Map Controls & Stats -->
        <div class="map-controls-panel">
          <div class="control-group">
            <div class="c-btn" :class="{ active: activeMapFilter === 'all' }" @click="setMapFilter('all')">全部</div>
            <div class="c-btn red" :class="{ active: activeMapFilter === 'merchants' }"
              @click="setMapFilter('merchants')">商家(16)</div>
            <div class="c-btn green" :class="{ active: activeMapFilter === 'fulfillers' }"
              @click="setMapFilter('fulfillers')">履约者(12)</div>
            <div class="c-btn blue" :class="{ active: activeMapFilter === 'orders' }" @click="setMapFilter('orders')">
              订单(5)</div>
            <div class="c-btn gray">灰色表示离线</div>
          </div>
        </div>
      </div>

      <!-- Right: Dispatch Control Panel -->
      <div class="right-panel">
        <OrderListPanel v-model="currentOrderTab" :orders="filteredOrders" :stats="orderStats" @focus="focusMapPoint"
          @dispatch="openDispatchDialog" />

        <RiderListPanel v-model="currentRiderTab" :riders="filteredRiders" @focus="focusMapPoint"
          @view-orders="handleViewRiderOrders" />
      </div>
    </div>

    <RiderOrdersDialog v-model="riderOrdersVisible" :riderInfo="currentRiderInfo" :orders="currentRiderOrders" />

    <DispatchDialog v-model="dispatchDialogVisible" :order="currentDispatchOrder" :currentRider="currentRider"
      :ridersList="ridersList" @submit="handleDispatchSubmit" />
  </div>
</template>

<script setup>
import { ref, computed, reactive, onMounted, watch } from 'vue';
import { ElMessage } from 'element-plus';
import { listServiceOnOrder } from '@/api/service/list/index'
import { listOnStore as listAreaStationOnStore } from '@/api/system/areaStation'

import OrderListPanel from './components/OrderListPanel.vue';
import RiderListPanel from './components/RiderListPanel.vue';
import RiderOrdersDialog from './components/RiderOrdersDialog.vue';
import DispatchDialog from './components/DispatchDialog.vue';

// Mock Data
import dispatchMockData from '@/mock/dispatch.json';
import riderOrdersMockData from '@/mock/RiderOrdersDialog.json';

// --- Data & State ---
const filters = reactive({
  orderType: 'all',
  station: undefined
});

const currentOrderTab = ref('PendingDispatch');
const currentRiderTab = ref('All');
const activeMapFilter = ref('all');

const ordersList = ref(dispatchMockData.ordersList);
const ridersList = ref(dispatchMockData.ridersList);
const merchantList = ref(dispatchMockData.merchantList);
const orderStats = reactive(dispatchMockData.stats);

const serviceOnOrderList = ref([])

const getServiceList = () => {
  listServiceOnOrder().then(res => {
    serviceOnOrderList.value = res?.data?.data || res?.data || []
  }).catch(() => {
    serviceOnOrderList.value = []
  })
}

const areaStationList = ref([])
const areaOptions = ref([])
const siteOptions = ref([])
const regionValue = ref([])

const buildTree = (data, parentId) => {
  return (data || [])
    .filter(item => String(item.parentId) === String(parentId))
    .map(item => ({
      value: item.id,
      label: item.name,
      children: buildTree(data, item.id)
    }))
}

const handleAreaChange = (value) => {
  filters.station = undefined
  if (value && value.length > 0) {
    const areaId = value[value.length - 1]
    siteOptions.value = areaStationList.value
      .filter(item => Number(item.type) === 2 && String(item.parentId) === String(areaId))
      .map(item => ({ value: item.id, label: item.name }))
  } else {
    siteOptions.value = []
  }
}

const getAreaStationList = async () => {
  try {
    const res = await listAreaStationOnStore()
    const data = res?.data || res
    areaStationList.value = Array.isArray(data) ? data : []
    const areaData = areaStationList.value.filter(item => Number(item.type) === 0 || Number(item.type) === 1)
    areaOptions.value = buildTree(areaData, 0)
    siteOptions.value = []

    const allStations = areaStationList.value.filter(item => Number(item.type) === 2)
    if (allStations.length > 0) {
      const randomStation = allStations[Math.floor(Math.random() * allStations.length)]
      const areaId = randomStation.parentId

      const path = []
      let currentId = areaId
      while (currentId && String(currentId) !== '0') {
        path.unshift(currentId)
        const currentArea = areaStationList.value.find(item => String(item.id) === String(currentId))
        if (currentArea) {
          currentId = currentArea.parentId
        } else {
          break
        }
      }

      regionValue.value = path
      siteOptions.value = areaStationList.value
        .filter(item => Number(item.type) === 2 && String(item.parentId) === String(areaId))
        .map(item => ({ value: item.id, label: item.name }))
      filters.station = randomStation.id
    }
  } catch {
    areaStationList.value = []
    areaOptions.value = []
    siteOptions.value = []
  }
}

// Rider Orders State
const riderOrdersVisible = ref(false);
const currentRiderInfo = ref(null);
const currentRiderOrders = ref([]);

const handleViewRiderOrders = (rider) => {
  currentRiderInfo.value = {
    name: rider.name,
    maskPhone: rider.phone.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2'),
    station: rider.station + ' - 东城片区',
    workType: '全职专送',
    categories: ['宠物接送', '上门喂遛', '洗护套餐']
  };
  currentRiderOrders.value = riderOrdersMockData.orders;
  riderOrdersVisible.value = true;
};

// Map Logic
let map = null;
const ak = 'E4805d16520de693a3fe707cdc962045'; // Public Key

const loadBMapScript = () => {
  return new Promise((resolve, reject) => {
    if (window.BMap) {
      resolve(window.BMap);
      return;
    }
    window.initBMapCallback = () => resolve(window.BMap);
    const script = document.createElement('script');
    script.src = `https://api.map.baidu.com/api?v=3.0&ak=${ak}&callback=initBMapCallback`;
    script.onerror = reject;
    document.head.appendChild(script);
  });
};

const initMap = () => {
  if (!window.BMap) return;
  map = new BMap.Map('baidu-map');
  const point = new BMap.Point(116.4551, 39.9255); // Chaoyang center
  map.centerAndZoom(point, 14);
  map.enableScrollWheelZoom(true);
  map.setMapStyleV2({
    styleId: '3d71dc5a4ce6228d3e9680188e982438'
  });

  refreshMarkers();
};

const refreshMarkers = () => {
  if (!map) return;
  map.clearOverlays();

  const filter = activeMapFilter.value;

  // 1. Merchants
  if (filter === 'all' || filter === 'merchants') {
    merchantList.value.forEach((m) => {
      const pt = new BMap.Point(m.lng, m.lat);
      const iconImg = m.icon || 'https://cube.elemecdn.com/e/fd/0fc7d20532fdaf769a25683617711png.png';

      const html = `
            <div style="position:absolute; transform:translate(-50%, -100%); width: 220px; filter: drop-shadow(0 4px 10px rgba(0,0,0,0.2));">
                <div style="background:#fff; border-radius:8px; padding: 12px; display: flex; align-items: center; gap: 10px; position: relative;">
                     <!-- Close Icon -->
                    <div style="position: absolute; top: 4px; right: 8px; color: #999; font-size: 16px; cursor: pointer;">×</div>
                    
                    <!-- Icon Ring -->
                    <div style="width: 48px; height: 48px; border-radius: 50%; border: 4px solid #F56C6C; padding: 2px; flex-shrink: 0; box-sizing: border-box; display: flex; align-items: center; justify-content: center;">
                         <img src="${iconImg}" style="width: 100%; height: 100%; border-radius: 50%; object-fit: cover;">
                    </div>
                    
                    <!-- Info -->
                    <div style="flex: 1; overflow: hidden;">
                        <div style="font-weight: bold; font-size: 14px; color: #333; margin-bottom: 4px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;">${m.name}</div>
                        <div style="font-size: 12px; color: #666;">今日 <span style="color: #F56C6C; font-weight: bold; font-size: 14px;">${m.orders}</span> 单</div>
                    </div>
                </div>
                <!-- Triangle -->
                <div style="width: 0; height: 0; border-left: 8px solid transparent; border-right: 8px solid transparent; border-top: 10px solid #fff; margin: 0 auto;"></div>
            </div>
            `;

      const label = new BMap.Label(html, { position: pt, offset: new BMap.Size(0, 0) });
      label.setStyle({ border: 'none', background: 'transparent' });
      map.addOverlay(label);
    });
  }

  // 2. Fulfiller
  if (filter === 'all' || filter === 'fulfillers') {
    ridersList.value.forEach((r) => {
      const pt = new BMap.Point(r.lng, r.lat);
      const borderColor = r.status === 'online' ? '#67C23A' : r.status === 'busy' ? '#409EFF' : '#DCDFE6';
      const pendingText =
        r.pendingCount > 0 ? `<span style="color:#67C23A;font-weight:bold;">挂${r.pendingCount}单</span>` : `<span style="color:#999;">挂0单</span>`;
      const avatar = r.avatar || 'https://cube.elemecdn.com/3/7c/3ea6beec64369c2642b92c6726f1epng.png';

      const html = `
            <div style="position:absolute; transform:translate(-50%, -100%); width: 200px; filter: drop-shadow(0 4px 10px rgba(0,0,0,0.2));">
                <div style="background:#fff; border-radius:8px; padding: 10px; display: flex; align-items: center; gap: 10px; position: relative;">
                    <!-- Close Icon -->
                    <div style="position: absolute; top: 2px; right: 6px; color: #999; font-size: 14px; cursor: pointer;">×</div>
                    
                    <!-- Avatar Ring -->
                    <div style="width: 44px; height: 44px; border-radius: 50%; border: 3px solid ${borderColor}; padding: 1px; flex-shrink: 0; box-sizing: border-box;">
                        <img src="${avatar}" style="width: 100%; height: 100%; border-radius: 50%; object-fit: cover;">
                    </div>
                    
                    <!-- Info -->
                    <div style="flex: 1; overflow: hidden;">
                        <div style="font-weight: bold; font-size: 13px; color: #333; margin-bottom: 2px;">[履约者]${r.name}</div>
                        <div style="font-size: 12px; color: #999;">${pendingText}</div>
                    </div>
                </div>
                 <!-- Triangle -->
                <div style="width: 0; height: 0; border-left: 6px solid transparent; border-right: 6px solid transparent; border-top: 8px solid #fff; margin: 0 auto;"></div>
            </div>
            `;

      const label = new BMap.Label(html, { position: pt, offset: new BMap.Size(0, 0) });
      label.setStyle({ border: 'none', background: 'transparent' });
      map.addOverlay(label);
    });
  }

  // 3. Orders (Blue/Purple)
  if (filter === 'all' || filter === 'orders') {
    filteredOrders.value.forEach((o) => {
      const pt = new BMap.Point(o.lng, o.lat);
      const marker = new BMap.Marker(pt);

      const labelContent = `<div style="border:1px solid #409EFF;background:#fff;color:#409EFF;padding:2px 6px;border-radius:4px;font-size:12px;">${o.type}</div>`;
      const label = new BMap.Label(labelContent, { position: pt, offset: new BMap.Size(-20, -35) });
      label.setStyle({ border: 'none', background: 'transparent' });

      map.addOverlay(marker);
      map.addOverlay(label);
    });
  }
};

const setMapFilter = (val) => {
  activeMapFilter.value = val;
};

const focusMapPoint = (lng, lat) => {
  if (!map) return;
  const pt = new BMap.Point(lng, lat);
  map.panTo(pt);
  map.setZoom(16);
};

watch(activeMapFilter, () => {
  refreshMarkers();
});

watch([currentOrderTab, currentRiderTab], () => {
  refreshMarkers();
});

onMounted(() => {
  getServiceList()
  getAreaStationList()
  loadBMapScript()
    .then(() => {
      initMap();
    })
    .catch((err) => {
      console.error('Map loading failed', err);
      ElMessage.error('地图加载失败，请检查网络');
    });
});

// Dispatch Dialog State
const dispatchDialogVisible = ref(false);
const currentDispatchOrder = ref(null);
const currentRider = ref(null);

const openDispatchDialog = (order) => {
  currentDispatchOrder.value = order;
  if (order.riderId) {
    currentRider.value = ridersList.value.find((r) => r.id === order.riderId) || null;
  } else {
    currentRider.value = null;
  }
  dispatchDialogVisible.value = true;
};

const handleDispatchSubmit = (data) => {
  dispatchDialogVisible.value = false;
  ElMessage.success('派单成功');

  if (currentDispatchOrder.value && currentDispatchOrder.value.status === 'pending_dispatch') {
    const idx = ordersList.value.findIndex((o) => o.id === currentDispatchOrder.value.id);
    if (idx !== -1) ordersList.value[idx].status = 'pending_accept';
  }
};

const filteredOrders = computed(() => {
  let result = ordersList.value;
  const statusMap = {
    'PendingDispatch': 'pending_dispatch',
    'PendingAccept': 'pending_accept',
    'Processing': 'processing'
  };
  const targetStatus = statusMap[currentOrderTab.value];
  if (targetStatus) {
    result = result.filter((o) => o.status === targetStatus);
  }
  if (filters.orderType !== 'all') {
    result = result.filter((o) => String(o.serviceId || o.service) === String(filters.orderType));
  }
  return result;
});

const filteredRiders = computed(() => {
  if (currentRiderTab.value === 'All') return ridersList.value;
  const map = {
    'Working': ['online', 'busy'],
    'Resting': ['offline'],
    'Disabled': ['disabled']
  };
  const allowed = map[currentRiderTab.value] || [];
  return ridersList.value.filter((r) => allowed.includes(r.status));
});
</script>

<style scoped>
.dispatch-container {
  height: calc(100vh - 84px);
  display: flex;
  flex-direction: column;
  background-color: #f0f2f5;
  overflow: hidden;
}

/* 1. Top Bar */
.top-filter-bar {
  height: 56px;
  background: #fff;
  border-bottom: 1px solid #e4e7ed;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 24px;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.02);
  z-index: 20;
}

/* 2. Main Content */
.main-content {
  flex: 1;
  display: flex;
  position: relative;
  overflow: hidden;
}

/* Left Map Area */
.map-wrapper {
  flex: 1;
  position: relative;
  background: #fcf9f2;
  overflow: hidden;
}

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

/* Map Controls */
.map-controls-panel {
  position: absolute;
  bottom: 24px;
  left: 24px;
  display: flex;
  align-items: center;
  gap: 16px;
  z-index: 10;
}

.control-group {
  background: #fff;
  border-radius: 8px;
  padding: 6px;
  display: flex;
  gap: 8px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}

.c-btn {
  padding: 6px 16px;
  border-radius: 6px;
  font-size: 13px;
  cursor: pointer;
  background: #f5f7fa;
  color: #606266;
  font-weight: 500;
  transition: all 0.2s;
}

.c-btn.active {
  background: #2d8cf0;
  color: #fff;
}

.c-btn.red {
  background: #fef0f0;
  color: #f56c6c;
  border: 1px solid #fde2e2;
}

.c-btn.green {
  background: #f0f9eb;
  color: #67c23a;
  border: 1px solid #e1f3d8;
}

.c-btn.gray {
  background: #f0f2f5;
  color: #909399;
  border: 1px solid #dcdfe6;
  cursor: default;
}

.c-btn.blue {
  background: #ecf5ff;
  color: #409eff;
  border: 1px solid #d9ecff;
}

/* Right Panel */
.right-panel {
  width: 440px;
  background: #fff;
  border-left: 1px solid #e4e7ed;
  display: flex;
  flex-direction: column;
  box-shadow: -4px 0 16px rgba(0, 0, 0, 0.05);
  z-index: 30;
}
</style>
