// File: wwwroot/js/fileInterop.js

export async function pickDirectory(startingDirectory) {
    try {
        if (window.electron && window.electron.showDirectoryPicker) {
            return await window.electron.showDirectoryPicker(startingDirectory);
        }

        if ("showDirectoryPicker" in window && typeof window.showDirectoryPicker === "function") {
            const handle = await window.showDirectoryPicker();
            return handle?.name ?? null;
        }

        return await new Promise((resolve, reject) => {
            const input = document.createElement("input");
            input.type = "file";
            input.webkitdirectory = true;
            input.multiple = false;

            input.onchange = (e) => {
                const files = e.target.files;
                if (files && files.length > 0) {
                    resolve(files[0].path || files[0].webkitRelativePath.split("/")[0]);
                } else {
                    resolve(null);
                }
            };

            input.oncancel = () => resolve(null);
            input.click();
        });
    } catch (err) {
        if (err?.name === "AbortError") {
            return null;
        }

        console.error("Error in pickDirectory:", err);
        return null;
    }
}

export async function pickFile(filters) {
    try {
        if (window.electron && typeof window.electron.showOpenFilePicker === "function") {
            return await window.electron.showOpenFilePicker(filters);
        }

        if ("showOpenFilePicker" in window && typeof window.showOpenFilePicker === "function") {
            const options = {
                multiple: false
            };

            if (filters) {
                const parts = filters.split("|");
                if (parts.length === 2) {
                    const extensions = parts[1]
                        .split(";")
                        .map(ext => ext.replace("*.", "."));

                    options.types = [{
                        description: parts[0],
                        accept: { "*/*": extensions }
                    }];
                }
            }

            const [fileHandle] = await window.showOpenFilePicker(options);
            const file = await fileHandle.getFile();
            return file?.path || file?.name || null;
        }

        return await new Promise((resolve) => {
            const input = document.createElement("input");
            input.type = "file";

            if (filters) {
                const parts = filters.split("|");
                if (parts.length === 2) {
                    input.accept = parts[1];
                }
            }

            input.onchange = (e) => {
                const files = e.target.files;
                if (files && files.length > 0) {
                    resolve(files[0].path || files[0].name || null);
                } else {
                    resolve(null);
                }
            };

            input.oncancel = () => resolve(null);
            input.click();
        });
    } catch (err) {
        if (err?.name === "AbortError") {
            return null;
        }

        console.error("Error in pickFile:", err);
        return null;
    }
}

export async function showDirectoryPicker() {
    return await pickDirectory();
}

export async function downloadUrlWithProgress(url, suggestedName, dotNetProgress) {
    if (!("showSaveFilePicker" in window) || typeof window.showSaveFilePicker !== "function") {
        return "unsupported";
    }

    if (!("ReadableStream" in window)) {
        return "unsupported";
    }

    let writable = null;
    try {
        const handle = await window.showSaveFilePicker({
            suggestedName: suggestedName || "download"
        });

        writable = await handle.createWritable();
        const response = await fetch(new URL(url, document.baseURI).toString(), {
            credentials: "include"
        });

        if (!response.ok) {
            throw new Error(`Download failed (${response.status} ${response.statusText})`);
        }

        if (!response.body) {
            throw new Error("This browser does not expose a readable download stream.");
        }

        const totalHeader = response.headers.get("content-length");
        const totalBytes = totalHeader ? Number(totalHeader) : null;
        const reader = response.body.getReader();
        let bytesTransferred = 0;

        while (true) {
            const { done, value } = await reader.read();
            if (done) {
                break;
            }

            await writable.write(value);
            bytesTransferred += value.byteLength;

            const percent = totalBytes && totalBytes > 0
                ? Math.min(100, Math.max(0, bytesTransferred / totalBytes * 100))
                : null;

            await dotNetProgress.invokeMethodAsync("Report", bytesTransferred, totalBytes, percent);
        }

        await writable.close();
        return "completed";
    } catch (err) {
        if (writable) {
            try {
                await writable.abort();
            } catch {
            }
        }

        if (err?.name === "AbortError") {
            return "cancelled";
        }

        console.error("Error in downloadUrlWithProgress:", err);
        throw err;
    }
}

window.fileInterop = {
    pickDirectory,
    pickFile,
    showDirectoryPicker,
    downloadUrlWithProgress
};
