import { getBrowserPool } from './headless-pool'

export async function renderWeatherMap(
  type: string,
  data: {
    lat: number
    lng: number
    value: number
    description: number
    temperature: number
    humidity: number
    cloudCoverage: number
    solarRadiation: number
    windSpeed: number
    windDirection: number
    precipitation?: number
  }[],
  width: number = 1800,
  height: number = 900
): Promise<Buffer> {
  console.log(`renderWeatherMap 호출됨: 타입=${type}, 데이터 개수=${data.length}`)

  if (!data || data.length === 0) {
    throw new Error('데이터가 없습니다. PNG 생성을 중단합니다.')
  }

  const browser = await getBrowserPool().acquire()

  try {
    console.log('브라우저 인스턴스 획득')
    const page = await browser.newPage()

    // 모든 콘솔 로그를 캡처하여 Node.js 프로세스에 출력
    page.on('console', msg => {
      console.log(`PAGE LOG [${msg.type()}]: ${msg.text()}`)
    })

    // 오류 이벤트도 추적 (예: Unhandled Promise Rejection)
    page.on('pageerror', err => {
      console.error('BROWSER PAGE ERROR:', err)
    })

    await page.setViewport({ width, height })

    await page.setContent(`
      <!DOCTYPE html>
      <html>
        <head>
          <style>body { margin: 0; }</style>
        </head>
        <body>
          <canvas id="weatherCanvas" width="${width}" height="${height}"></canvas>
        </body>
      </html>
    `)

    console.log('HTML 콘텐츠 설정 완료')

    await page.evaluate(
      (type, data, width, height) => {
        try {
          console.log('Canvas 렌더링 시작')

          const canvas = document.getElementById('weatherCanvas') as HTMLCanvasElement
          if (!canvas) {
            throw new Error('캔버스를 찾을 수 없습니다.')
          }

          const ctx = canvas.getContext('2d')
          if (!ctx) {
            throw new Error('CanvasRenderingContext2D를 가져올 수 없습니다.')
          }

          ctx.clearRect(0, 0, width, height)

          function latLngToPixel(lat, lng) {
            if (isNaN(lat) || isNaN(lng)) return null
            const x = Math.floor(((lng + 180) / 360) * width)
            const y = Math.floor(((90 - lat) / 180) * height)
            if (x < 0 || x >= width || y < 0 || y >= height) return null
            return { x, y }
          }

          function valueToRGB(type, dataPoint) {
            if (!dataPoint || typeof dataPoint.value !== 'number') {
              console.warn('잘못된 데이터 포인트:', dataPoint)
              return { r: 0, g: 0, b: 0, a: 0 }
            }
            switch (type) {
              case 'temperature':
                return { r: Math.min(255, Math.max(0, (dataPoint.value + 50) * 2.55)), g: 0, b: 0, a: 255 }
              case 'humidity':
                return { r: 0, g: Math.min(255, Math.max(0, dataPoint.humidity * 2.55)), b: 0, a: 255 }
              case 'wind':
                return { r: Math.min(255, Math.max(0, dataPoint.windSpeed * 5)), g: 0, b: 255, a: 255 }
              case 'precipitation':
                return { r: 0, g: 0, b: Math.min(255, Math.max(0, dataPoint.precipitation * 2.55)), a: 255 }
              default:
                return { r: 255, g: 255, b: 255, a: 255 }
            }
          }

          function calculateColor(type, value) {
            switch (type) {
              case 'temperature':
                return { r: Math.min(255, Math.max(0, (value + 50) * 2.55)), g: 0, b: 0, a: 255 }
              case 'humidity':
                return { r: 0, g: Math.min(255, Math.max(0, value * 2.55)), b: 0, a: 255 }
              case 'wind':
                return { r: Math.min(255, Math.max(0, value * 5)), g: 0, b: 255, a: 255 }
              case 'precipitation':
                return { r: 0, g: 0, b: Math.min(255, Math.max(0, value * 2.55)), a: 255 }
              default:
                return { r: 255, g: 255, b: 255, a: 255 }
            }
          }

          function renderInterpolated(ctx, data, type, width, height) {
            const imageData = ctx.createImageData(width, height)
            const maxDistance = width * 0.05 // 최대 영향 거리 (이미지 너비의 5%)

            // 모든 픽셀에 대해 계산
            for (let y = 0; y < height; y++) {
              for (let x = 0; x < width; x++) {
                // 픽셀의 위/경도 계산
                const lng = (x / width) * 360 - 180
                const lat = 90 - (y / height) * 180

                // 역거리 가중치 보간법
                let weightedSum = 0
                let totalWeight = 0

                data.forEach(point => {
                  const pixelX = ((point.lng + 180) / 360) * width
                  const pixelY = ((90 - point.lat) / 180) * height
                  const distance = Math.sqrt(Math.pow(x - pixelX, 2) + Math.pow(y - pixelY, 2))

                  if (distance <= maxDistance && typeof point.value === 'number') {
                    const weight = 1 / (Math.pow(distance, 2) + 0.1)
                    weightedSum += point.value * weight
                    totalWeight += weight
                  }
                })

                const index = (y * width + x) * 4
                if (totalWeight > 0) {
                  const value = weightedSum / totalWeight
                  const color = calculateColor(type, value)

                  imageData.data[index] = color.r
                  imageData.data[index + 1] = color.g
                  imageData.data[index + 2] = color.b
                  imageData.data[index + 3] = color.a
                } else {
                  // 영향 범위 내 데이터 없음
                  imageData.data[index + 3] = 0 // 투명하게
                }
              }
            }

            ctx.putImageData(imageData, 0, 0)
          }

          // 보간 렌더링 호출
          renderInterpolated(ctx, data, type, width, height)

          console.log('Canvas 렌더링 완료')
          ;(window as any).renderComplete = true
        } catch (err) {
          console.error('렌더링 오류:', err)
          ;(window as any).renderComplete = false
        }
      },
      type,
      data,
      width,
      height
    )

    console.log('렌더링 완료')

    const renderComplete = await page
      .waitForFunction('window.renderComplete === true', { timeout: 10000 })
      .catch(err => {
        console.error('렌더링 완료 신호 감지 실패:', err)
        return false
      })

    if (!renderComplete) {
      throw new Error('렌더링이 완료되지 않았습니다.')
    }

    const pngBuffer = await page.screenshot({
      type: 'png',
      omitBackground: true
    })

    console.log(`PNG 생성 완료: ${pngBuffer.length} 바이트`)
    return pngBuffer
  } catch (error) {
    console.error('날씨 맵 렌더링 오류:', error)
    throw error
  } finally {
    await getBrowserPool().release(browser)
  }
}
