import { Hono } from 'hono';
import { handleTusRequest, cleanupExpiredUploads, getStorageInfo } from '../services/tus';
import {
	getResourceByFileId,
	deleteResource,
	updateResource,
	migrateResourcesStorageType,
} from '../database/operations';
import { StorageManager, validateStorageConfig } from '../core/adapter';
import { StorageType, type StorageConfig } from '../types';

/**
 * 创建存储相关的 Hono 路由
 * @param basePath 基础路径，默认为 '/api/storage'
 * @returns Hono 应用实例
 */
export function createStorageRoutes(basePath: string = '/api/storage') {
	const app = new Hono();

	// 获取文件资源信息
	app.get('/resource/:fileId', async (c) => {
		const encodedFileId = c.req.param('fileId');
		const fileId = decodeURIComponent(encodedFileId);
		console.log('API request - Encoded fileId:', encodedFileId);
		console.log('API request - Decoded fileId:', fileId);
		const result = await getResourceByFileId(fileId);
		return c.json(result);
	});

	// 删除资源
	app.delete('/resource/:id', async (c) => {
		const id = c.req.param('id');
		const result = await deleteResource(id);
		return c.json(result);
	});

	// 更新资源
	app.patch('/resource/:id', async (c) => {
		const id = c.req.param('id');
		const data = await c.req.json();
		const result = await updateResource(id, data);
		return c.json(result);
	});

	// 迁移资源存储类型（批量更新数据库中的存储类型标记）
	app.post('/migrate-storage', async (c) => {
		try {
			const { from, to } = await c.req.json();
			const result = await migrateResourcesStorageType(from as StorageType, to as StorageType);
			return c.json({
				success: true,
				message: `Migrated ${result.count} resources from ${from} to ${to}`,
				count: result.count,
			});
		} catch (error) {
			console.error('Failed to migrate storage type:', error);
			return c.json(
				{
					success: false,
					error: error instanceof Error ? error.message : 'Unknown error',
				},
				400,
			);
		}
	});

	// 清理过期上传
	app.post('/cleanup', async (c) => {
		const result = await cleanupExpiredUploads();
		return c.json(result);
	});

	// 获取存储信息
	app.get('/storage/info', async (c) => {
		const storageInfo = getStorageInfo();
		return c.json(storageInfo);
	});

	// 切换存储类型（需要重启应用）
	app.post('/storage/switch', async (c) => {
		try {
			const newConfig = (await c.req.json()) as StorageConfig;
			const storageManager = StorageManager.getInstance();
			await storageManager.switchStorage(newConfig);

			return c.json({
				success: true,
				message: 'Storage configuration updated. Please restart the application for changes to take effect.',
				newType: newConfig.type,
			});
		} catch (error) {
			console.error('Failed to switch storage:', error);
			return c.json(
				{
					success: false,
					error: error instanceof Error ? error.message : 'Unknown error',
				},
				400,
			);
		}
	});

	// 验证存储配置
	app.post('/storage/validate', async (c) => {
		try {
			const config = (await c.req.json()) as StorageConfig;
			const errors = validateStorageConfig(config);

			if (errors.length > 0) {
				return c.json({ valid: false, errors }, 400);
			}

			return c.json({ valid: true, message: 'Storage configuration is valid' });
		} catch (error) {
			return c.json(
				{
					valid: false,
					errors: [error instanceof Error ? error.message : 'Invalid JSON'],
				},
				400,
			);
		}
	});

	return app;
}

/**
 * 创建TUS上传处理路由
 * @param uploadPath 上传路径，默认为 '/upload'
 * @returns Hono 应用实例
 */
export function createTusUploadRoutes(uploadPath: string = '/upload') {
	const app = new Hono();

	// TUS 协议处理 - 使用通用处理器
	app.all('/*', async (c) => {
		try {
			// 创建适配的请求和响应对象
			const adaptedReq = createNodeRequestAdapter(c);
			const adaptedRes = createNodeResponseAdapter(c);

			await handleTusRequest(adaptedReq, adaptedRes);
			return adaptedRes.getResponse();
		} catch (error) {
			console.error('TUS request error:', error);
			return c.json({ error: 'Upload request failed' }, 500);
		}
	});

	return app;
}

