// cables.js - Cable loading and rendering module

import * as THREE from 'three';

import { CONFIG, CABLE_COLORS, PATHS, CABLE_STATE } from './constants.js';
import { latLonToVector3 } from './utils.js';
import { updateEarthStats, showStatusMessage } from './ui.js';
import { showInfoCard } from './info-card.js';

export let cableLines = [];
export let landingPoints = [];
export let lockedCable = null;
let cableIdMap = new Map();
let cablesVisible = true;

function getCableColor(properties) {
  if (properties.color) {
    if (typeof properties.color === 'string' && properties.color.startsWith('#')) {
      return parseInt(properties.color.substring(1), 16);
    } else if (typeof properties.color === 'number') {
      return properties.color;
    }
  }
  
  const cableName = properties.Name || properties.cableName || properties.shortname || '';
  if (cableName.includes('Americas II')) {
    return CABLE_COLORS['Americas II'];
  } else if (cableName.includes('AU Aleutian A')) {
    return CABLE_COLORS['AU Aleutian A'];
  } else if (cableName.includes('AU Aleutian B')) {
    return CABLE_COLORS['AU Aleutian B'];
  }
  
  return CABLE_COLORS.default;
}

function createCableLine(points, color, properties, earthObj) {
  if (points.length < 2) return null;
  
  const lineGeometry = new THREE.BufferGeometry().setFromPoints(points);
  
  const lineMaterial = new THREE.LineBasicMaterial({ 
    color: color,
    linewidth: 1,
    transparent: true,
    opacity: 1.0,
    depthTest: true,
    depthWrite: true
  });
  
  const cableLine = new THREE.Line(lineGeometry, lineMaterial);
  const cableId = properties.cable_id || properties.id || properties.Name || Math.random().toString(36);
  cableLine.userData = {
    type: 'cable',
    cableId: cableId,
    name: properties.Name || properties.cableName || 'Unknown',
    owner: properties.owner || properties.owners || '-',
    status: properties.status || '-',
    length: properties.length || '-',
    coords: '-',
    rfs: properties.rfs || '-',
    originalColor: color
  };
  cableLine.renderOrder = 1;
  
  if (!cableIdMap.has(cableId)) {
    cableIdMap.set(cableId, []);
  }
  cableIdMap.get(cableId).push(cableLine);
  
  return cableLine;
}

function calculateGreatCirclePoints(lat1, lon1, lat2, lon2, radius, segments = 50) {
  const points = [];
  const phi1 = lat1 * Math.PI / 180;
  const lambda1 = lon1 * Math.PI / 180;
  const phi2 = lat2 * Math.PI / 180;
  const lambda2 = lon2 * Math.PI / 180;
  
  const dLambda = Math.min(Math.abs(lambda2 - lambda1), 2 * Math.PI - Math.abs(lambda2 - lambda1));
  const cosDelta = Math.sin(phi1) * Math.sin(phi2) + Math.cos(phi1) * Math.cos(phi2) * Math.cos(dLambda);
  
  let delta = Math.acos(Math.max(-1, Math.min(1, cosDelta)));
  
  if (delta < 0.01) {
    const p1 = latLonToVector3(lat1, lon1, radius);
    const p2 = latLonToVector3(lat2, lon2, radius);
    return [p1, p2];
  }
  
  for (let i = 0; i <= segments; i++) {
    const t = i / segments;
    const sinDelta = Math.sin(delta);
    const A = Math.sin((1 - t) * delta) / sinDelta;
    const B = Math.sin(t * delta) / sinDelta;
    
    const x1 = Math.cos(phi1) * Math.cos(lambda1);
    const y1 = Math.cos(phi1) * Math.sin(lambda1);
    const z1 = Math.sin(phi1);
    
    const x2 = Math.cos(phi2) * Math.cos(lambda2);
    const y2 = Math.cos(phi2) * Math.sin(lambda2);
    const z2 = Math.sin(phi2);
    
    let x = A * x1 + B * x2;
    let y = A * y1 + B * y2;
    let z = A * z1 + B * z2;
    
    const norm = Math.sqrt(x*x + y*y + z*z);
    x = x / norm * radius;
    y = y / norm * radius;
    z = z / norm * radius;
    
    const lat = Math.asin(z / radius) * 180 / Math.PI;
    let lon = Math.atan2(y, x) * 180 / Math.PI;
    
    if (lon > 180) lon -= 360;
    if (lon < -180) lon += 360;
    
    const point = latLonToVector3(lat, lon, radius);
    points.push(point);
  }
  
  return points;
}

