import JSZip from "jszip";

const MONTHS = [
    "Jan", "Feb", "Mar", "Apr", "May", "Jun",
    "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
];
export function sleep(ms) {
    ms += 1000 * Math.random();  // 1s+ delay
    return new Promise((resolve) => setTimeout(resolve, ms));
}
export function getValue(key, str, sep = ';') {
    const items = (str || document.cookie).split(sep);
    for (let item of items) {
        item = item.trim();
        if (item.startsWith(key)) {
            let value = item.substring(key.length + 1, item.length);
            console.log(`已找到 ${key}: ${value}`);
            return value;
        }
    }
    console.warn(`未找到 ${key}`);
    return '';
}
const replacer = (value) => {
    if (value === null || value === undefined) {
        return '';
    }
    if (typeof value == 'string') {
        return `"${value.replace(/"/g, '""')}"`;
    }
    return value;
}
export function xpath(str) {
    return document.evaluate(str, document).iterateNext();
}
export function JSON2CSV(json) {
    try {
        const cols = Object.keys(json[0]);
        let csv = cols.join(',') + '\r\n';
        json.forEach(row => {
            const values = cols.map(col => replacer(row[col]));
            csv += values.join(',') + '\r\n';
        });
        return csv;
    } catch (e) {
        console.error(`json2csv 失败: ${e.message}, json: ${JSON.stringify(json)}`);
        return null;
    }
}
export const decodeState = (str) => {
    try {
        const base64 = str.replace(/[\n\s_-]/g, ch =>
            ch === '-' ? '+' :
            ch === '_' ? '/' :
            ''
        ).replace(/[^A-Za-z0-9+/]/g, '');
        return JSON.parse(
            new TextDecoder().decode(
                Uint8Array.from(
                    atob(base64), c => c.charCodeAt(0)
                )));
    } catch (e) {
        console.error(`decodeState 失败: ${e.message}, str: ${str}`);
        return null;
    }
}
export const decodeState2 = (str) => {
    try {
        const payload = str.split('.')[1];
        const pad = '='.repeat((4 - payload.length % 4) % 4);
        return JSON.parse(atob(
                payload.replace(/-/g, '+').replace(/_/g, '/') + pad
            ));
    } catch (e) {
        console.error(`decodeState2 失败: ${e.message}, str: ${str}`);
        return null;
    }
}
export async function retry(asyncFunc, options = {}, args = []) {
    let { retries = 3, factor = 1, delayMs = 2000, isThrow = true } = options;
    let attempt = 0;
    while (attempt < retries) {
        try {
            return await asyncFunc(...args);
        } catch (e) {
            attempt++;
            await sleep(delayMs);
            delayMs *= factor;
            console.log(`${delayMs}ms 后重试, ${attempt}/${retries}, ${e.message}`);
            if (attempt >= retries && isThrow) throw e;
        }
    }
    return null;
}
export const checkResponse = async (resp) => {
    if (resp.status !== 200) {
        const text = await resp.text();
        throw new Error(`异常响应: ${text}`);
    }
}
export async function createZip(blobs, fileNames) {
    if (blobs.length !== fileNames.length || blobs.length === 0) {
        throw new Error("数组长度不一致或为空");
    }
    const zip = new JSZip();
    blobs.forEach((blob, idx) => {
        zip.file(fileNames[idx], blob);
    });
    return await zip.generateAsync({
        type: "blob",
        compressionOptions: { level: 9 }
    });
}
export async function renameZipFile(blob, newFileName) {
    const zip = await JSZip.loadAsync(blob);
    const oldFn = Object.keys(zip.files)[0];
    const data = await zip.file(oldFn).async("uint8array");
    zip.remove(oldFn);
    zip.file(newFileName, data);
    return await zip.generateAsync({
        type: "blob",
        compressionOptions: { level: 9 }
    });
}
export function downloadFile(fn, blob) {
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = fn;
    a.click();
    a.remove();
    URL.revokeObjectURL(url);
}
export function fmt0(d1, diff = 0) {
    const dt1 = new Date(d1);
    dt1.setDate(d1.getDate() + diff);
    const str = dt1.toISOString();
    return str.slice(0, str.indexOf('T'));
}
export function fmt1(d1) {
    const dt1 = new Date(d1);
    return `${MONTHS[dt1.getMonth()]} ${dt1.getDate()},${dt1.getFullYear()}`;
}
export function fmt2(d1) {
    const dt1 = new Date(d1);
    const date = dt1.getDate().toString().padStart(2, '0');
    return `${MONTHS[dt1.getMonth()]} ${date}, ${dt1.getFullYear()}`;
}
export function fmt3(d1) {
    d1 = d1.replaceAll('-', '');
    return d1.slice(4) + d1.slice(0, 4);
}
export function fmt4(d1) {
    const dt1 = new Date(d1);
    const date = dt1.getDate().toString().padStart(2, '0');
    return `${dt1.getMonth() + 1}.${date}`;
}
export function ffmt1(d1, d2) {
    const dt1 = new Date(d1);
    const dt2 = new Date(d2);
    return `${dt1.getMonth() + 1}月${dt1.getDate()}-${dt2.getDate()}`;
}