// Node.js 请求适配器
function createNodeRequestAdapter(c: any) {
	const honoReq = c.req;
	const url = new URL(honoReq.url);

	// 导入Node.js模块
	const { Readable } = require('stream');
	const { EventEmitter } = require('events');

	// 创建一个继承自Readable的适配器类
	class TusRequestAdapter extends Readable {
		method: string;
		url: string;
		headers: Record<string, string>;
		httpVersion: string;
		complete: boolean;
		private reader: ReadableStreamDefaultReader<Uint8Array> | null = null;
		private _reading: boolean = false;

		constructor() {
			super();
			this.method = honoReq.method;
			this.url = url.pathname + url.search;
			this.headers = honoReq.header() || {};
			this.httpVersion = '1.1';
			this.complete = false;

			// 如果有请求体，获取reader
			if (honoReq.method !== 'GET' && honoReq.method !== 'HEAD' && honoReq.raw.body) {
				this.reader = honoReq.raw.body.getReader();
			}
		}

		_read() {
			if (this._reading || !this.reader) {
				return;
			}

			this._reading = true;

			this.reader
				.read()
				.then(({ done, value }) => {
					this._reading = false;
					if (done) {
						this.push(null); // 结束流
						this.complete = true;
					} else {
						// 确保我们推送的是正确的二进制数据
						const buffer = Buffer.from(value);
						this.push(buffer);
					}
				})
				.catch((error) => {
					this._reading = false;
					this.destroy(error);
				});
		}

		// 模拟IncomingMessage的destroy方法
		destroy(error?: Error) {
			if (this.reader) {
				this.reader.cancel().catch(() => {
					// 忽略取消错误
				});
				this.reader = null;
			}
			super.destroy(error);
		}
	}

	return new TusRequestAdapter();
}

// Node.js 响应适配器
function createNodeResponseAdapter(c: any) {
	let statusCode = 200;
	let headers: Record<string, string> = {};
	let body: any = null;

	const adapter = {
		statusCode,
		setHeader: (name: string, value: string) => {
			headers[name] = value;
		},
		getHeader: (name: string) => {
			return headers[name];
		},
		writeHead: (code: number, reasonOrHeaders?: any, headersObj?: any) => {
			statusCode = code;
			if (typeof reasonOrHeaders === 'object') {
				Object.assign(headers, reasonOrHeaders);
			}
			if (headersObj) {
				Object.assign(headers, headersObj);
			}
		},
		write: (chunk: any) => {
			if (body === null) {
				body = chunk;
			} else if (typeof body === 'string' && typeof chunk === 'string') {
				body += chunk;
			} else {
				// 处理 Buffer 或其他类型
				body = chunk;
			}
		},
		end: (data?: any) => {
			if (data !== undefined) {
				body = data;
			}
		},
		// 添加事件方法
		on: (event: string, handler: Function) => {
			// 简单的空实现
		},
		emit: (event: string, ...args: any[]) => {
			// 简单的空实现
		},
		// 获取最终的 Response 对象
		getResponse: () => {
			if (body === null || body === undefined) {
				return new Response(null, {
					status: statusCode,
					headers: headers,
				});
			}

			return new Response(body, {
				status: statusCode,
				headers: headers,
			});
		},
	};

	return adapter;
}

/**
 * 创建文件下载路由（支持所有存储类型）
 * @param downloadPath 下载路径，默认为 '/download'
 * @returns Hono 应用实例
 */
