import { BaseProvider } from '#templates/base/provider';
import { File } from '#models/File';
import Config from '#config';

export class FileProvider extends BaseProvider<File> {
	public static instance: FileProvider;

	public static getInstance(): FileProvider {
		FileProvider.instance ??= new FileProvider();
		return FileProvider.instance;
	}

	public static get model() {
		return File;
	}

	constructor() {
		super('File');
	}

	/**
	 * Soft delete a file by setting deleted_at and deleted_by
	 */
	async softDelete(id: string, deletedBy: string): Promise<boolean> {
		const toDelete = await File.findByPk(id);
		if (!toDelete) {
			return false;
		}

		await toDelete.update({
			deleted_at: new Date(),
			deleted_by: deletedBy,
		});

		return true;
	}

	/**
	 * Restore a soft-deleted file by clearing deleted_at and deleted_by
	 */
	override async restore(
		id: string,
		options?: {
			transaction?: any;
			restored_by?: string;
		},
	): Promise<string> {
		// Use BaseProvider restore method
		return super.restore(id, options);
	}

	/**
	 * Hard delete a file - permanently remove from database
	 * MISS-02: Implemented hard delete method for permanent file deletion
	 */
	async hardDelete(id: string): Promise<boolean> {
		const toDelete = await File.findByPk(id);
		if (!toDelete) {
			return false;
		}

		await toDelete.destroy();
		return true;
	}

	/**
	 * Get storage quota for a user
	 */
	async getStorageQuota(
		userId?: string,
	): Promise<{ used_bytes: number; used_files: number; limit_bytes: number | null }> {
		const where = userId ? { owner_user_id: userId, deleted_at: null } : { deleted_at: null };

		const result = await File.findAll({
			where,
			attributes: [
				[File.sequelize!.fn('SUM', File.sequelize!.col('size_bytes')), 'total_size'],
				[File.sequelize!.fn('COUNT', File.sequelize!.col('id')), 'total_files'],
			],
			raw: true,
		});

		const firstResult = result[0] as { total_size?: string | number; total_files?: string | number } | undefined;
		const used_bytes = Number(firstResult?.total_size ?? 0);
		const used_files = Number(firstResult?.total_files ?? 0);
		const limit_bytes = Config.storage.quotaPerUser > 0 ? Config.storage.quotaPerUser : null;

		return { used_bytes, used_files, limit_bytes };
	}
}