export async function loadGeoJSONFromPath(scene, earthObj) {
  try {
    console.log('正在加载电缆数据...');
    showStatusMessage('正在加载电缆数据...', 'warning');
    
    const response = await fetch(PATHS.cablesApi);
    if (!response.ok) {
      throw new Error(`HTTP错误: ${response.status}`);
    }
    
    const data = await response.json();
    
    cableLines.forEach(line => earthObj.remove(line));
    cableLines = [];
    
    if (!data.features || !Array.isArray(data.features)) {
      throw new Error('无效的GeoJSON格式');
    }
    
    const cableCount = data.features.length;
    document.getElementById('cable-count').textContent = cableCount + '个';
    
    const inServiceCount = data.features.filter(
      feature => feature.properties && feature.properties.status === 'In Service'
    ).length;
    
    const statusEl = document.getElementById('cable-status-summary');
    if (statusEl) {
      statusEl.textContent = `${inServiceCount}/${cableCount} 运行中`;
    }
    
    for (const feature of data.features) {
      const geometry = feature.geometry;
      const properties = feature.properties || {};
      
      if (!geometry || !geometry.coordinates) continue;
      
      const color = getCableColor(properties);
      console.log('电缆 properties:', JSON.stringify(properties));
      
      if (geometry.type === 'MultiLineString') {
        for (const lineCoords of geometry.coordinates) {
          if (!lineCoords || lineCoords.length < 2) continue;
          
          const points = [];
          for (let i = 0; i < lineCoords.length - 1; i++) {
            const lon1 = lineCoords[i][0];
            const lat1 = lineCoords[i][1];
            const lon2 = lineCoords[i + 1][0];
            const lat2 = lineCoords[i + 1][1];
            
            const segment = calculateGreatCirclePoints(lat1, lon1, lat2, lon2, 100.2, 50);
            if (i === 0) {
              points.push(...segment);
            } else {
              points.push(...segment.slice(1));
            }
          }
          
          if (points.length >= 2) {
            const line = createCableLine(points, color, properties, earthObj);
            if (line) {
              cableLines.push(line);
              earthObj.add(line);
              console.log('添加线缆成功');
            }
          }
        }
      } else if (geometry.type === 'LineString') {
        const allCoords = geometry.coordinates;
        const points = [];
        
        for (let i = 0; i < allCoords.length - 1; i++) {
          const lon1 = allCoords[i][0];
          const lat1 = allCoords[i][1];
          const lon2 = allCoords[i + 1][0];
          const lat2 = allCoords[i + 1][1];
          
          const segment = calculateGreatCirclePoints(lat1, lon1, lat2, lon2, 100.2, 50);
          if (i === 0) {
            points.push(...segment);
          } else {
            points.push(...segment.slice(1));
          }
        }
        
        if (points.length >= 2) {
          const line = createCableLine(points, color, properties, earthObj);
          if (line) {
            cableLines.push(line);
            earthObj.add(line);
          }
        }
      }
    }
    
    updateEarthStats({
      cableCount: cableLines.length,
      landingPointCount: landingPoints.length,
      terrainOn: false,
      textureQuality: '8K 卫星图'
    });
    
    showStatusMessage(`成功加载 ${cableLines.length} 条电缆`, 'success');
    document.getElementById('loading').style.display = 'none';
    
  } catch (error) {
    console.error('加载电缆数据失败:', error);
    showStatusMessage('加载电缆数据失败: ' + error.message, 'error');
  }
}

