import { Server, Upload } from '../tus';
import { nanoid } from 'nanoid';
import { slugify } from 'transliteration';
import { StorageManager } from '../core/adapter';
import { createResource, deleteFailedUploadingResource, updateResourceStatus } from '../database/operations';
import { ResourceStatus } from '../enum';

const FILE_UPLOAD_CONFIG = {
	maxSizeBytes: 20_000_000_000, // 20GB
};

// 全局 TUS 服务器实例
let tusServer: Server | null = null;

function getFileId(uploadId: string) {
	return uploadId.replace(/\/[^/]+$/, '');
}

function getFilenameWithoutExt(filename: string): string {
	const lastDotIndex = filename.lastIndexOf('.');
	return lastDotIndex > 0 ? filename.substring(0, lastDotIndex) : filename;
}

async function handleUploadCreate(req: any, res: any, upload: Upload, url: string) {
	try {
		console.log(`[TUS] Upload create event for ${upload.id}, size: ${upload.size}, metadata:`, upload.metadata);
		const fileId = getFileId(upload.id);
		const storageManager = StorageManager.getInstance();

		await createResource({
			fileId,
			filename: upload.metadata?.filename || 'untitled',
			size: upload.size || 0,
			mimeType: upload.metadata?.filetype,
			storageType: storageManager.getStorageType(),
			status: ResourceStatus.UPLOADING,
		});

		console.log(`[TUS] Resource created for ${upload.id} using ${storageManager.getStorageType()} storage`);
	} catch (error) {
		console.error('[TUS] Failed to create resource during upload:', error);
		// 不抛出错误，让上传继续进行
	}
}

async function handleUploadFinish(req: any, res: any, upload: Upload) {
	try {
		console.log(`[TUS] Upload finish event for ${upload.id}, final size: ${upload.size}, offset: ${upload.offset}`);
		const fileId = getFileId(upload.id);
		await updateResourceStatus(fileId, ResourceStatus.UPLOADED);

		// TODO: 这里可以添加队列处理逻辑
		// fileQueue.add(QueueJobType.FILE_PROCESS, { resource }, { jobId: resource.id });
		console.log(`[TUS] Upload finished ${upload.id} using ${StorageManager.getInstance().getStorageType()} storage`);
	} catch (error) {
		console.error('[TUS] Failed to update resource after upload:', error);
	}
}

function initializeTusServer() {
	if (tusServer) {
		return tusServer;
	}

	// 获取存储管理器实例
	const storageManager = StorageManager.getInstance();
	const dataStore = storageManager.getDataStore();

	console.log(`[TUS] Initializing TUS server with ${storageManager.getStorageType()} storage`);

	tusServer = new Server({
		namingFunction(req, metadata) {
			const safeFilename = slugify(metadata?.filename || 'untitled');
			const now = new Date();
			const year = now.getFullYear();
			const month = String(now.getMonth() + 1).padStart(2, '0');
			const day = String(now.getDate()).padStart(2, '0');
			const uniqueId = nanoid(10);
			const fileName = `${year}/${month}/${day}/${uniqueId}/${safeFilename}`;
			console.log(`[TUS] Generated filename: ${fileName} for upload with metadata:`, metadata);
			return fileName;
		},
		path: '/upload',
		datastore: dataStore, // 使用存储适配器
		maxSize: FILE_UPLOAD_CONFIG.maxSizeBytes,
		postReceiveInterval: 1000,
		getFileIdFromRequest: (req, lastPath) => {
			const match = req.url?.match(/\/upload\/(.+)/);
			const fileId = match ? match[1] : lastPath;
			console.log(`[TUS] Extracted file ID: ${fileId} from URL: ${req.url}`);
			return fileId;
		},
		onIncomingRequest: async (req, res, id) => {
			console.log(`[TUS] Incoming request for ${id}, method: ${req.method}, url: ${req.url}`);
		},
		onUploadCreate: async (req, res, upload) => {
			console.log(`[TUS] onUploadCreate called for ${upload.id}`);
			return res;
		},
		onUploadFinish: async (req, res, upload) => {
			console.log(`[TUS] onUploadFinish called for ${upload.id}`);
			return res;
		},
	});

	// 设置事件处理器
	tusServer.on('POST_CREATE', handleUploadCreate);
	tusServer.on('POST_FINISH', handleUploadFinish);

	// 添加错误处理
	tusServer.on('error', (error) => {
		console.error('[TUS] Server error:', error);
	});

	console.log(`[TUS] TUS server initialized with ${storageManager.getStorageType()} storage`);
	return tusServer;
}

export function getTusServer() {
	return initializeTusServer();
}

export async function handleTusRequest(req: any, res: any) {
	const server = getTusServer();
	return server.handle(req, res);
}

export async function cleanupExpiredUploads() {
	try {
		const storageManager = StorageManager.getInstance();

		// 获取过期时间配置，如果设置为 0 则不自动清理
		const expirationPeriod: number = 24 * 60 * 60 * 1000;

		// Delete incomplete uploads older than expiration period
		const deletedResources = await deleteFailedUploadingResource(expirationPeriod);

		const server = getTusServer();
		const expiredUploadCount = await server.cleanUpExpiredUploads();

		console.log(
			`Cleanup complete: ${deletedResources.count} resources and ${expiredUploadCount} uploads removed from ${storageManager.getStorageType()} storage`,
		);

		return { deletedResources: deletedResources.count, expiredUploads: expiredUploadCount };
	} catch (error) {
		console.error('Expired uploads cleanup failed', error);
		throw error;
	}
}

// 获取存储信息
export function getStorageInfo() {
	const storageManager = StorageManager.getInstance();
	return storageManager.getStorageInfo();
}
