// @ts-nocheck
import * as q from './quark-api';

/**
 * 分享模块 — 分享链接解析、转存任务、创建分享链接。
 */
// ==================== Acquire Stoken ====================
/**
 * Acquire stoken for a share link (needed for detail/save).
 */
export async function acquireStoken(cookie, pwdId) {
    for (let attempt = 0; attempt < 3; attempt++) {
        try {
            const params = new URLSearchParams(q.getCommonParams());
            const resp = await fetch(`q.QUARK_DRIVE_HOST + q.EP.SHARE_PAGE_TOKEN?${params.toString()}`, {
                method: 'POST',
                headers: { ...q.getHeaders(cookie), 'Content-Type': 'application/json' },
                body: JSON.stringify({ pwd_id: pwdId, passcode: '' }),
                signal: AbortSignal.timeout(10000),
            });
            if (!resp.ok) {
                if (attempt < 2)
                    continue;
                return null;
            }
            const data = await resp.json();
            if (data.status === 200 && data.data?.stoken) {
                return data.data.stoken;
            }
            return null;
        }
        catch {
            if (attempt >= 2)
                return null;
            await new Promise(r => setTimeout(r, 500 * (attempt + 1)));
        }
    }
    return null;
}
// ==================== Get Share Files ====================
/**
 * Fetch detail at a given pdir_fid within a share.
 */
export async function getDetailAt(cookie, pwdId, stoken, pdirFid) {
    const params = new URLSearchParams({
        ...q.getCommonParams(),
        pwd_id: pwdId,
        stoken,
        pdir_fid: pdirFid,
        force: '0',
        _page: '1',
        _size: '50',
        _fetch_banner: '0',
        _fetch_share: '1',
        _fetch_total: '1',
        _sort: 'file_type:asc,updated_at:desc',
        ver: '2',
        fetch_share_full_path: '0',
    });
    const resp = await fetch(`q.QUARK_DRIVE_HOST + q.EP.SHARE_PAGE_DETAIL?${params.toString()}`, { headers: q.getHeaders(cookie), signal: AbortSignal.timeout(15000) });
    if (!resp.ok)
        return [];
    const data = await resp.json();
    if (data.status !== 200)
        return [];
    return (data.data?.list || []).filter((f) => f.fid).map((f) => ({
        fid: f.fid,
        file_name: f.file_name,
        share_fid_token: f.share_fid_token || '',
        dir: f.dir || false,
        size: f.size || 0,
    }));
}
/**
 * Recursively collect files from a share.
 * If the share contains a single directory, drill into it to list contents
 * but still save the directory itself.
 */
export async function getShareFiles(cookie, pwdId, stoken) {
    try {
        const topLevel = await getDetailAt(cookie, pwdId, stoken, '0');
        if (!topLevel || topLevel.length === 0)
            return null;
        // If the share is a single directory, we save the directory itself
        // and fetch its contents for renaming later
        if (topLevel.length === 1 && topLevel[0].dir) {
            const innerFiles = await getDetailAt(cookie, pwdId, stoken, topLevel[0].fid);
            return {
                files: topLevel,
                topDir: true,
                childFiles: innerFiles || [],
            };
        }
        // Multiple top-level items: save them directly
        return {
            files: topLevel,
            topDir: false,
        };
    }
    catch {
        return null;
    }
}
// ==================== Save Files (share → cloud) ====================
/**
 * Save shared files to the user's cloud directory.
 */
export async function saveFiles(cookie, pwdId, stoken, fids, fidTokens, toPdirFid) {
    try {
        const resp = await fetch(`q.QUARK_DRIVE_HOST + q.EP.SHARE_PAGE_SAVE?${q.makeQuery()}`, {
            method: 'POST',
            headers: { ...q.getHeaders(cookie), 'Content-Type': 'application/json' },
            body: JSON.stringify({
                fid_list: fids,
                fid_token_list: fidTokens,
                to_pdir_fid: toPdirFid,
                pwd_id: pwdId,
                stoken,
                pdir_fid: '0',
                scene: 'link',
            }),
            signal: AbortSignal.timeout(30000),
        });
        const data = await resp.json();
        if (data.status === 200 && data.data?.task_id) {
            return { success: true, message: 'Save task created', taskId: data.data.task_id };
        }
        return {
            success: false,
            message: data.message === 'require login [guest]'
                ? '夸克网盘 Cookie 已过期，请在后台重新配置 Cookie'
                : (data.message || `API 返回错误 (status=${data.status}, code=${data.code})`),
        };
    }
    catch (err) {
        return { success: false, message: err.message || 'Network error' };
    }
}
// ==================== Wait for Save Task ====================
/**
 * Poll task status until complete or timeout.
 * Returns the saved file FIDs (save_as_top_fids).
 */
