<template>
  <div class="grid-map-container">
    <div class="map-header">
      <h3>环境监测网格地图</h3>
      <div class="map-controls">
        <el-select v-model="selectedCity" placeholder="选择城市" @change="handleCityChange" size="small">
          <el-option v-for="city in cities" :key="city" :label="city" :value="city" />
        </el-select>
        <el-button type="primary" size="small" :icon="Loading" :loading="loading" @click="refreshData">
          刷新数据
        </el-button>
      </div>
    </div>
    <div class="map-content">
      <div class="map-container" ref="mapContainer">
        <div v-if="loading" class="loading-overlay">
          <el-icon class="loading-icon" :size="32"><Loading /></el-icon>
          <div class="loading-text">加载中...</div>
        </div>
      </div>
      
      <div class="map-legend">
        <div v-for="city in Object.keys(cityColorPalette)" :key="city" class="legend-item">
          <div class="legend-color" :style="{ backgroundColor: cityColorPalette[city] }"></div>
          <span>{{ city }}</span>
        </div>
        <div class="legend-item">
          <div class="legend-color" style="background-color: #333333;"></div>
          <span>障碍区域</span>
        </div>
      </div>
      
      <!-- 网格编辑/详情一体化对话框 -->
      <el-dialog
        v-model="gridEditDialogVisible"
        :title="editingGrid ? `编辑网格 (${editingGrid.gridX}, ${editingGrid.gridY})` : '网格详情'"
        width="600px"
        destroy-on-close
      >
        <el-form v-if="editingGrid" :model="editFormData" label-width="120px">
          <el-descriptions :column="1" border class="detail-view" v-if="!isEditMode">
            <el-descriptions-item label="城市">{{ editingGrid.cityName }}</el-descriptions-item>
            <el-descriptions-item label="区域">{{ editingGrid.districtName || '未指定' }}</el-descriptions-item>
            <el-descriptions-item label="状态">
              <el-tag :type="editingGrid.isObstacle ? 'danger' : currentWorkerInDialog ? 'success' : 'warning'" effect="dark">
                {{ editingGrid.isObstacle ? '障碍区域' : currentWorkerInDialog ? '已分配' : '未分配' }}
              </el-tag>
            </el-descriptions-item>
            <el-descriptions-item label="描述">{{ editFormData.description || '无' }}</el-descriptions-item>
            <el-descriptions-item label="网格员">
              <div v-if="currentWorkerInDialog">
                <strong>{{ currentWorkerInDialog.name }}</strong> (ID: {{ currentWorkerInDialog.id }})
              </div>
              <div v-else>未分配</div>
            </el-descriptions-item>
          </el-descriptions>

          <div v-if="isEditMode">
            <el-form-item label="描述">
              <el-input v-model="editFormData.description" type="textarea" :rows="3" placeholder="请输入网格描述" />
            </el-form-item>
            <el-form-item label="是否为障碍物">
              <el-switch v-model="editFormData.isObstacle" />
            </el-form-item>
            <div v-if="!editFormData.isObstacle">
              <el-divider>网格员分配</el-divider>
              <el-form-item label="分配网格员">
                <el-select v-model="editFormData.workerId" placeholder="选择或搜索网格员" clearable filterable style="width: 100%;">
                  <el-option 
                    v-for="worker in availableGridWorkers"
                    :key="worker.id"
                    :label="`${worker.name} (ID: ${worker.id})`"
                    :value="worker.id"
                  />
                </el-select>
              </el-form-item>
            </div>
          </div>
        </el-form>
        
        <template #footer>
          <span class="dialog-footer">
            <el-button @click="isEditMode = !isEditMode">{{ isEditMode ? '返回详情' : '编辑网格' }}</el-button>
            <el-button @click="gridEditDialogVisible = false">关闭</el-button>
            <el-button v-if="isEditMode" type="primary" @click="handleUpdateGrid" :loading="loading">保存</el-button>
          </span>
        </template>
      </el-dialog>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, onBeforeUnmount, computed } from 'vue';
