export default class UploadAdapter {
	constructor(loader, options) {
		this.loader = loader
		this.options = options
		this.timeout = 60000 // 60秒超时
	}

	upload() {
		return this.loader.file.then(
			(file) =>
				new Promise((resolve, reject) => {
					this._initRequest()
					this._initListeners(resolve, reject, file)
					this._sendRequest(file)
					this._initTimeout(reject)
				}),
		)
	}

	abort() {
		if (this.xhr) {
			this.xhr.abort()
		}
		if (this.timeoutId) {
			clearTimeout(this.timeoutId)
		}
	}

	_initRequest() {
		const xhr = (this.xhr = new XMLHttpRequest())

		xhr.open('POST', this.options.upload.uploadUrl, true)
		xhr.responseType = 'json'
	}

	_initListeners(resolve, reject, file) {
		const xhr = this.xhr
		const loader = this.loader
		const genericErrorText = `Couldn't upload file: ${file.name}.`

		xhr.addEventListener('error', () => {
			console.error('[UploadAdapter] Upload error for file:', file.name)
			reject(genericErrorText)
		})

		xhr.addEventListener('abort', () => {
			console.warn('[UploadAdapter] Upload aborted for file:', file.name)
			reject()
		})

		xhr.addEventListener('timeout', () => {
			console.error('[UploadAdapter] Upload timeout for file:', file.name)
			reject(`Upload timeout: ${file.name}. Please try again.`)
		})

		xhr.addEventListener('load', () => {
			const response = xhr.response

			// 检查响应状态码
			if (xhr.status >= 200 && xhr.status < 300) {
				if (!response) {
					console.error('[UploadAdapter] Empty response for file:', file.name)
					reject(genericErrorText)
					return
				}

				// 检查业务状态码（假设 code=1 表示成功）
				if (response.code == 1 || response.code == undefined) {
					const url = response.data?.url || response.data?.src
					if (!url) {
						console.error('[UploadAdapter] No URL in response for file:', file.name, response)
						reject('Upload succeeded but no URL returned')
						return
					}
					resolve({ default: url })
				} else {
					const errorMessage = response.message || genericErrorText
					console.error('[UploadAdapter] Upload failed for file:', file.name, 'Error:', errorMessage)
					reject(errorMessage)
				}
			} else {
				console.error('[UploadAdapter] HTTP error for file:', file.name, 'Status:', xhr.status)
				reject(`Server error (${xhr.status}): ${file.name}`)
			}
		})

		// 上传进度监听
		if (xhr.upload) {
			xhr.upload.addEventListener('progress', (evt) => {
				if (evt.lengthComputable) {
					loader.uploadTotal = evt.total
					loader.uploaded = evt.loaded
				}
			})
		}
	}

	_initTimeout(reject) {
		// 清除之前的超时定时器（如果有）
		if (this.timeoutId) {
			clearTimeout(this.timeoutId)
		}

		// 设置新的超时定时器
		this.timeoutId = setTimeout(() => {
			if (this.xhr) {
				this.xhr.abort()
				reject(new Error('Upload timeout'))
			}
		}, this.timeout)
	}

	_sendRequest(file) {
		// 设置请求超时
		this.xhr.timeout = this.timeout

		// Set headers if specified.
		const headers = this.options.upload.headers || {}
		const extendData = this.options.upload.extendData || {}
		// Use the withCredentials flag if specified.
		const withCredentials = this.options.upload.withCredentials || false
		const uploadName = this.options.upload.uploadName || 'file'

		for (const headerName of Object.keys(headers)) {
			this.xhr.setRequestHeader(headerName, headers[headerName])
		}

		this.xhr.withCredentials = withCredentials

		const data = new FormData()
		for (const key of Object.keys(extendData)) {
			data.append(key, extendData[key])
		}
		data.append(uploadName, file)

		this.xhr.send(data)
	}
}

export function UploadAdapterPlugin(editor) {
	editor.plugins.get('FileRepository').createUploadAdapter = (loader) => {
		return new UploadAdapter(loader, editor.config._config)
	}
}