export async function waitForTask(cookie, taskId, timeoutMs) {
    const start = Date.now();
    let retryIndex = 0;
    while (Date.now() - start < timeoutMs) {
        try {
            const params = new URLSearchParams({
                ...q.getCommonParams(),
                uc_param_str: '',
                task_id: taskId,
                retry_index: String(retryIndex),
                __dt: String(Math.floor(Math.random() * 240000 + 60000)),
                __t: String(Date.now() / 1000),
            });
            const resp = await fetch(`q.QUARK_DRIVE_HOST + q.EP.TASK?${params.toString()}`, { headers: q.getHeaders(cookie), signal: AbortSignal.timeout(10000) });
            const data = await resp.json();
            if (data.status === 200) {
                if (data.data?.status === 2) {
                    // Task completed
                    const savedFids = data.data?.save_as?.save_as_top_fids || [];
                    return savedFids;
                }
                // Still in progress
                retryIndex++;
            }
        }
        catch {
            // Network error, retry
        }
        await new Promise(r => setTimeout(r, 1000));
    }
    return null; // Timeout
}
// ==================== Rename File ====================
/**
 * Rename a file by its FID.
 */
export async function renameFile(cookie, fid, newName) {
    try {
        const resp = await fetch(`q.QUARK_DRIVE_HOST + q.EP.FILE_RENAME?${q.makeQuery()}`, {
            method: 'POST',
            headers: { ...q.getHeaders(cookie), 'Content-Type': 'application/json' },
            body: JSON.stringify({ fid, file_name: newName }),
            signal: AbortSignal.timeout(10000),
        });
        const data = await resp.json();
        return data.status === 200 || data.code === 0;
    }
    catch {
        return false;
    }
}
// ==================== Create Share Link ====================
/**
 * Create a share link for a file/folder.
 * Flow: create task → poll for share_id → submit to get short URL.
 */
export async function createShareLink(cookie, fileId) {
    try {
        const sharePwd = q.randomSharePwd();
        // Try different share_type values (1=7天, 0=无限制)
        const shareTypes = ['1', '0'];
        let lastError = '';
        for (const st of shareTypes) {
            await q.humanDelay();
            // Step 1: Create share task - get task_id
            const response = await fetch(`q.QUARK_DRIVE_HOST + q.EP.SHARE + "?"${q.makeQuery()}`, {
                method: 'POST',
                headers: { ...q.getHeaders(cookie), 'Content-Type': 'application/json' },
                body: JSON.stringify({
                    fid_list: [fileId],
                    share_type: st,
                    url_type: '1',
                    share_pwd: sharePwd,
                }),
                signal: AbortSignal.timeout(15000),
            });
            const data = await response.json();
            const taskId = data.data?.task_id;
            if (!taskId) {
                lastError = data.message || `share_type=${st} 失败`;
                console.error('[Quark] Create share task failed (type=%s):', st, data.message || JSON.stringify(data).slice(0, 200));
                continue;
            }
            // Step 2: Poll task until complete
            const result = await waitForShareTask(cookie, taskId, 20000);
            if (!result?.shareId) {
                lastError = result?.message || '任务超时';
                console.error('[Quark] Wait for share task failed (type=%s):', st, result?.message || 'unknown');
                continue;
            }
            // Step 3: Submit share via /password endpoint
            const shareUrl = await submitShare(cookie, result.shareId, sharePwd);
            if (shareUrl) {
                return {
                    success: true,
                    shareUrl,
                    sharePwd,
                    message: `分享链接已生成（密码：${sharePwd}）`,
                };
            }
            lastError = '提交密码后未获取到短链接';
        }
        return { success: false, message: lastError || '🤷 各种姿势都试过了，就是分享不出来…' };
    }
    catch (err) {
        console.error('[Quark] createShareLink error:', err.message);
        return { success: false, message: err.message || '🌩️ 网络开小差了，再试试？' };
    }
}
/**
 * Submit share via /password endpoint to get the actual short URL.
 */