export function createFileDownloadRoutes(downloadPath: string = '/download') {
	const app = new Hono();

	// 通过文件ID下载文件
	app.get('/:fileId', async (c) => {
		try {
			// 获取并解码fileId
			const encodedFileId = c.req.param('fileId');
			const fileId = decodeURIComponent(encodedFileId);

			console.log('=== DOWNLOAD DEBUG START ===');
			console.log('Download request - Encoded fileId:', encodedFileId);
			console.log('Download request - Decoded fileId:', fileId);

			const storageManager = StorageManager.getInstance();
			const storageType = storageManager.getStorageType();

			// 从数据库获取文件信息
			const { status, resource } = await getResourceByFileId(fileId);
			if (status !== 'UPLOADED' || !resource) {
				console.log('Download - File not found, status:', status);
				return c.json({ error: `File not found or not ready. Status: ${status}, FileId: ${fileId}` }, 404);
			}

			// 详细记录资源信息
			console.log('Download - Full resource object:', JSON.stringify(resource, null, 2));
			console.log('Download - Resource title:', resource.title);
			console.log('Download - Resource type:', resource.type);
			console.log('Download - Resource fileId:', resource.fileId);

			// 使用resource.title作为下载文件名，如果没有则使用默认名称
			let downloadFileName = resource.title || 'download';

			// 确保文件名有正确的扩展名
			if (downloadFileName && !downloadFileName.includes('.') && resource.type) {
				// 如果没有扩展名，尝试从MIME类型推断
				const mimeTypeToExt: Record<string, string> = {
					// Microsoft Office
					'application/vnd.openxmlformats-officedocument.wordprocessingml.document': '.docx',
					'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': '.xlsx',
					'application/vnd.openxmlformats-officedocument.presentationml.presentation': '.pptx',
					'application/msword': '.doc',
					'application/vnd.ms-excel': '.xls',
					'application/vnd.ms-powerpoint': '.ppt',

					// WPS Office
					'application/wps-office.docx': '.docx',
					'application/wps-office.xlsx': '.xlsx',
					'application/wps-office.pptx': '.pptx',
					'application/wps-office.doc': '.doc',
					'application/wps-office.xls': '.xls',
					'application/wps-office.ppt': '.ppt',

					// 其他文档格式
					'application/pdf': '.pdf',
					'application/rtf': '.rtf',
					'text/plain': '.txt',
					'text/csv': '.csv',
					'application/json': '.json',
					'application/xml': '.xml',
					'text/xml': '.xml',

					// 图片格式
					'image/jpeg': '.jpg',
					'image/jpg': '.jpg',
					'image/png': '.png',
					'image/gif': '.gif',
					'image/bmp': '.bmp',
					'image/webp': '.webp',
					'image/svg+xml': '.svg',
					'image/tiff': '.tiff',

					// 音频格式
					'audio/mpeg': '.mp3',
					'audio/wav': '.wav',
					'audio/ogg': '.ogg',
					'audio/aac': '.aac',
					'audio/flac': '.flac',

					// 视频格式
					'video/mp4': '.mp4',
					'video/avi': '.avi',
					'video/quicktime': '.mov',
					'video/x-msvideo': '.avi',
					'video/webm': '.webm',

					// 压缩文件
					'application/zip': '.zip',
					'application/x-rar-compressed': '.rar',
					'application/x-7z-compressed': '.7z',
					'application/gzip': '.gz',
					'application/x-tar': '.tar',

					// 其他常见格式
					'application/octet-stream': '',
				};

				const extension = mimeTypeToExt[resource.type];
				if (extension) {
					downloadFileName += extension;
					console.log('Download - Added extension from MIME type:', extension);
				}
			}

			console.log('Download - Final download filename:', downloadFileName);

			if (storageType === StorageType.LOCAL) {
				// 本地存储：直接读取文件
				const config = storageManager.getStorageConfig();
				const uploadDir = config.local?.directory || './uploads';

				// fileId 是目录路径格式，直接使用
				const fileDir = `${uploadDir}/${fileId}`;

				try {
					// 使用 Node.js fs 而不是 Bun.file
					const fs = await import('fs');
					const path = await import('path');

					// 检查目录是否存在
					if (!fs.existsSync(fileDir)) {
						console.log('Download - Directory not found:', fileDir);
						return c.json({ error: `File directory not found: ${fileDir}` }, 404);
					}

					// 读取目录内容，找到实际的文件（排除 .json 文件）
					const files = fs.readdirSync(fileDir).filter((f) => !f.endsWith('.json'));
					console.log('Download - Files in directory:', files);

					if (files.length === 0) {
						return c.json({ error: `No file found in directory: ${fileDir}` }, 404);
					}

					// 通常只有一个文件，取第一个
					const actualFileName = files[0];
					if (!actualFileName) {
						return c.json({ error: 'No valid file found' }, 404);
					}
					const filePath = path.join(fileDir, actualFileName);

					console.log('Download - Actual file in directory:', actualFileName);
					console.log('Download - Full file path:', filePath);

					// 获取文件统计信息
					const stats = fs.statSync(filePath);
					const fileSize = stats.size;

					// 强制设置正确的MIME类型
					let contentType = resource.type || 'application/octet-stream';
					if (downloadFileName.endsWith('.docx')) {
						contentType = 'application/vnd.openxmlformats-officedocument.wordprocessingml.document';
					} else if (downloadFileName.endsWith('.xlsx')) {
						contentType = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
					} else if (downloadFileName.endsWith('.pdf')) {
						contentType = 'application/pdf';
					}

					console.log('Download - Final Content-Type:', contentType);

					// 处理中文文件名 - 现在使用正确的RFC 2231格式
					let contentDisposition: string;
					const hasNonAscii = !/^[\x00-\x7F]*$/.test(downloadFileName);

					if (hasNonAscii) {
						// 包含中文字符，使用RFC 2231标准
						const encodedFileName = encodeURIComponent(downloadFileName);
						// 同时提供fallback和UTF-8编码版本
						const fallbackName = downloadFileName.replace(/[^\x00-\x7F]/g, '_');
						contentDisposition = `attachment; filename="${fallbackName}"; filename*=UTF-8''${encodedFileName}`;

						console.log('Download - Original filename:', downloadFileName);
						console.log('Download - Encoded filename:', encodedFileName);
						console.log('Download - Fallback filename:', fallbackName);
					} else {
						// ASCII文件名，使用简单格式
						contentDisposition = `attachment; filename="${downloadFileName}"`;
					}

					// 设置所有必要的响应头
					c.header('Content-Type', contentType);
					c.header('Content-Length', fileSize.toString());
					c.header('Content-Disposition', contentDisposition);

					// 添加额外的头部以确保浏览器正确处理
					c.header('Cache-Control', 'no-cache, no-store, must-revalidate');
					c.header('Pragma', 'no-cache');
					c.header('Expires', '0');

					console.log('Download - Content-Disposition:', contentDisposition);
					console.log('=== DOWNLOAD DEBUG END ===');

					// 返回文件流 - 使用Hono的正确方式
					const fileStream = fs.createReadStream(filePath);

					// 将Node.js ReadStream转换为Web Stream
					const readableStream = new ReadableStream({
						start(controller) {
							fileStream.on('data', (chunk) => {
								controller.enqueue(chunk);
							});
							fileStream.on('end', () => {
								controller.close();
							});
							fileStream.on('error', (error) => {
								controller.error(error);
							});
						},
					});

					return new Response(readableStream, {
						status: 200,
						headers: {
							'Content-Type': contentType,
							'Content-Length': fileSize.toString(),
							'Content-Disposition': contentDisposition,
							'Cache-Control': 'no-cache, no-store, must-revalidate',
							Pragma: 'no-cache',
							Expires: '0',
						},
					});
				} catch (error) {
					console.error('Error reading local file:', error);
					return c.json({ error: 'Failed to read file' }, 500);
				}
			} else if (storageType === StorageType.S3) {
				// S3 存储：简单重定向，让S3处理文件名
				const config = storageManager.getStorageConfig();
				const s3Config = config.s3!;

				// 构建S3 key - 使用fileId和原始文件名
				const fileName = resource.title || 'file';
				const fullS3Key = `${fileId}/${fileName}`;

				console.log('Download - S3 Key:', fullS3Key);

				// 生成 S3 URL
				let s3Url: string;
				if (s3Config.endpoint && s3Config.endpoint !== 'https://s3.amazonaws.com') {
					// 自定义 S3 兼容服务
					s3Url = `${s3Config.endpoint}/${s3Config.bucket}/${fullS3Key}`;
				} else {
					// AWS S3
					s3Url = `https://${s3Config.bucket}.s3.${s3Config.region}.amazonaws.com/${fullS3Key}`;
				}

				console.log(`Redirecting to S3 URL: ${s3Url}`);
				console.log('=== DOWNLOAD DEBUG END ===');
				// 重定向到 S3 URL
				return c.redirect(s3Url, 302);
			}

			return c.json({ error: 'Unsupported storage type' }, 500);
		} catch (error) {
			console.error('Download error:', error);
			return c.json({ error: 'Internal server error' }, 500);
		}
	});

	return app;
}

/**
 * 创建完整的存储应用，包含API和上传功能
 * @param options 配置选项
 * @returns Hono 应用实例
 */
export function createStorageApp(
	options: {
		apiBasePath?: string;
		uploadPath?: string;
		downloadPath?: string;
	} = {},
) {
	const { apiBasePath = '/api/storage', uploadPath = '/upload', downloadPath = '/download' } = options;

	const app = new Hono();

	// 添加存储API路由
	app.route(apiBasePath, createStorageRoutes());

	// 添加TUS上传路由
	app.route(uploadPath, createTusUploadRoutes());

	// 添加文件下载路由
	app.route(downloadPath, createFileDownloadRoutes());

	return app;
}
