// @ts-nocheck
import { ChooseFileOption, ChooseFile, ChooseFileSuccessCallbackResult } from '../interface'
import { UIDocumentPickerDelegate, UIDocumentPickerMode } from "UIKit"
import { URL, FileManager } from 'Foundation';
import { GeneralCallbackResultImpl } from '../unierror'
import { DispatchQueue } from 'Dispatch';

const documentTypes : Map<string, string[]> = new Map([
	["all", ["public.item"]],
	["file", [
		"public.text",
		"public.zip-archive",
		"public.data",
		"com.adobe.pdf",
		"com.microsoft.word.doc",
		"com.microsoft.word.docx",
		"com.microsoft.excel.xls",
		"com.microsoft.excel.xlsx"
		]
	],
	["video", ["public.movie"]],
	["image", ["public.image"]],
])

class ChooseFileImpl {
	name : string = ''
	path : string = ''
	size : number = 0
	time : number = 0
	type : string = 'file'
	constructor(uri : URL, options : ChooseFileOption) {
		try {
			const originalFileName = uri.lastPathComponent;
			const attributes = UTSiOS.try(FileManager.default.attributesOfItem(atPath = uri.path))
			const fileSize = attributes[FileAttributeKey.size] as number
			const pathExtension = `${uri.pathExtension}`
			
			const imageFormats = ['jpeg', 'jpg', 'png', 'gif', 'bmp', 'tiff', 'svg']
			const videoFormats = ['mov', 'm4v', 'mp4', 'avi']
			
			
			let fileName = originalFileName
			if(options.filename != null) {
				fileName = options.filename!
				if(options.count != null && options.count! > 1) {
					fileName = `${fileName}_${Date.now()}`;
				}
				fileName = `${fileName}.${pathExtension}`
			}
			




			const dataPath = UTSiOS.getDataPath().replace(/data$/, "doc");

			const file = new URL(fileURLWithPath = dataPath).appendingPathComponent(fileName)//.absoluteString
			const fileData = FileManager.default.contents(atPath = uri.path);
			UTSiOS.try(fileData?.write(to = file))

			if (imageFormats.includes(pathExtension)) {
				this.type = 'image'
			} else if (videoFormats.includes(pathExtension)) {
				this.type = 'video'
			} else {
				this.type = 'file'
			}

			this.name = `${originalFileName}`
			this.size = fileSize
			this.path = `${file.absoluteString}`
		} catch (e) {

		}
	}
}

class FilePickerManager implements UIDocumentPickerDelegate {
	options : ChooseFileOption = {}
	constructor() { }
	chooseFile(options : ChooseFileOption) {
		DispatchQueue.main.async(execute = () : void => {
			this.options = options
			const type = options.type ?? 'all'
			const count = options.count ?? 1
			const types = (documentTypes.get(type) ?? documentTypes.get('all')) as string[]
			let documentPicker = UIDocumentPickerViewController(
				documentTypes = types,
				in = UIDocumentPickerMode.import
			)
			documentPicker.delegate = this
			// 多选要大于 ios11
			if (UTSiOS.available("iOS 11.0, *")) {
				documentPicker.allowsMultipleSelection = count > 1
			}
			UTSiOS.getCurrentViewController().present(documentPicker, animated = true)
		})
	}
	documentPicker(controller : UIDocumentPickerViewController, @argumentLabel("didPickDocumentsAt") urls : URL[]) {
		DispatchQueue.main.async(execute = () : void => {
			const tempFiles : ChooseFile[] = []
			for (let i = 0; i < urls.length; i++) {
				const url = urls[i]
				const chooseFile = new ChooseFileImpl(url, this.options);
				// IOS -> js 无法传class?
				const file : ChooseFile = {
					name: chooseFile.name,
					path: chooseFile.path,
					size: chooseFile.size,
					time: chooseFile.time,
					type: chooseFile.type,
				}
				if (chooseFile.path != '') {
					tempFiles.push(file)
				}
			}
			
			const count = this.options.count ?? Number.from(Double.greatestFiniteMagnitude) //Number.from(Double.MAX_VALUE)
			if (tempFiles.length > 0 && count >= tempFiles.length) {
				const res : ChooseFileSuccessCallbackResult = {
					tempFiles,
					errMsg: 'chooseFile:ok'
				}
				this.options.success?.(res)
			} else {
				const err = new GeneralCallbackResultImpl(9010002, `没有可用的文件或文件超过设置数量`)
				this.options.fail?.(err)
				this.options.complete?.(err)
			}
		})
	}
}

const fileManager = new FilePickerManager()

export function chooseFile(options : ChooseFileOption) {
	fileManager.chooseFile(options)
}