const SETTINGS_KEY = "warpbox.upload.settings.v1";

const el = {
    form: document.querySelector("#upload-form"),
    fileInput: document.querySelector("#file-upload"),
    dropSurface: document.querySelector("#drop-surface"),
    dropzone: document.querySelector("#dropzone"),
    fileList: document.querySelector("#file-list"),
    queueLabel: document.querySelector("#queue-label"),
    queueSize: document.querySelector("#queue-size"),
    limitHint: document.querySelector("#limit-hint"),
    boxSpaceText: document.querySelector("#box-space-text"),
    boxSpaceBar: document.querySelector("#box-space-bar"),
    overallBar: document.querySelector("#overall-bar"),
    overallPercent: document.querySelector("#overall-percent"),
    shareLink: document.querySelector("#share-link"),
    copyButton: document.querySelector("#copy-button"),
    startButton: document.querySelector("#start-button"),
    statusText: document.querySelector("#status-text"),
    toast: document.querySelector("#toast"),
    terminal: document.querySelector("#terminal-box"),
    copyCurlButton: document.querySelector("#copy-curl-button"),
    docPopup: document.querySelector("#doc-popup"),
    modalBackdrop: document.querySelector("#modal-backdrop"),
    docPopupTitle: document.querySelector("#doc-popup-title"),
    docPopupBody: document.querySelector("#doc-popup-body"),
    docPopupClose: document.querySelector("#doc-popup-close"),
    expiry: document.querySelector("#expiry-select"),
    password: document.querySelector("#password-input"),
    optionsForm: document.querySelector("#box-options-form"),
    maxViews: document.querySelector("#max-views"),
    boxName: document.querySelector("#box-name"),
    customSlug: document.querySelector("#custom-slug"),
    downloadPage: document.querySelector("#download-page"),
    allowZip: document.querySelector("#allow-zip"),
    allowPreview: document.querySelector("#allow-preview"),
    keepFilenames: document.querySelector("#keep-filenames"),
    privateBox: document.querySelector("#private-box"),
    apiKeyMode: document.querySelector("#api-key-mode"),
    apiKeyInput: document.querySelector("#api-key-input"),
    apiKeyRow: document.querySelector("#api-key-row"),
    apiKeyState: document.querySelector("#api-key-state"),
};

const uploadsEnabled = el.form?.dataset.uploadsEnabled === "true";
const defaultRetention = el.form?.dataset.defaultRetention || "10s";
const maxFileBytes = numberFromDataset(el.form?.dataset.maxFileBytes);
const maxBoxBytes = numberFromDataset(el.form?.dataset.maxBoxBytes);
const oneTimeRetentionKey = "one-time";

let files = [];
let shareUrl = "";
let uploadLocked = false;
let statusTimer = null;
let pendingDuplicateFiles = [];
let apiKeyTimer = null;
let completedImpactKeys = new Set();
let overallImpactDone = false;

function numberFromDataset(value) {
    const number = Number.parseInt(value || "0", 10);
    return Number.isFinite(number) && number > 0 ? number : 0;
}

function formatBytes(bytes) {
    if (!bytes) return "0 B";
    const units = ["B", "KB", "MB", "GB", "TB"];
    let value = bytes;
    let unit = 0;
    while (value >= 1024 && unit < units.length - 1) {
        value /= 1024;
        unit += 1;
    }
    return `${value.toFixed(value >= 10 || unit === 0 ? 0 : 1)} ${units[unit]}`;
}

const htmlEscape = window.WarpBoxUI.htmlEscape;

function shellQuote(value) {
    return `'${String(value).replaceAll("'", "'\\''")}'`;
}

function totalBytes() {
    return files.reduce((sum, item) => sum + item.file.size, 0);
}

function uploadedBytes() {
    return files.reduce((sum, item) => sum + item.loaded, 0);
}

function overallProgress() {
    const total = totalBytes();
    return total ? Math.round((uploadedBytes() / total) * 100) : 0;
}

function oversizedFiles() {
    return maxFileBytes ? files.filter((item) => item.file.size > maxFileBytes) : [];
}

function isOverBoxQuota() {
    return maxBoxBytes ? totalBytes() > maxBoxBytes : false;
}

function hasQuotaError() {
    return isOverBoxQuota() || oversizedFiles().length > 0;
}

function normalizedFileName(name) {
    return String(name || "").trim().toLowerCase();
}

function splitNameForIncrement(name) {
    const value = String(name || "file");
    const dot = value.lastIndexOf(".");
    if (dot > 0 && dot < value.length - 1) return [value.slice(0, dot), value.slice(dot)];
    return [value, ""];
}

function nextIncrementedFileName(name, usedNames) {
    const [base, ext] = splitNameForIncrement(name);
    let index = 2;
    let candidate = `${base} (${index})${ext}`;
    while (usedNames.has(normalizedFileName(candidate))) {
        index += 1;
        candidate = `${base} (${index})${ext}`;
    }
    usedNames.add(normalizedFileName(candidate));
    return candidate;
}

function makeQueuedFile(file, displayName = file.name) {
    return {
        file,
        displayName,
        loaded: 0,
        uploaded: false,
        failed: false,
        error: "",
        row: null,
        boxID: "",
        boxFile: null,
        previewURL: file.type?.startsWith("image/") ? URL.createObjectURL(file) : "",
    };
}

function iconForFile(file) {
    const filename = file.name || "";
    const mimeType = file.type || "";
    const extension = filename.includes(".") ? filename.slice(filename.lastIndexOf(".")).toLowerCase() : "";

    if (extension === ".exe") return "/static/img/icons/Program Files Icons - PNG/MSONSEXT.DLL_14_6-0.png";
    if (mimeType.startsWith("image/")) return "/static/img/sprites/bitmap.png";
    if (mimeType.startsWith("video/") || mimeType.startsWith("audio/")) return "/static/img/icons/netshow_notransm-1.png";
    if (mimeType.startsWith("text/") || extension === ".md") return "/static/img/sprites/notepad_file-1.png";
    if (mimeType.includes("zip") || mimeType.includes("compressed") || [".rar", ".7z", ".tar", ".gz"].includes(extension)) return "/static/img/icons/Windows Icons - PNG/zipfldr.dll_14_101-0.png";
    if ([".ttf", ".otf", ".woff", ".woff2"].includes(extension)) return "/static/img/sprites/font.png";
    if (extension === ".pdf") return "/static/img/sprites/journal.png";
    if ([".html", ".css", ".js"].includes(extension)) return "/static/img/sprites/frame_web-0.png";
    return "/static/img/icons/Windows Icons - PNG/ole2.dll_14_DEFICON.png";
}