async function submitShare(cookie, shareId, sharePwd) {
    try {
        const response = await fetch(`q.QUARK_DRIVE_HOST + q.EP.SHARE_PASSWORD?${q.makeQuery()}`, {
            method: 'POST',
            headers: { ...q.getHeaders(cookie), 'Content-Type': 'application/json' },
            body: JSON.stringify({ share_id: shareId, share_pwd: sharePwd || '' }),
            signal: AbortSignal.timeout(15000),
        });
        const data = await response.json();
        if (data.status === 200 && data.data?.share_url) {
            console.log('[Quark] Share short URL:', data.data.share_url);
            return data.data.share_url;
        }
        console.log('[Quark] /password response:', JSON.stringify(data).slice(0, 300));
        console.error('[Quark] /password FAIL status=%s msg=%s', data.status, data.message || '');
        return null;
    }
    catch (err) {
        console.log('[Quark] /password error:', err);
        return null;
    }
}
/**
 * Poll share task until complete and extract share URL/shortcode.
 */
async function waitForShareTask(cookie, taskId, timeoutMs) {
    const start = Date.now();
    let retryIndex = 0;
    while (Date.now() - start < timeoutMs) {
        try {
            const params = new URLSearchParams({
                ...q.getCommonParams(),
                uc_param_str: '',
                task_id: taskId,
                retry_index: String(retryIndex),
                __dt: String(Math.floor(Math.random() * 240000 + 60000)),
                __t: String(Date.now() / 1000),
            });
            const resp = await fetch(`q.QUARK_DRIVE_HOST + q.EP.TASK?${params.toString()}`, { headers: q.getHeaders(cookie), signal: AbortSignal.timeout(10000) });
            const data = await resp.json();
            if (data.data?.status === 2) {
                // Task completed — try multiple extraction approaches
                // 1. Direct share_url field
                if (data.data?.share_url) {
                    const match = data.data.share.match(/\/s\/([a-zA-Z0-9]+)/);
                    if (match)
                        return { shareId: match[1] };
                }
                // 2. Nested share object
                if (data.data?.share?.url) {
                    const match = data.data.share.url.match(/\/s\/([a-zA-Z0-9]+)/);
                    if (match)
                        return { shareId: match[1] };
                }
                if (data.data?.share?.short_url) {
                    const match = data.data.share.short.match(/\/s\/([a-zA-Z0-9]+)/);
                    if (match)
                        return { shareId: match[1] };
                }
                // 3. share_id — validate it's a reasonable short code (8-20 chars, not UUID-like)
                const shareId = data.data?.share_id;
                if (shareId && shareId.length <= 20 && shareId.length >= 8) {
                    return { shareId };
                }
                // 4. Regex search through the full response for a URL pattern
                const str = JSON.stringify(data);
                const urlMatch = str.match(/https?:\/\/pan\.quark\.cn\/s\/([a-zA-Z0-9]{6,16})/);
                if (urlMatch) {
                    return { shareId: urlMatch[1] };
                }
                // 5. Extract from any URL field in the response
                const urlFields = ['url', 'link', 'share_url', 'short_url', 'share_link'];
                for (const field of urlFields) {
                    const val = data.data?.[field] || data.data?.share?.[field];
                    if (typeof val === 'string' && val.includes('pan.quark.cn/s/')) {
                        const m = val.match(/\/s\/([a-zA-Z0-9]+)/);
                        if (m)
                            return { shareId: m[1] };
                    }
                }
                // 6. Log full share task response for debugging
                console.log('[Quark] Full share task response:', JSON.stringify(data, null, 2).slice(0, 2000));
                // 7. Even if shareId is UUID-like (32 hex chars), use it anyway as last resort
                if (shareId) {
                    return { shareId };
                }
                return { message: 'Share task completed but no share URL found' };
            }
            if (data.data?.status === 3) {
                return { message: data.message || 'Share task failed' };
            }
            retryIndex++;
        }
        catch {
            // Retry
        }
        await new Promise(r => setTimeout(r, 1000));
    }
    return { message: 'Share task timed out' };
}
