import { get } from '@/core/http/http-client'
import { HttpError } from '@/core/http/http-error'
import { parseApiResponse, snapshotEnvelope } from '@/core/http/response-evaluator'
import { buildRestPath } from '@/core/config/api-paths'
import appSettings from '@/core/config/app-settings'
import { pullHomeCategories } from '@/features/travel/gateway'

const uploadConfigPath = () => buildRestPath('common/uploadData')
const publishPath = () => buildRestPath('find/find/addData')
const videoUploadPath = () => '/common/localuploadvideo'

function resolveUploadUrl(path) {
	if (!path) return ''
	if (/^https?:\/\//.test(path)) return path
	if (path.startsWith('//')) return `https:${path}`
	const base = (appSettings.appurl || '').replace(/\/$/, '')
	return `${base}${path.startsWith('/') ? path : `/${path}`}`
}

function unwrapUploadConfig(payload) {
	const body = payload && typeof payload === 'object' ? payload : {}
	if (body.uploadurl) return body
	if (body.data && typeof body.data === 'object') return body.data
	return body
}

function parseUploadResponse(raw) {
	if (!raw) return ''
	if (typeof raw === 'string') {
		try {
			const parsed = JSON.parse(raw)
			if (parsed.data && parsed.data.fullurl) return parsed.data.fullurl
			if (parsed.data && parsed.data.url) return parsed.data.url
			if (parsed.fullurl) return parsed.fullurl
			if (parsed.url) return parsed.url
		} catch (_) {
			return ''
		}
	}
	if (typeof raw === 'object') {
		if (raw.data && raw.data.fullurl) return raw.data.fullurl
		if (raw.data && raw.data.url) return raw.data.url
		if (raw.fullurl) return raw.fullurl
		if (raw.url) return raw.url
	}
	return ''
}

/**
 * 上传前解码并压缩图片，降低 App 端大图 / HEIC 导致的内存闪退。
 * 
 * @param {string} src
 * @returns {Promise<string>} 可用于 uploadFile 的本地路径
 */
export function prepareImageForUpload(src) {
	return new Promise((resolve) => {
		const fallback = () => resolve(src || '')
		if (!src) {
			fallback()
			return
		}
		const compress = (path, width = 0, height = 0) => {
			if (typeof uni.compressImage !== 'function') {
				resolve(path)
				return
			}
			const opts = {
				src: path,
				quality: 60,
				success: (res) => resolve((res && res.tempFilePath) || path),
				fail: () => resolve(path)
			}
			const w = Number(width) || 0
			const h = Number(height) || 0
			if (w > 1280 || h > 1280) {
				if (w >= h) opts.compressedWidth = 1280
				else opts.compressedHeight = 1280
			}
			try {
				uni.compressImage(opts)
			} catch (_) {
				resolve(path)
			}
		}
		uni.getImageInfo({
			src,
			success: (info) => {
				const path = (info && info.path) || src
				compress(path, info && info.width, info && info.height)
			},
			fail: () => {
				// 解码失败时仍尝试压缩原路径（部分机型 getImageInfo 对 HEIC 不稳定）
				compress(src)
			}
		})
	})
}

/**
 * 获取图片上传配置（wanlshop/common/uploadData）
 */
export async function fetchUploadConfig() {
	const { data, raw } = await get(uploadConfigPath())
	const cfg = unwrapUploadConfig(data)
	if (cfg.uploadurl) return cfg
	return unwrapUploadConfig(raw?.res?.data ?? raw?.data)
}

/**
 * 上传单张图片，返回相对路径 url
 */
export function uploadImageFile(filePath, config) {
	return new Promise((resolve, reject) => {
		const uploadurl = resolveUploadUrl(config && config.uploadurl)
		if (!uploadurl) {
			reject(new Error('上传地址无效'))
			return
		}
		if (!filePath) {
			reject(new Error('图片文件无效'))
			return
		}
		const opts = {
			url: uploadurl,
			filePath,
			name: 'file',
			success: (res) => {
				const url = parseUploadResponse(res.data)
				if (url) resolve(url)
				else reject(new Error('上传失败'))
			},
			fail: (err) => reject(err || new Error('上传失败'))
		}
		// local 不传 formData；非 local 才带 multipart（与参考工程一致）
		if (config && config.storage !== 'local' && config.multipart) {
			opts.formData = config.multipart
		}
		uni.uploadFile(opts)
	})
}

function postFindData(body) {
	return new Promise((resolve, reject) => {
		let settled = false
		const finish = (fn, value) => {
			if (settled) return
			settled = true
			fn(value)
		}
		uni.request({
			url: publishPath(),
			method: 'POST',
			data: body,
			success(res) {
				try {
					snapshotEnvelope(res)
					const parsed = parseApiResponse(res)
					if (parsed.kind === 'success' || parsed.kind === 'passthrough') {
						finish(resolve, parsed.data)
						return
					}
					finish(reject, HttpError.fromParsed(parsed))
				} catch (err) {
					finish(reject, err)
				}
			},
			fail(err) {
				finish(reject, HttpError.fromNetwork(err))
			},
			complete() {
				setTimeout(() => {
					if (!settled) {
						finish(reject, new HttpError('BUSINESS', '发布失败'))
					}
				}, 0)
			}
		})
	})
}

function normalizeRelativeVideoPath(path) {
	if (!path) return ''
	const raw = String(path).replace(/\\\//g, '/')
	if (/^https?:\/\//i.test(raw)) {
		const match = raw.match(/^https?:\/\/[^/]+(\/.*)$/i)
		return match ? match[1] : raw
	}
	return raw.startsWith('/') ? raw : `/${raw}`
}

function resolveVideoPreviewUrl(data) {
	if (!data || typeof data !== 'object') return ''
	const full = data.fullurl || data.full_url || ''
	if (full) return String(full).replace(/\\\//g, '/')
	const rel = normalizeRelativeVideoPath(data.url || '')
	if (!rel) return ''
	const base = (appSettings.cdnurl || appSettings.appurl || '')
		.replace(/\/api\/?$/i, '')
		.replace(/\/$/, '')
	return `${base}${rel}`
}

function parseVideoUploadEnvelope(raw) {
	if (!raw) return null
	let envelope = raw
	if (typeof raw === 'string') {
		try {
			envelope = JSON.parse(raw)
		} catch (_) {
			return null
		}
	}
	const body = envelope && envelope.data
	if (body && body.video_id != null && (envelope.code === 1 || envelope.code === '1')) {
		return {
			video_id: body.video_id,
			url: normalizeRelativeVideoPath(body.url || ''),
			previewUrl: resolveVideoPreviewUrl(body)
		}
	}
	return null
}

/**
 * 视频标签列表（/appvideolabel/list）
 */
export async function fetchVideoLabels() {
	try {
		return await pullHomeCategories()
	} catch (_) {
		return []
	}
}

/**
 * 上传短视频（/common/localuploadvideo）
 */
export function uploadVideoFile(filePath, { fileName, onProgress } = {}) {
	return new Promise((resolve, reject) => {
		if (!filePath) {
			reject(new Error('视频文件无效'))
			return
		}
		const uploadTask = uni.uploadFile({
			url: videoUploadPath(),
			filePath,
			name: 'file',
			formData: {
				name: fileName || `video-${Date.now()}.mp4`
			},
			success: (res) => {
				const parsed = parseVideoUploadEnvelope(res.data)
				if (res.statusCode === 200 && parsed) {
					resolve(parsed)
					return
				}
				let message = '视频上传失败'
				try {
					const envelope = typeof res.data === 'string' ? JSON.parse(res.data) : res.data
					if (envelope && envelope.msg) message = String(envelope.msg)
				} catch (_) {}
				reject(new Error(message))
			},
			fail: (err) => reject(err || new Error('视频上传失败'))
		})
		if (onProgress && uploadTask && typeof uploadTask.onProgressUpdate === 'function') {
			uploadTask.onProgressUpdate(onProgress)
		}
	})
}

/**
 * 发布种草动态（type=want）
 * 使用 uni.request + complete，避免拦截器 return false 时 Promise 永不 settle
 */
export function publishGrassPost({ content, images, goodsIds = [] }) {
	const body = {
		type: 'want',
		content,
		images,
		goods_ids: goodsIds,
		video_id: null,
		label_id: null
	}
	return postFindData(body)
}

/**
 * 发布短视频（type=video）
 */
export function publishVideoPost({ content, videoId, videoUrl, labelId, goodsIds = [] }) {
	const body = {
		type: 'video',
		content,
		images: [],
		goods_ids: goodsIds,
		video_id: videoId,
		video: videoUrl || null,
		label_id: labelId
	}
	return postFindData(body)
}
