import CryptoJS from 'crypto-js'
import {Base64} from 'js-base64'
import {i18n} from '@/locale'

// === 👉 请在这里填写你的 AWS 信息 ===
const S3Config = {
    bucket: 'cheflink',      // 你的存储桶名称
    region: 'us-east-1',   // 桶所在区域
    accessKeyId: 'AKIA3LKQVMAPD3KFPJGS',
    secretKey: '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',
    timeout: 0.1 // 签名有效时间（小时）
}

// === 签名函数 ===
function getPolicyBase64(): string {
    const expiration = new Date(Date.now() + 10 * 60 * 1000).toISOString() // 10分钟有效
    const policyText = {
        expiration,
        conditions: [
            {bucket: S3Config.bucket},
            ['starts-with', '$key', 'cheflink/'],
            ['starts-with', '$Content-Type', 'image/']
        ]
    }
    return Base64.encode(JSON.stringify(policyText))
}


function getSignature(policyBase64: string): string {
    const bytes = CryptoJS.HmacSHA1(policyBase64, S3Config.secretKey)
    return CryptoJS.enc.Base64.stringify(bytes)
}

// === 图片压缩函数 ===
function compressImageIfNeeded(filePath: string, size: number): Promise<string> {
    return new Promise((resolve, reject) => {
        // #ifdef APP-PLUS
        if (size > 3 * 1024 * 1024) {
            uni.compressImage({
                src: filePath,
                quality: 70,
                success: res => {
                    uni.getFileInfo({
                        filePath: res.tempFilePath,
                        success: info => resolve(res.tempFilePath),
                        fail: () => resolve(res.tempFilePath),
                    })
                },
                fail: err => reject(err),
            })
        } else {
            resolve(filePath)
        }
        // #endif

        // #ifdef H5
        if (size > 3 * 1024 * 1024) {
            const img = new Image()
            img.crossOrigin = 'Anonymous'
            img.onload = function () {
                const canvas = document.createElement('canvas')
                canvas.width = img.width
                canvas.height = img.height
                const ctx = canvas.getContext('2d')
                ctx?.drawImage(img, 0, 0, img.width, img.height)
                canvas.toBlob(
                    blob => {
                        if (blob) {
                            const url = URL.createObjectURL(blob)
                            resolve(url)
                        } else {
                            reject(new Error('图片压缩失败'))
                        }
                    },
                    'image/jpeg',
                    0.7
                )
            }
            img.onerror = () => reject(new Error('图片加载失败'))
            img.src = filePath
        } else {
            resolve(filePath)
        }
        // #endif

        // #ifndef APP-PLUS || H5
        resolve(filePath)
        // #endif
    })
}

// === S3 上传函数 ===
const uploadToS3 = async function (filePath: string, suffix = '.jpg', dir = 'cheflink/'): Promise<string> {
    if (!filePath) {
        uni.showToast({icon: 'none', title: i18n.global.t('common.prompt.picture-wrong-please-try-again')})
        return Promise.reject(new Error('filePath is empty'))
    }

    // 获取文件信息
    let fileInfo: UniApp.GetFileInfoSuccessCallbackResult
    try {
        fileInfo = await new Promise((resolve, reject) => {
            uni.getFileInfo({
                filePath,
                success: resolve,
                fail: reject,
            })
        })
    } catch (err) {
        uni.showToast({icon: 'none', title: i18n.global.t('common.prompt.request-incorrect')})
        return Promise.reject(err)
    }

    // 压缩图片（如果大于 3MB）
    let uploadPath: string
    try {
        uploadPath = await compressImageIfNeeded(filePath, fileInfo.size)
    } catch (err) {
        uni.showToast({icon: 'none', title: i18n.global.t('common.prompt.request-incorrect')})
        return Promise.reject(err)
    }

    // 文件名
    const filename = Date.now() + Math.floor(Math.random() * 1000) + suffix
    const key = dir + filename
    const policyBase64 = getPolicyBase64()
    const signature = getSignature(policyBase64)
    const uploadUrl = `https://${S3Config.bucket}.s3.${S3Config.region}.amazonaws.com/`

    return new Promise((resolve, reject) => {
        uni.uploadFile({
            url: uploadUrl,
            filePath: uploadPath,
            name: 'file',
            formData: {
                key,
                AWSAccessKeyId: S3Config.accessKeyId,
                policy: policyBase64,
                signature,
                'Content-Type': 'image/jpeg',
            },
            success: res => {
                if (res.statusCode === 204) {
                    uni.showToast({icon: 'none', title: i18n.global.t('common.operation-success')})
                    resolve(`${uploadUrl}${key}`)
                } else {
                    uni.showToast({icon: 'none', title: i18n.global.t('common.prompt.up-failed')})
                    reject(new Error(`上传失败，状态码: ${res.statusCode}`))
                }
            },
            fail: err => {
                uni.showToast({
                    icon: 'none',
                    title: i18n.global.t('common.prompt.request-failed-please-try-again-later')
                })
                reject(err)
            }
        })
    })
}

export {uploadToS3}