import { 
  getGrids, 
  getGridWorkers, 
  updateGrid, 
  assignGridWorkerByCoordinates, 
  removeGridWorkerByCoordinates 
} from '@/api/grid';
import type { GridData, GridWorker } from '@/api/grid';
import { 
  ElMessage, 
  ElDialog, 
  ElDescriptions, 
  ElDescriptionsItem, 
  ElButton, 
  ElDivider, 
  ElTag, 
  ElSelect, 
  ElOption,
  ElForm,
  ElFormItem,
  ElInput,
  ElSwitch,
  ElAlert
} from 'element-plus';
import { Loading } from '@element-plus/icons-vue';

const loading = ref(false);
const selectedCity = ref<string>('北京市');
const cities = ref<string[]>(['北京市']);
const mapContainer = ref<HTMLDivElement | null>(null);
const gridData = ref<GridData[]>([]);
const gridWorkers = ref<GridWorker[]>([]);
const availableGridWorkers = ref<GridWorker[]>([]);

const gridEditDialogVisible = ref(false);
const editingGrid = ref<GridData | null>(null);
const isEditMode = ref(false);

const editFormData = ref({
  description: '',
  isObstacle: false,
  workerId: null as number | string | null,
});

const currentWorkerInDialog = computed(() => {
  if (!editingGrid.value) return null;
  return gridWorkers.value.find(w => w.gridX === editingGrid.value!.gridX && w.gridY === editingGrid.value!.gridY) || null;
});

let gridSize = 20;
const cityColorPalette: Record<string, string> = {};

const getCityColor = (cityName: string): string => {
  if (!cityColorPalette[cityName]) {
    const predefinedColors = ['#4e79a7', '#f28e2b', '#e15759', '#76b7b2', '#59a14f', '#edc948', '#b07aa1', '#ff9da7', '#9c755f', '#bab0ac'];
    const allCityNames = [...new Set(gridData.value.map(g => g.cityName))];
    const cityIndex = allCityNames.indexOf(cityName);
    cityColorPalette[cityName] = predefinedColors[cityIndex % predefinedColors.length];
  }
  return cityColorPalette[cityName];
};

const loadData = async () => {
  loading.value = true;
  try {
    const [grids, workers] = await Promise.all([
      getGrids(),
      getGridWorkers()
    ]);

    if (Array.isArray(grids)) {
      gridData.value = grids;
      const uniqueCities = [...new Set(grids.map(g => g.cityName))];
      if (uniqueCities.length > 0) {
        cities.value = uniqueCities;
        selectedCity.value = uniqueCities[0];
      }
    }
    
    if (Array.isArray(workers)) {
      gridWorkers.value = workers;
    }
    
    renderMap();
  } catch (error) {
    console.error('加载数据失败:', error);
    ElMessage.error('加载数据失败，请检查后端服务');
  } finally {
    loading.value = false;
  }
};

const fetchAvailableGridWorkers = async () => {
  try {
    const response = await getGridWorkers({ unassigned: true });
    availableGridWorkers.value = Array.isArray(response) ? response : [];
  } catch (error) {
    console.error('获取可用网格员数据失败:', error);
    ElMessage.error('获取可用网格员列表失败');
  }
};

