import crypto from 'node:crypto'
import https from 'node:https'

import { runtimeConfig } from '../src/config/runtime.js'

function percentEncode(value: string): string {
  return encodeURIComponent(String(value || ''))
    .replace(/\+/g, '%20')
    .replace(/\*/g, '%2A')
    .replace(/%7E/g, '~')
}

function signAliyunRequest(params: Record<string, string>, accessKeySecret: string): string {
  const canonicalizedQuery = Object.entries(params)
    .map(([key, value]) => `${percentEncode(key)}=${percentEncode(value)}`)
    .sort((left, right) =>
      String(left[0]) < String(right[0]) ? -1 : String(left[0]) > String(right[0]) ? 1 : 0,
    )
    .join('&')
  const stringToSign = `GET&${percentEncode('/')}&${percentEncode(canonicalizedQuery)}`
  const hmac = crypto.createHmac('sha1', `${accessKeySecret}&`)
  hmac.update(stringToSign)
  return hmac.digest('base64')
}

async function main() {
  const config = runtimeConfig.worker.sms
  console.log('当前短信配置：')
  console.log('  provider        :', config.provider)
  console.log(
    '  accessKeyId     :',
    config.accessKeyId
      ? `${config.accessKeyId.slice(0, 4)}...${config.accessKeyId.slice(-4)}`
      : '(空)',
  )
  console.log(
    '  accessKeySecret :',
    config.accessKeySecret
      ? `${config.accessKeySecret.slice(0, 4)}...${config.accessKeySecret.slice(-4)}（长度 ${config.accessKeySecret.length}）`
      : '(空)',
  )
  console.log('  signName        :', config.signName)
  console.log('  templateCode    :', config.templateCode)
  console.log('')

  if (!config.accessKeyId || !config.accessKeySecret || !config.signName || !config.templateCode) {
    console.error('配置不完整，请检查 .env 中的 WORKER_SMS_* 配置')
    return
  }

  const phone = process.argv[2] || '13800000000'
  const params: Record<string, string> = {
    AccessKeyId: config.accessKeyId,
    Action: 'SendSms',
    Format: 'JSON',
    Version: '2017-05-25',
    SignatureMethod: 'HMAC-SHA1',
    SignatureVersion: '1.0',
    SignatureNonce: crypto.randomUUID(),
    Timestamp: new Date().toISOString().replace(/\.\d{3}Z$/, 'Z'),
    PhoneNumbers: phone,
    SignName: config.signName,
    TemplateCode: config.templateCode,
    TemplateParam: JSON.stringify({ code: '123456' }),
  }

  const signature = signAliyunRequest(params, config.accessKeySecret)
  params.Signature = signature

  const queryString = Object.entries(params)
    .map(([key, value]) => `${percentEncode(key)}=${percentEncode(value)}`)
    .sort()
    .join('&')
  const url = `https://dysmsapi.aliyuncs.com/?${queryString}`

  console.log('stringToSign:')
  console.log(
    '  ',
    `GET&%2F&${percentEncode(
      Object.entries(params)
        .filter(([key]) => key !== 'Signature')
        .map(([key, value]) => `${percentEncode(key)}=${percentEncode(value)}`)
        .sort((left, right) =>
          String(left[0]) < String(right[0]) ? -1 : String(left[0]) > String(right[0]) ? 1 : 0,
        )
        .join('&'),
    )}`,
  )
  console.log('')
  console.log(`发送测试短信到 ${phone}（验证码 123456）...`)

  https
    .get(url, (response) => {
      const chunks: Buffer[] = []
      response.on('data', (chunk) => chunks.push(Buffer.from(chunk)))
      response.on('end', () => {
        const body = Buffer.concat(chunks).toString('utf8')
        console.log('响应:', body)
      })
    })
    .on('error', (error) => {
      console.error('请求失败:', error.message)
    })
}

void main()
