/**
 * 围栏生成Hook
 * 提供在3D地图上生成围栏的功能
 * 基于THREE.js实现3D围栏的创建、纹理生成和材质配置
 * 
 * @param {Object} options - 围栏配置选项
 * @param {number} options.height - 围栏高度，默认值为20
 * @param {string} options.color - 围栏颜色，默认值为橙色'#ff7f50'
 * @param {boolean} options.isCloseTop - 是否封闭顶部，默认值为false（不封闭）
 * @returns {Object} - 包含生成围栏函数的对象
 */
export function useFence({height = 20, isCloseTop = false, color = '#ff7f50'}) {
  const { THREE } = window.VgoMap

  /**
 * 生成围栏材质纹理
 * 使用64x64的HTML5 Canvas创建垂直渐变纹理
 * 纹理将用于围栏的侧面材质
 */
const tex = generateTexture(64)
// 设置纹理的重复模式为REPEAT
if(tex) {
  tex.wrapT = tex.wrapS = THREE.RepeatWrapping
}

/**
   * 生成围栏函数
   * 创建一个3D围栏网格对象，使用THREE.js的ExtrudeGeometry实现挤出效果
   * 
   * @param {Array<THREE.Vector3>} points - 围栏的顶点数组，按顺时针或逆时针顺序排列
   * @returns {THREE.Mesh} - 生成的围栏3D网格对象
   */
  function generateFence(points) {
    // 创建THREE.js形状对象
    const shape = new THREE.Shape()
    // 根据输入的顶点数组设置形状
    shape.setFromPoints(points)
    
    // 创建挤出几何体，将2D形状挤出为3D围栏
    const geo = new THREE.ExtrudeGeometry(shape, {
      steps: 2,          // 挤出的层数
      depth: height,     // 挤出的深度（围栏高度）
      bevelEnabled: false, // 禁用斜角
    })
    
    // 创建围栏材质数组
    const mater = [
      // 顶部材质
      new THREE.MeshBasicMaterial({
        color,
        transparent: true,
        opacity: 0.1,
        visible: isCloseTop, // 根据配置决定是否显示顶部
      }),
      // 侧面材质
      new THREE.MeshBasicMaterial({
        map: tex,        // 使用渐变纹理
        transparent: true,
        color,
        opacity: 0.1,
        side: 2,         // 设置为双面显示（THREE.DoubleSide）
      })
    ]
    
    // 创建围栏网格对象
    const mesh = new THREE.Mesh(geo, mater)
    
    // 统一设置所有材质的透明度为0.7
    mesh.material.forEach(m => m.opacity = 0.7)
    
    return mesh
  }

/**
   * 生成纹理函数
   * 创建一个垂直渐变的HTML5 Canvas纹理，用于围栏侧面的材质
   * 
   * @param {number} size - 纹理大小，默认值为64
   * @returns {THREE.Texture|null} - 生成的THREE.js纹理对象，如果创建失败则返回null
   */
  function generateTexture (size = 64) {
    // 创建HTML5 Canvas元素
    let canvas = document.createElement('canvas')
    canvas.width = size
    canvas.height = size
    
    // 获取Canvas 2D上下文
    let ctx = canvas.getContext('2d')
    if(!ctx) return null // 如果无法获取上下文，则返回null
    
    // 创建垂直线性渐变
    let linearGradient = ctx.createLinearGradient(0, 0, 0, size)
    // 顶部：完全透明
    linearGradient.addColorStop(0.2, hexToRgba(color, 0.0))
    // 中部：半透明
    linearGradient.addColorStop(0.8, hexToRgba(color, 0.5))
    // 底部：不透明
    linearGradient.addColorStop(1.0, hexToRgba(color, 1.0))
    
    // 使用渐变填充整个Canvas
    ctx.fillStyle = linearGradient
    ctx.fillRect(0, 0, size, size)

    // 创建THREE.js纹理对象
    let texture = new THREE.Texture(canvas)
    texture.needsUpdate = true // 必须设置为true，通知THREE.js更新纹理
    
    return texture
  }

/**
   * 将十六进制颜色转换为RGBA格式
   * 用于在Canvas绘制时设置带透明度的颜色
   * 
   * @param {string} hex - 十六进制颜色值，格式为'#RRGGBB'
   * @param {number} opacity - 透明度，取值范围为0-1，默认值为1（完全不透明）
   * @returns {string} - RGBA格式的颜色字符串，格式为'rgba(R,G,B,A)'
   */
  function hexToRgba (hex, opacity = 1) {
    // 提取R、G、B分量并转换为十进制
    const r = parseInt('0x' + hex.slice(1, 3))
    const g = parseInt('0x' + hex.slice(3, 5))
    const b = parseInt('0x' + hex.slice(5, 7))
    
    // 构造并返回RGBA格式的颜色字符串
    return `rgba(${r},${g},${b},${opacity})`
  }
  
/**
   * 返回hook提供的函数
   * 将内部实现的generateFence函数暴露给外部使用
   */
  return {
    generateFence, // 生成围栏的主要函数
  }
}