const renderMap = () => {
  const container = mapContainer.value;
  if (!container || !gridData.value || gridData.value.length === 0) {
    if (container) container.innerHTML = '<div class="empty-state">没有可显示的网格数据</div>';
    return;
  }

  container.innerHTML = '';
  const allX = gridData.value.map(g => g.gridX);
  const allY = gridData.value.map(g => g.gridY);
  const minX = Math.min(...allX);
  const maxX = Math.max(...allX);
  const minY = Math.min(...allY);
  const maxY = Math.max(...allY);
  const worldWidth = maxX - minX + 1;
  const worldHeight = maxY - minY + 1;
  gridSize = Math.max(5, Math.floor(Math.min(container.clientWidth / worldWidth, container.clientHeight / worldHeight)));
  const svgWidth = worldWidth * gridSize;
  const svgHeight = worldHeight * gridSize;
  const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
  svg.setAttribute('width', `${svgWidth}px`);
  svg.setAttribute('height', `${svgHeight}px`);
  svg.setAttribute('viewBox', `0 0 ${svgWidth} ${svgHeight}`);

  gridData.value.forEach(grid => {
    const rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
    rect.setAttribute('x', `${(grid.gridX - minX) * gridSize}`);
    rect.setAttribute('y', `${(grid.gridY - minY) * gridSize}`);
    rect.setAttribute('width', `${gridSize}`);
    rect.setAttribute('height', `${gridSize}`);
    rect.setAttribute('fill', grid.isObstacle ? '#333333' : getCityColor(grid.cityName));
    rect.setAttribute('stroke-width', '0.5');
    rect.setAttribute('stroke', '#fff');
    rect.setAttribute('cursor', 'pointer');
    rect.addEventListener('click', () => showGridDialog(grid));
    svg.appendChild(rect);
  });
  container.appendChild(svg);
};

const showGridDialog = async (grid: GridData) => {
  isEditMode.value = false;
  editingGrid.value = grid;
  const currentWorker = gridWorkers.value.find(w => w.gridX === grid.gridX && w.gridY === grid.gridY);
  
  editFormData.value = {
    description: grid.description || '',
    isObstacle: grid.isObstacle,
    workerId: currentWorker ? currentWorker.id : '',
  };
  
  await fetchAvailableGridWorkers();
  gridEditDialogVisible.value = true;
};

const handleUpdateGrid = async () => {
  if (!editingGrid.value) return;

  loading.value = true;
  const grid = editingGrid.value;
  const { isObstacle, description, workerId } = editFormData.value;
  const newWorkerId = workerId ? Number(workerId) : null;

  try {
    await updateGrid({ ...grid, isObstacle, description });
    
    const workerAssignmentChanged = (currentWorkerInDialog.value?.id ?? null) !== newWorkerId;

    if (isObstacle && currentWorkerInDialog.value) {
      await removeGridWorkerByCoordinates(grid.gridX, grid.gridY);
    } else if (!isObstacle && workerAssignmentChanged) {
      if (newWorkerId) {
        await assignGridWorkerByCoordinates(grid.gridX, grid.gridY, newWorkerId);
      } else if (currentWorkerInDialog.value) {
        await removeGridWorkerByCoordinates(grid.gridX, grid.gridY);
      }
    }
    ElMessage.success('网格信息更新成功');
    gridEditDialogVisible.value = false;
    await loadData();
  } catch (error: any) {
    ElMessage.error('更新网格失败: ' + (error?.response?.data?.message || error.message));
  } finally {
    loading.value = false;
  }
};

const refreshData = () => loadData();
const handleCityChange = () => { /* Future implementation for city-specific view */ };

onMounted(() => {
  loadData();
  window.addEventListener('resize', renderMap);
});
onBeforeUnmount(() => {
  window.removeEventListener('resize', renderMap);
});
</script>

<style scoped>
.grid-map-container {
  display: flex;
  flex-direction: column;
  height: 100%;
  background: #fff;
  border-radius: 8px;
}
.map-header {
  padding: 15px 20px;
  border-bottom: 1px solid #ebeef5;
}
.map-content {
  flex: 1;
  display: flex;
  flex-direction: column;
  padding: 15px;
  overflow: hidden;
}
.map-container {
  flex: 1;
  position: relative;
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  overflow: auto;
}
.map-legend {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 15px;
  padding-top: 15px;
}
.legend-item { display: flex; align-items: center; }
.legend-color { width: 16px; height: 16px; margin-right: 8px; border-radius: 4px; }
.dialog-footer { text-align: right; }
.detail-view { margin-bottom: 20px; }
</style> 