export async function loadLandingPoints(scene, earthObj) {
  try {
    console.log('正在加载登陆点数据...');
    
    const response = await fetch(PATHS.landingPointsApi);
    if (!response.ok) {
      console.error('HTTP错误:', response.status);
      return;
    }
    
    const data = await response.json();
    
    if (!data.features || !Array.isArray(data.features)) {
      console.error('无效的GeoJSON格式');
      return;
    }
    
    landingPoints = [];
    let validCount = 0;
    
    const sphereGeometry = new THREE.SphereGeometry(0.4, 16, 16);
    const sphereMaterial = new THREE.MeshStandardMaterial({
      color: 0xffaa00,
      emissive: 0x442200,
      emissiveIntensity: 0.5
    });
    
    for (const feature of data.features) {
      if (!feature.geometry || !feature.geometry.coordinates) continue;
      
      const [lon, lat] = feature.geometry.coordinates;
      const properties = feature.properties || {};
      
      if (typeof lon !== 'number' || typeof lat !== 'number' ||
          isNaN(lon) || isNaN(lat) ||
          Math.abs(lat) > 90 || Math.abs(lon) > 180) {
        continue;
      }
      
      const position = latLonToVector3(lat, lon, 100.1);
      
      if (isNaN(position.x) || isNaN(position.y) || isNaN(position.z)) {
        continue;
      }
      
      const sphere = new THREE.Mesh(sphereGeometry, sphereMaterial.clone());
      sphere.position.copy(position);
      sphere.userData = {
        type: 'landingPoint',
        name: properties.name || '未知登陆站',
        cableNames: properties.cable_names || [],
        country: properties.country || '未知国家',
        status: properties.status || 'Unknown'
      };
      
      earthObj.add(sphere);
      landingPoints.push(sphere);
      validCount++;
    }
    
    console.log(`成功创建 ${validCount} 个登陆点标记`);
    showStatusMessage(`成功加载 ${validCount} 个登陆点`, 'success');
    
    const lpCountEl = document.getElementById('landing-point-count');
    if (lpCountEl) {
      lpCountEl.textContent = validCount + '个';
    }
    
  } catch (error) {
    console.error('加载登陆点数据失败:', error);
  }
}

export function handleCableClick(cable) {
  lockedCable = cable;
  
  const data = cable.userData;
  showInfoCard('cable', {
    name: data.name,
    owner: data.owner,
    status: data.status,
    length: data.length,
    coords: data.coords,
    rfs: data.rfs
  });
  
  showStatusMessage(`已锁定: ${data.name}`, 'info');
}

export function clearCableSelection() {
  lockedCable = null;
}

export function getCableLines() {
  return cableLines;
}

export function getCablesById(cableId) {
  return cableIdMap.get(cableId) || [];
}

export function getLandingPoints() {
  return landingPoints;
}

const cableStates = new Map();

export function getCableState(cableId) {
  return cableStates.get(cableId) || CABLE_STATE.NORMAL;
}

export function setCableState(cableId, state) {
  cableStates.set(cableId, state);
}

export function clearAllCableStates() {
  cableStates.clear();
}

export function getCableStateInfo() {
  const states = {};
  cableStates.forEach((state, cableId) => {
    states[cableId] = state;
  });
  return states;
}

export function getLandingPointsByCableName(cableName) {
  return landingPoints.filter(lp => lp.userData.cableNames?.includes(cableName));
}

export function getAllLandingPoints() {
  return landingPoints;
}

export function applyLandingPointVisualState(lockedCableName, dimAll = false) {
  const pulse = (Math.sin(Date.now() * 0.003) + 1) * 0.5;
  const brightness = 0.3;
  
  landingPoints.forEach(lp => {
    const isRelated = !dimAll && lp.userData.cableNames?.includes(lockedCableName);
    
    if (isRelated) {
      lp.material.color.setHex(0xffaa00);
      lp.material.emissive.setHex(0x442200);
      lp.material.emissiveIntensity = 0.5 + pulse * 0.5;
      lp.material.opacity = 0.8 + pulse * 0.2;
      lp.scale.setScalar(1.2 + pulse * 0.3);
    } else {
      const r = 255 * brightness;
      const g = 170 * brightness;
      const b = 0 * brightness;
      lp.material.color.setRGB(r / 255, g / 255, b / 255);
      lp.material.emissive.setHex(0x000000);
      lp.material.emissiveIntensity = 0;
      lp.material.opacity = 0.3;
      lp.scale.setScalar(1.0);
    }
  });
}

export function resetLandingPointVisualState() {
  landingPoints.forEach(lp => {
    lp.material.color.setHex(0xffaa00);
    lp.material.emissive.setHex(0x442200);
    lp.material.emissiveIntensity = 0.5;
    lp.material.opacity = 1.0;
    lp.scale.setScalar(1.0);
  });
}

export function toggleCables(show) {
  cablesVisible = show;
  cableLines.forEach(cable => {
    cable.visible = cablesVisible;
  });
  landingPoints.forEach(lp => {
    lp.visible = cablesVisible;
  });
}

export function getShowCables() {
  return cablesVisible;
}
