<?php
include("./includes/common.php");

if($conf['forcelogin'] == 1 && !$islogin2) exit(json_encode(['code' => -1, 'msg' => '请先登录']));

$act = isset($_GET['act']) ? $_GET['act'] : null;

// 鉴权
$is_guest = false;
if(!$islogin2) {
    // 检查游客权限 (从Cookie获取Token)
    $guestIds = get_guest_file_ids();
    if(count($guestIds) > 0) {
        $is_guest = true;
        $uid = 0; // 游客 UID 为 0
    } else {
        exit(json_encode(['code' => -1, 'msg' => '请先登录']));
    }
}

$folder = new \lib\Folder($DB);
$fileHelper = new \lib\File($DB);

header('Content-Type: application/json; charset=UTF-8');

function ensure_folder_share_columns($DB){
    static $inited = false;
    if($inited) return;
    $inited = true;

    // 使用缓存文件避免重复查询表结构
    $cacheFile = sys_get_temp_dir() . '/folder_columns_checked_' . DB_VERSION . '.cache';
    if(file_exists($cacheFile) && (time() - filemtime($cacheFile)) < 86400) {
        return;
    }

    $columns = $DB->getAll("SHOW COLUMNS FROM pre_folder");
    $exists = [];
    foreach((array)$columns as $col){
        if(isset($col['Field'])) $exists[$col['Field']] = true;
    }
    if(!isset($exists['share_key'])) $DB->exec("ALTER TABLE pre_folder ADD COLUMN share_key varchar(64) DEFAULT NULL");
    if(!isset($exists['share_need_pwd'])) $DB->exec("ALTER TABLE pre_folder ADD COLUMN share_need_pwd tinyint(1) NOT NULL DEFAULT 0");
    if(!isset($exists['share_pwd'])) $DB->exec("ALTER TABLE pre_folder ADD COLUMN share_pwd varchar(255) DEFAULT NULL");
    if(!isset($exists['share_notice'])) $DB->exec("ALTER TABLE pre_folder ADD COLUMN share_notice text");

    // 创建缓存文件
    file_put_contents($cacheFile, time());
}

function ensure_file_description_column($DB){
    static $inited = false;
    if($inited) return;
    $inited = true;

    // 使用缓存文件避免重复查询表结构
    $cacheFile = sys_get_temp_dir() . '/file_desc_column_checked_' . DB_VERSION . '.cache';
    if(file_exists($cacheFile) && (time() - filemtime($cacheFile)) < 86400) {
        return;
    }

    $columns = $DB->getAll("SHOW COLUMNS FROM pre_file");
    $exists = [];
    foreach((array)$columns as $col){
        if(isset($col['Field'])) $exists[$col['Field']] = true;
    }
    if(!isset($exists['description'])) $DB->exec("ALTER TABLE pre_file ADD COLUMN description text");

    // 创建缓存文件
    file_put_contents($cacheFile, time());
}

function ensure_file_share_columns($DB){
    static $inited = false;
    if($inited) return;
    $inited = true;

    // 使用缓存文件避免重复查询表结构
    $cacheFile = sys_get_temp_dir() . '/file_share_columns_checked_' . DB_VERSION . '.cache';
    if(file_exists($cacheFile) && (time() - filemtime($cacheFile)) < 86400) {
        return;
    }

    $columns = $DB->getAll("SHOW COLUMNS FROM pre_file");
    $exists = [];
    foreach((array)$columns as $col){
        if(isset($col['Field'])) $exists[$col['Field']] = true;
    }
    if(!isset($exists['share_key'])) $DB->exec("ALTER TABLE pre_file ADD COLUMN share_key varchar(64) DEFAULT NULL");
    if(!isset($exists['share_type'])) $DB->exec("ALTER TABLE pre_file ADD COLUMN share_type tinyint(1) NOT NULL DEFAULT 0 COMMENT '分享类型:0=直链,1=普通链接'");
    if(!isset($exists['share_notice'])) $DB->exec("ALTER TABLE pre_file ADD COLUMN share_notice text COMMENT '分享页面公告(支持HTML)'");
    if(!isset($exists['share_count'])) $DB->exec("ALTER TABLE pre_file ADD COLUMN share_count int(11) unsigned NOT NULL DEFAULT 0 COMMENT '分享页面访问次数'");
    // 添加索引
    try {
        $DB->exec("CREATE INDEX idx_share_key ON pre_file (share_key)");
    } catch (Exception $e) {}

    // 创建缓存文件
    file_put_contents($cacheFile, time());
}

switch($act) {
    case 'create':
        $name = trim($_POST['name']);
        $parentId = intval($_POST['parent_id']);
        echo json_encode($folder->create($uid, $name, $parentId));
        break;
        
    case 'rename':
        $folderId = intval($_POST['folder_id']);
        $newName = trim($_POST['new_name']);
        echo json_encode($folder->rename($uid, $folderId, $newName));
        break;
        
    case 'delete':
        $folderId = intval($_POST['folder_id']);
        echo json_encode($folder->delete($uid, $folderId));
        break;

    case 'batch_delete':
        $folderIds = isset($_POST['folder_ids']) ? $_POST['folder_ids'] : [];
        $fileIds = isset($_POST['file_ids']) ? $_POST['file_ids'] : [];
        
        $success = 0;
        $fail = 0;
        
        if (!empty($folderIds)) {
            if ($is_guest) {
            } else {
                foreach ($folderIds as $fid) {
                    $res = $folder->delete($uid, intval($fid));
                    if ($res['code'] == 0) $success++;
                    else $fail++;
                }
            }
        }
        
        if (!empty($fileIds)) {
            $stor = \lib\StorHelper::getModel($conf['storage']);
            $guestIds = $is_guest ? get_guest_file_ids() : [];
            
            foreach ($fileIds as $fid) {
                $fid = intval($fid);
                $fileRow = $DB->getRow("SELECT * FROM pre_file WHERE id=:id", [':id'=>$fid]);
                
                if ($fileRow) {
                    if ($is_guest) {
                        $has_token = isset($fileRow['guest_token']) && $fileRow['guest_token'] === get_guest_token();
                        if (!$has_token && !in_array($fid, $guestIds) && (!isset($_SESSION['fileids']) || !in_array($fid, $_SESSION['fileids']))) {
                            $fail++; continue;
                        }
                    } else {
                        if ($fileRow['uid'] != $uid) {
                            $fail++; continue;
                        }
                    }

                    $count = $DB->getColumn("SELECT count(*) FROM pre_file WHERE hash=:hash", [':hash'=>$fileRow['hash']]);
                    if ($count <= 1) {
                        $stor->delete($fileRow['hash']);
                    }
                    $DB->exec("DELETE FROM pre_file WHERE id=:id", [':id'=>$fid]);
                    $success++;
                } else {
                    $fail++;
                }
            }
        }
        
        echo json_encode(['code'=>0, 'msg'=>"成功删除 {$success} 项，失败 {$fail} 项"]);
        break;

    case 'sort':
        $folderId = intval($_POST['folder_id']);
        $sort = intval($_POST['sort']);
        if ($sort < 1 || $sort > 999) exit(json_encode(['code'=>-1, 'msg'=>'排序值必须在1-999之间']));
        echo json_encode($folder->sort($uid, $folderId, $sort));
        break;
        
    case 'move':
        $targetId = intval($_POST['target_id']);
        $folderIds = isset($_POST['folder_ids']) ? $_POST['folder_ids'] : [];
        $fileIds = isset($_POST['file_ids']) ? $_POST['file_ids'] : [];
        echo json_encode($folder->move($uid, $targetId, $folderIds, $fileIds));
        break;

    case 'get_share_info':
        ensure_folder_share_columns($DB);
        $folderId = intval($_POST['folder_id']);
        if($folderId <= 0) exit(json_encode(['code'=>-1, 'msg'=>'参数错误']));
        $row = $DB->getRow("SELECT folder_id,name,share_key,share_need_pwd,share_pwd,share_notice FROM pre_folder WHERE folder_id=:fid AND uid=:uid LIMIT 1", [':fid'=>$folderId, ':uid'=>$uid]);
        if(!$row) exit(json_encode(['code'=>-1, 'msg'=>'文件夹不存在或无权限']));
        if(empty($row['share_key'])){
            $shareKey = substr(md5(uniqid((string)$uid, true).mt_rand()), 0, 16);
            $DB->exec("UPDATE pre_folder SET share_key=:k WHERE folder_id=:fid AND uid=:uid", [':k'=>$shareKey, ':fid'=>$folderId, ':uid'=>$uid]);
            $row['share_key'] = $shareKey;
        }
        echo json_encode([
            'code'=>0,
            'data'=>[
                'folder_id'=>(int)$row['folder_id'],
                'name'=>$row['name'],
                'share_key'=>$row['share_key'],
                'share_need_pwd'=>(int)$row['share_need_pwd'],
                'share_pwd'=>$row['share_pwd'] ? $row['share_pwd'] : '',
                'share_notice'=>$row['share_notice'] ? $row['share_notice'] : ''
            ]
        ]);
        break;

    case 'set_share':
        ensure_folder_share_columns($DB);
        $folderId = intval($_POST['folder_id']);
        if($folderId <= 0) exit(json_encode(['code'=>-1, 'msg'=>'参数错误']));
        $needPwd = isset($_POST['share_need_pwd']) ? intval($_POST['share_need_pwd']) : 0;
        $needPwd = $needPwd ? 1 : 0;
        $sharePwd = isset($_POST['share_pwd']) ? trim($_POST['share_pwd']) : '';
        $shareNotice = isset($_POST['share_notice']) ? trim($_POST['share_notice']) : '';
        $row = $DB->getRow("SELECT folder_id,share_key FROM pre_folder WHERE folder_id=:fid AND uid=:uid LIMIT 1", [':fid'=>$folderId, ':uid'=>$uid]);
        if(!$row) exit(json_encode(['code'=>-1, 'msg'=>'文件夹不存在或无权限']));
        if($needPwd === 1 && $sharePwd === ''){
            exit(json_encode(['code'=>-1, 'msg'=>'已开启访问密码，请填写密码']));
        }
        if($needPwd === 1 && strlen($sharePwd) > 64){
            exit(json_encode(['code'=>-1, 'msg'=>'访问密码长度不能超过64']));
        }
        if(strlen($shareNotice) > 20000){
            exit(json_encode(['code'=>-1, 'msg'=>'公告内容过长']));
        }
        $shareKey = !empty($row['share_key']) ? $row['share_key'] : substr(md5(uniqid((string)$uid, true).mt_rand()), 0, 16);
        $DB->exec("UPDATE pre_folder SET share_key=:k,share_need_pwd=:need_pwd,share_pwd=:pwd,share_notice=:notice,updated_at=NOW() WHERE folder_id=:fid AND uid=:uid", [
            ':k'=>$shareKey,
            ':need_pwd'=>$needPwd,
            ':pwd'=>$needPwd ? $sharePwd : null,
            ':notice'=>$shareNotice === '' ? null : $shareNotice,
            ':fid'=>$folderId,
            ':uid'=>$uid
        ]);
        echo json_encode(['code'=>0, 'msg'=>'保存成功', 'share_key'=>$shareKey]);
        break;

    case 'rename_file':
        $fileId = intval($_POST['file_id']);
        $newName = trim($_POST['new_name']);
        
        if ($is_guest) {
            $guestIds = get_guest_file_ids();
            $row = $DB->getRow("SELECT * FROM pre_file WHERE id=:id", [':id'=>$fileId]);
            if(!$row) exit(json_encode(['code'=>-1, 'msg'=>'文件不存在']));
            
            $has_token = isset($row['guest_token']) && $row['guest_token'] === get_guest_token();
            if (!$has_token && !in_array($fileId, $guestIds) && (!isset($_SESSION['fileids']) || !in_array($fileId, $_SESSION['fileids']))) {
                exit(json_encode(['code'=>-1, 'msg'=>'无权限']));
            }
        }
        
        echo json_encode($fileHelper->rename($uid, $fileId, $newName));
        break;

    case 'get_password':
        $fileId = intval($_POST['file_id']);
        
        if ($is_guest) {
            $guestIds = get_guest_file_ids();
            $row = $DB->getRow("SELECT * FROM pre_file WHERE id=:id", [':id'=>$fileId]);
            if(!$row) exit(json_encode(['code'=>-1, 'msg'=>'文件不存在']));
            
            $has_token = isset($row['guest_token']) && $row['guest_token'] === get_guest_token();
            if (!$has_token && !in_array($fileId, $guestIds) && (!isset($_SESSION['fileids']) || !in_array($fileId, $_SESSION['fileids']))) {
                exit(json_encode(['code'=>-1, 'msg'=>'无权限']));
            }
        }
        
        $pwd = $fileHelper->getPassword($uid, $fileId);
        echo json_encode(['code'=>0, 'password'=>$pwd]);
        break;

    case 'set_password':
        $fileId = intval($_POST['file_id']);
        $password = trim($_POST['password']);
        $oldPassword = isset($_POST['old_password']) ? trim($_POST['old_password']) : null;
        
        if ($is_guest) {
            $guestIds = get_guest_file_ids();
            $row = $DB->getRow("SELECT * FROM pre_file WHERE id=:id", [':id'=>$fileId]);
            if(!$row) exit(json_encode(['code'=>-1, 'msg'=>'文件不存在']));
            
            $has_token = isset($row['guest_token']) && $row['guest_token'] === get_guest_token();
            if (!$has_token && !in_array($fileId, $guestIds) && (!isset($_SESSION['fileids']) || !in_array($fileId, $_SESSION['fileids']))) {
                exit(json_encode(['code'=>-1, 'msg'=>'无权限']));
            }
        }
        
        echo json_encode($fileHelper->setPassword($uid, $fileId, $password, $oldPassword));
        break;

    case 'get_description':
        ensure_file_description_column($DB);
        $fileId = intval($_POST['file_id']);
        if($fileId <= 0) exit(json_encode(['code'=>-1, 'msg'=>'参数错误']));
        $row = $DB->getRow("SELECT id,description FROM pre_file WHERE id=:id AND uid=:uid LIMIT 1", [':id'=>$fileId, ':uid'=>$uid]);
        if(!$row) exit(json_encode(['code'=>-1, 'msg'=>'文件不存在或无权限']));
        echo json_encode(['code'=>0, 'description'=>($row['description'] ? $row['description'] : '')]);
        break;

    case 'set_description':
        ensure_file_description_column($DB);
        $fileId = intval($_POST['file_id']);
        $description = isset($_POST['description']) ? trim($_POST['description']) : '';
        if($fileId <= 0) exit(json_encode(['code'=>-1, 'msg'=>'参数错误']));
        if(strlen($description) > 50000) exit(json_encode(['code'=>-1, 'msg'=>'说明内容过长']));
        $row = $DB->getRow("SELECT id FROM pre_file WHERE id=:id AND uid=:uid LIMIT 1", [':id'=>$fileId, ':uid'=>$uid]);
        if(!$row) exit(json_encode(['code'=>-1, 'msg'=>'文件不存在或无权限']));
        $DB->exec("UPDATE pre_file SET description=:d WHERE id=:id AND uid=:uid", [':d'=>($description === '' ? null : $description), ':id'=>$fileId, ':uid'=>$uid]);
        echo json_encode(['code'=>0, 'msg'=>'保存成功']);
        break;

    case 'batch_rename':
        $fileIds = isset($_POST['file_ids']) ? $_POST['file_ids'] : [];
        $pattern = trim($_POST['pattern']);
        if (empty($fileIds)) exit(json_encode(['code'=>-1, 'msg'=>'未选择文件']));
        echo json_encode($fileHelper->batchRename($uid, $fileIds, $pattern));
        break;

    case 'batch_set_password':
        $fileIds = isset($_POST['file_ids']) ? $_POST['file_ids'] : [];
        $password = trim($_POST['password']);
        if (empty($fileIds)) exit(json_encode(['code'=>-1, 'msg'=>'未选择文件']));
        echo json_encode($fileHelper->batchSetPassword($uid, $fileIds, $password));
        break;

    case 'batch_copy':
        $fileIds = isset($_POST['file_ids']) ? $_POST['file_ids'] : [];
        $targetId = intval($_POST['target_id']);
        if (empty($fileIds)) exit(json_encode(['code'=>-1, 'msg'=>'未选择文件']));

        if ($islogin2) {
            $quota = check_user_quota($userrow);
            if ($quota['code'] !== 0) {
                exit(json_encode(['code'=>-1, 'msg'=>$quota['msg']]));
            }
        }

        echo json_encode($fileHelper->batchCopy($uid, $fileIds, $targetId));
        break;

    case 'get_file_share_info':
        ensure_file_share_columns($DB);
        $fileId = intval($_POST['file_id']);
        if($fileId <= 0) exit(json_encode(['code'=>-1, 'msg'=>'参数错误']));

        // 检查权限（支持游客）
        if ($is_guest) {
            $guestIds = get_guest_file_ids();
            $row = $DB->getRow("SELECT * FROM pre_file WHERE id=:id", [':id'=>$fileId]);
            if(!$row) exit(json_encode(['code'=>-1, 'msg'=>'文件不存在']));
            $has_token = isset($row['guest_token']) && $row['guest_token'] === get_guest_token();
            if (!$has_token && !in_array($fileId, $guestIds) && (!isset($_SESSION['fileids']) || !in_array($fileId, $_SESSION['fileids']))) {
                exit(json_encode(['code'=>-1, 'msg'=>'无权限']));
            }
        } else {
            $row = $DB->getRow("SELECT id,name,hash,share_key,share_type,share_pwd,share_notice FROM pre_file WHERE id=:fid AND uid=:uid LIMIT 1", [':fid'=>$fileId, ':uid'=>$uid]);
            if(!$row) exit(json_encode(['code'=>-1, 'msg'=>'文件不存在或无权限']));
        }

        if(empty($row['share_key'])){
            $shareKey = substr(md5(uniqid((string)$uid, true).mt_rand()), 0, 16);
            $DB->exec("UPDATE pre_file SET share_key=:k WHERE id=:fid", [':k'=>$shareKey, ':fid'=>$fileId]);
            $row['share_key'] = $shareKey;
        }
        // 获取分享链接
        $shareLink = $siteurl . 'share.php?key=' . $row['share_key'];
        $directLink = $siteurl . 'file.php?hash=' . $row['hash'];
        echo json_encode([
            'code'=>0,
            'data'=>[
                'file_id'=>(int)$row['id'],
                'name'=>$row['name'],
                'share_key'=>$row['share_key'],
                'share_type'=>(int)$row['share_type'],
                'share_notice'=>$row['share_notice'] ? $row['share_notice'] : '',
                'share_link'=>$shareLink,
                'direct_link'=>$directLink
            ]
        ]);
        break;

case 'set_file_share':
        ensure_file_share_columns($DB);
        $fileId = intval($_POST['file_id']);
        if($fileId <= 0) exit(json_encode(['code'=>-1, 'msg'=>'参数错误']));

        // 检查权限（支持游客）
        if ($is_guest) {
            $guestIds = get_guest_file_ids();
            $row = $DB->getRow("SELECT * FROM pre_file WHERE id=:id", [':id'=>$fileId]);
            if(!$row) exit(json_encode(['code'=>-1, 'msg'=>'文件不存在']));
            $has_token = isset($row['guest_token']) && $row['guest_token'] === get_guest_token();
            if (!$has_token && !in_array($fileId, $guestIds) && (!isset($_SESSION['fileids']) || !in_array($fileId, $_SESSION['fileids']))) {
                exit(json_encode(['code'=>-1, 'msg'=>'无权限']));
            }
        } else {
            $row = $DB->getRow("SELECT id,share_key FROM pre_file WHERE id=:fid AND uid=:uid LIMIT 1", [':fid'=>$fileId, ':uid'=>$uid]);
            if(!$row) exit(json_encode(['code'=>-1, 'msg'=>'文件不存在或无权限']));
        }

        $shareType = isset($_POST['share_type']) ? intval($_POST['share_type']) : 0;
        $shareType = $shareType ? 1 : 0;
        $shareNotice = isset($_POST['share_notice']) ? trim($_POST['share_notice']) : '';

        if(strlen($shareNotice) > 20000){
            exit(json_encode(['code'=>-1, 'msg'=>'公告内容过长']));
        }
        $shareKey = !empty($row['share_key']) ? $row['share_key'] : substr(md5(uniqid((string)$uid, true).mt_rand()), 0, 16);
        // 注意：密码使用文件原有的密码保护字段，不在share_pwd中存储
        $DB->exec("UPDATE pre_file SET share_key=:k,share_type=:type,share_notice=:notice WHERE id=:fid", [
            ':k'=>$shareKey,
            ':type'=>$shareType,
            ':notice'=>$shareNotice === '' ? null : $shareNotice,
            ':fid'=>$fileId
        ]);
        $shareLink = $siteurl . 'share.php?key=' . $shareKey;
        echo json_encode(['code'=>0, 'msg'=>'保存成功', 'share_key'=>$shareKey, 'share_link'=>$shareLink]);
        break;

    case 'transfer_preview':
        $url = isset($_POST['url']) ? trim($_POST['url']) : '';
        if(empty($url)) exit(json_encode(['code'=>-1, 'msg'=>'链接不能为空']));

        $parsed = parse_url($url);
        $path = isset($parsed['path']) ? $parsed['path'] : '';
        $query = isset($parsed['query']) ? $parsed['query'] : '';
        parse_str($query, $params);

        if((strpos($path, '/file.php') !== false || strpos($path, '/down.php') !== false) && isset($params['hash'])) {
            $hash = trim($params['hash']);
            $fileRow = $DB->getRow("SELECT id,name,size,type,pwd,uid FROM pre_file WHERE hash=:hash LIMIT 1", [':hash'=>$hash]);
            if(!$fileRow) exit(json_encode(['code'=>-1, 'msg'=>'文件不存在或链接已失效']));
            if($fileRow['block'] >= 1) exit(json_encode(['code'=>-1, 'msg'=>'文件已被屏蔽']));

            $isOwner = $islogin2 && intval($uid) === intval($fileRow['uid']);
            $needPwd = !empty($fileRow['pwd']) && !$isOwner;

            echo json_encode([
                'code'=>0,
                'type'=>'file',
                'name'=>$fileRow['name'],
                'size'=>$fileRow['size'],
                'need_password'=>$needPwd,
                'source'=>$siteurl . 'file.php?hash=' . $hash
            ]);
            break;
        }

        if(strpos($path, '/share.php') !== false && isset($params['key'])) {
            ensure_file_share_columns($DB);
            $key = trim($params['key']);
            $fileRow = $DB->getRow("SELECT id,name,size,type,pwd,uid,hash FROM pre_file WHERE share_key=:key LIMIT 1", [':key'=>$key]);
            if(!$fileRow) exit(json_encode(['code'=>-1, 'msg'=>'文件不存在或链接已失效']));
            if($fileRow['block'] >= 1) exit(json_encode(['code'=>-1, 'msg'=>'文件已被屏蔽']));

            $isOwner = $islogin2 && intval($uid) === intval($fileRow['uid']);
            $needPwd = !empty($fileRow['pwd']) && !$isOwner;

            echo json_encode([
                'code'=>0,
                'type'=>'file',
                'name'=>$fileRow['name'],
                'size'=>$fileRow['size'],
                'need_password'=>$needPwd,
                'source'=>$siteurl . 'share.php?key=' . $key
            ]);
            break;
        }

        if(strpos($path, '/folder.php') !== false && isset($params['key'])) {
            $key = trim($params['key']);
            $folderRow = $DB->getRow("SELECT folder_id,name,uid,share_need_pwd,share_pwd FROM pre_folder WHERE share_key=:key LIMIT 1", [':key'=>$key]);
            if(!$folderRow) exit(json_encode(['code'=>-1, 'msg'=>'文件夹不存在或链接已失效']));

            $isOwner = $islogin2 && intval($uid) === intval($folderRow['uid']);
            $needPwd = intval($folderRow['share_need_pwd']) === 1 && !$isOwner;

            $subFolders = $DB->getAll("SELECT folder_id FROM pre_folder WHERE uid=:uid AND parent_id=:pid", [':uid'=>$folderRow['uid'], ':pid'=>$folderRow['folder_id']]);
            $files = $DB->getAll("SELECT id FROM pre_file WHERE uid=:uid AND folder_id=:pid", [':uid'=>$folderRow['uid'], ':pid'=>$folderRow['folder_id']]);

            echo json_encode([
                'code'=>0,
                'type'=>'folder',
                'name'=>$folderRow['name'],
                'folder_count'=>count($subFolders),
                'file_count'=>count($files),
                'need_password'=>$needPwd,
                'source'=>$siteurl . 'folder.php?key=' . $key
            ]);
            break;
        }

        exit(json_encode(['code'=>-1, 'msg'=>'无法识别的链接格式，请确保是文件直链或文件夹分享链接']));
        break;

    case 'transfer':
        $url = isset($_POST['url']) ? trim($_POST['url']) : '';
        $password = isset($_POST['password']) ? trim($_POST['password']) : '';
        $targetFolder = isset($_POST['target_folder']) ? intval($_POST['target_folder']) : 0;

        if(empty($url)) exit(json_encode(['code'=>-1, 'msg'=>'链接不能为空']));

        if(!$islogin2) exit(json_encode(['code'=>-1, 'msg'=>'请登录后再进行转存']));

        $quota = check_user_quota($userrow);
        if ($quota['code'] !== 0) exit(json_encode(['code'=>-1, 'msg'=>$quota['msg']]));

        $parsed = parse_url($url);
        $path = isset($parsed['path']) ? $parsed['path'] : '';
        $query = isset($parsed['query']) ? $parsed['query'] : '';
        parse_str($query, $params);

        if((strpos($path, '/file.php') !== false || strpos($path, '/down.php') !== false) && isset($params['hash'])) {
            $hash = trim($params['hash']);
            $fileRow = $DB->getRow("SELECT id,name,size,type,hash,pwd,uid FROM pre_file WHERE hash=:hash LIMIT 1", [':hash'=>$hash]);
            if(!$fileRow) exit(json_encode(['code'=>-1, 'msg'=>'文件不存在或链接已失效']));
            if($fileRow['block'] >= 1) exit(json_encode(['code'=>-1, 'msg'=>'文件已被屏蔽']));

            $isOwner = intval($uid) === intval($fileRow['uid']);
            if(!empty($fileRow['pwd']) && !$isOwner) {
                $info = password_get_info($fileRow['pwd']);
                if ($info['algo'] != 0) {
                    if(!password_verify($password, $fileRow['pwd'])) {
                        exit(json_encode(['code'=>-1, 'msg'=>'访问密码错误']));
                    }
                } else {
                    if($fileRow['pwd'] !== $password) {
                        exit(json_encode(['code'=>-1, 'msg'=>'访问密码错误']));
                    }
                }
            }

            $uniqueName = $fileHelper->getUniqueName($uid, $targetFolder, $fileRow['name']);

            $fileSize = intval($fileRow['size']);
            if ($userrow['storage_limit'] > 0 && ($userrow['storage_used'] + $fileSize) > ($userrow['storage_limit'] * 1024 * 1024)) {
                exit(json_encode(['code'=>-1, 'msg'=>'存储空间不足，无法转存该文件']));
            }

            $ip = function_exists('real_ip') ? real_ip() : $_SERVER['REMOTE_ADDR'];
            $sql = "INSERT INTO `pre_file` (`name`,`type`,`size`,`hash`,`addtime`,`ip`,`hide`,`pwd`,`uid`,`folder_id`) VALUES (:name,:type,:size,:hash,NOW(),:ip,0,NULL,:uid,:folder_id)";
            $data = [
                ':name'=>$uniqueName,
                ':type'=>$fileRow['type'],
                ':size'=>$fileSize,
                ':hash'=>$fileRow['hash'],
                ':ip'=>$ip,
                ':uid'=>$uid,
                ':folder_id'=>$targetFolder
            ];

            if($DB->exec($sql, $data)) {
                $DB->exec("UPDATE pre_user SET storage_used=storage_used+:size WHERE uid=:uid", [':size'=>$fileSize, ':uid'=>$uid]);
                exit(json_encode(['code'=>0, 'msg'=>'转存成功', 'success_count'=>1, 'fail_count'=>0]));
            } else {
                exit(json_encode(['code'=>-1, 'msg'=>'转存失败']));
            }
            break;
        }

        if(strpos($path, '/share.php') !== false && isset($params['key'])) {
            ensure_file_share_columns($DB);
            $key = trim($params['key']);
            $fileRow = $DB->getRow("SELECT id,name,size,type,hash,pwd,uid FROM pre_file WHERE share_key=:key LIMIT 1", [':key'=>$key]);
            if(!$fileRow) exit(json_encode(['code'=>-1, 'msg'=>'文件不存在或链接已失效']));
            if($fileRow['block'] >= 1) exit(json_encode(['code'=>-1, 'msg'=>'文件已被屏蔽']));

            $isOwner = intval($uid) === intval($fileRow['uid']);
            if(!empty($fileRow['pwd']) && !$isOwner) {
                $info = password_get_info($fileRow['pwd']);
                if ($info['algo'] != 0) {
                    if(!password_verify($password, $fileRow['pwd'])) {
                        exit(json_encode(['code'=>-1, 'msg'=>'访问密码错误']));
                    }
                } else {
                    if($fileRow['pwd'] !== $password) {
                        exit(json_encode(['code'=>-1, 'msg'=>'访问密码错误']));
                    }
                }
            }

            $uniqueName = $fileHelper->getUniqueName($uid, $targetFolder, $fileRow['name']);

            $fileSize = intval($fileRow['size']);
            if ($userrow['storage_limit'] > 0 && ($userrow['storage_used'] + $fileSize) > ($userrow['storage_limit'] * 1024 * 1024)) {
                exit(json_encode(['code'=>-1, 'msg'=>'存储空间不足，无法转存该文件']));
            }

            $ip = function_exists('real_ip') ? real_ip() : $_SERVER['REMOTE_ADDR'];
            $sql = "INSERT INTO `pre_file` (`name`,`type`,`size`,`hash`,`addtime`,`ip`,`hide`,`pwd`,`uid`,`folder_id`) VALUES (:name,:type,:size,:hash,NOW(),:ip,0,NULL,:uid,:folder_id)";
            $data = [
                ':name'=>$uniqueName,
                ':type'=>$fileRow['type'],
                ':size'=>$fileSize,
                ':hash'=>$fileRow['hash'],
                ':ip'=>$ip,
                ':uid'=>$uid,
                ':folder_id'=>$targetFolder
            ];

            if($DB->exec($sql, $data)) {
                $DB->exec("UPDATE pre_user SET storage_used=storage_used+:size WHERE uid=:uid", [':size'=>$fileSize, ':uid'=>$uid]);
                exit(json_encode(['code'=>0, 'msg'=>'转存成功', 'success_count'=>1, 'fail_count'=>0]));
            } else {
                exit(json_encode(['code'=>-1, 'msg'=>'转存失败']));
            }
            break;
        }

        if(strpos($path, '/folder.php') !== false && isset($params['key'])) {
            $key = trim($params['key']);
            $folderRow = $DB->getRow("SELECT folder_id,name,uid,share_need_pwd,share_pwd FROM pre_folder WHERE share_key=:key LIMIT 1", [':key'=>$key]);
            if(!$folderRow) exit(json_encode(['code'=>-1, 'msg'=>'文件夹不存在或链接已失效']));

            $isOwner = intval($uid) === intval($folderRow['uid']);
            if(intval($folderRow['share_need_pwd']) === 1 && !$isOwner) {
                if($folderRow['share_pwd'] !== $password) {
                    exit(json_encode(['code'=>-1, 'msg'=>'访问密码错误']));
                }
            }

            $newFolderName = $fileHelper->getUniqueFolderName($uid, $targetFolder, $folderRow['name']);
            $result = $folder->create($uid, $newFolderName, $targetFolder);
            if($result['code'] !== 0) exit(json_encode(['code'=>-1, 'msg'=>$result['msg']]));

            $newFolderId = $result['folder_id'];
            transferFolderContents($DB, $fileHelper, $folderRow['uid'], $folderRow['folder_id'], $uid, $newFolderId, $userrow);

            exit(json_encode(['code'=>0, 'msg'=>'转存成功', 'success_count'=>1, 'fail_count'=>0]));
            break;
        }

        exit(json_encode(['code'=>-1, 'msg'=>'无法识别的链接格式']));
        break;

    function transferFolderContents($DB, $fileHelper, $sourceUid, $sourceFolderId, $targetUid, $targetFolderId, $userrow) {
        $subFolders = $DB->getAll("SELECT folder_id,name FROM pre_folder WHERE uid=:uid AND parent_id=:pid ORDER BY sort ASC", [':uid'=>$sourceUid, ':pid'=>$sourceFolderId]);
        $files = $DB->getAll("SELECT name,type,size,hash FROM pre_file WHERE uid=:uid AND folder_id=:pid", [':uid'=>$sourceUid, ':pid'=>$sourceFolderId]);
        
        foreach($subFolders as $sf) {
            $newSubName = $fileHelper->getUniqueName($targetUid, $targetFolderId, $sf['name']);
            $DB->exec("INSERT INTO pre_folder (uid,name,parent_id,created_at,updated_at) VALUES (:uid,:name,:pid,NOW(),NOW())", [':uid'=>$targetUid, ':name'=>$newSubName, ':pid'=>$targetFolderId]);
            $newSubId = $DB->lastInsertId();
            transferFolderContents($DB, $fileHelper, $sourceUid, $sf['folder_id'], $targetUid, $newSubId, $userrow);
        }
        
        foreach($files as $f) {
            $uniqueName = $fileHelper->getUniqueName($targetUid, $targetFolderId, $f['name']);
            $fileSize = intval($f['size']);
            
            if ($userrow['storage_limit'] > 0 && ($userrow['storage_used'] + $fileSize) > ($userrow['storage_limit'] * 1024 * 1024)) {
                continue;
            }
            
            $ip = function_exists('real_ip') ? real_ip() : $_SERVER['REMOTE_ADDR'];
            $DB->exec("INSERT INTO pre_file (name,type,size,hash,addtime,ip,hide,uid,folder_id) VALUES (:name,:type,:size,:hash,NOW(),:ip,0,:uid,:pid)", [
                ':name'=>$uniqueName,
                ':type'=>$f['type'],
                ':size'=>$fileSize,
                ':hash'=>$f['hash'],
                ':ip'=>$ip,
                ':uid'=>$targetUid,
                ':pid'=>$targetFolderId
            ]);
            $DB->exec("UPDATE pre_user SET storage_used=storage_used+:size WHERE uid=:uid", [':size'=>$fileSize, ':uid'=>$targetUid]);
        }
    }
        
    case 'list':
        // 获取指定文件夹下的内容（文件+文件夹）
        $parentId = isset($_GET['parent_id']) ? intval($_GET['parent_id']) : 0;
        $kw = isset($_GET['kw']) ? trim($_GET['kw']) : '';
        
        if (!empty($kw)) {
            if ($is_guest) {
                $guest_token = get_guest_token();
                $guestIds = get_guest_file_ids();
                $sessionIds = (isset($_SESSION['fileids']) && count($_SESSION['fileids'])>0) ? $_SESSION['fileids'] : [];
                $mergeIds = array_values(array_unique(array_merge($guestIds, $sessionIds)));
                
                $idSql = "";
                if(count($mergeIds) > 0){
                    $ids = implode(',', $mergeIds);
                    $idSql = "id IN ($ids)";
                }
                
                $where = "uid=0 AND name LIKE :kw";
                if ($guest_token) {
                    $where .= " AND (guest_token = '$guest_token'" . ($idSql ? " OR $idSql" : "") . ")";
                } elseif ($idSql) {
                    $where .= " AND ($idSql)";
                } else {
                    $where .= " AND 1=2";
                }
                
                $folders = [];
                $files = $DB->getAll("SELECT * FROM pre_file WHERE $where ORDER BY id DESC", [':kw'=>'%'.$kw.'%']);
            } else {
                $folders = $DB->getAll("SELECT * FROM pre_folder WHERE uid=:uid AND name LIKE :kw ORDER BY folder_id DESC", [':uid'=>$uid, ':kw'=>'%'.$kw.'%']);
                $files = $DB->getAll("SELECT * FROM pre_file WHERE uid=:uid AND name LIKE :kw ORDER BY id DESC", [':uid'=>$uid, ':kw'=>'%'.$kw.'%']);
            }
            $path = [];
        } else {
            $folders = $folder->getFolders($uid, $parentId);
            
            try {
                if ($is_guest) {
                    $guest_token = get_guest_token();
                    $guestIds = get_guest_file_ids();
                    $sessionIds = (isset($_SESSION['fileids']) && count($_SESSION['fileids'])>0) ? $_SESSION['fileids'] : [];
                    $mergeIds = array_values(array_unique(array_merge($guestIds, $sessionIds)));
                    
                    $idSql = "";
                    if(count($mergeIds) > 0){
                        $ids = implode(',', $mergeIds);
                        $idSql = "id IN ($ids)";
                    }
                    
                    $where = "uid=0 AND folder_id=:pid";
                    if ($guest_token) {
                        $where .= " AND (guest_token = '$guest_token'" . ($idSql ? " OR $idSql" : "") . ")";
                    } elseif ($idSql) {
                        $where .= " AND ($idSql)";
                    } else {
                        $where .= " AND 1=2";
                    }
                    
                    $files = $DB->getAll("SELECT * FROM pre_file WHERE $where ORDER BY id DESC", [':pid'=>$parentId]);
                } else {
                    $files = $DB->getAll("SELECT * FROM pre_file WHERE uid=:uid AND folder_id=:pid ORDER BY id DESC", [':uid'=>$uid, ':pid'=>$parentId]);
                }
            } catch (Exception $e) {
                $files = []; 
            }
            
            $path = $folder->getPath($uid, $parentId);
        }
        
        $quota = ['code' => 0];
        if ($islogin2) {
            $quota = check_user_quota($userrow);
        }
        
        echo json_encode(['code'=>0, 'folders'=>$folders, 'files'=>$files, 'path'=>$path, 'quota'=>$quota]);
        break;

    case 'simple_upload':
        if(!isset($_FILES['file'])) exit(json_encode(['code'=>-1, 'msg'=>'请选择文件']));
        $folderId = intval($_POST['folder_id']);
        if($folderId < 0) $folderId = 0;
        if($folderId > 0){
            if(!$islogin2) exit(json_encode(['code'=>-1, 'msg'=>'请登录后选择文件夹']));
            $folderRow = $DB->getRow("SELECT folder_id FROM pre_folder WHERE folder_id=:fid AND uid=:uid LIMIT 1", [':fid'=>$folderId, ':uid'=>$uid]);
            if(!$folderRow) exit(json_encode(['code'=>-1, 'msg'=>'目标文件夹不存在或无权限']));
        }
        
        $file = $_FILES['file'];
        $name = trim(htmlspecialchars($file['name']));
        $size = intval($file['size']);
        $name = str_replace(['/','\\',':','*','"','<','>','|','?'],'',$name);
        
        if(empty($name)) exit(json_encode(['code'=>-1, 'msg'=>'文件名不能为空']));

        if ($islogin2) {
            $quota = check_user_quota($userrow);
            if ($quota['code'] !== 0) {
                exit(json_encode(['code' => -1, 'msg' => $quota['msg']]));
            }
            if ($userrow['storage_limit'] > 0 && ($userrow['storage_used'] + $size) > ($userrow['storage_limit'] * 1024 * 1024)) {
                exit(json_encode(['code' => -1, 'msg' => '您的存储空间已不足']));
            }
        }
        
        $name = $fileHelper->getUniqueName($uid, $folderId, $name);

        $ext = get_file_ext($name);
        $hash = md5_file($file['tmp_name']);
        
        $stor = \lib\StorHelper::getModel($conf['storage']);
        if(!$stor->exists($hash)) {
            $res = $stor->upload($hash, $file['tmp_name'], minetype($ext));
            if(!$res) exit(json_encode(['code'=>-1, 'msg'=>'上传失败:'.$stor->errmsg()]));
        }
        
        $ip = function_exists('real_ip') ? real_ip() : $_SERVER['REMOTE_ADDR'];
        $guest_token = ($uid == 0) ? get_guest_token() : null;
        
        $data = [
            ':name' => $name,
            ':type' => $ext,
            ':size' => $size,
            ':hash' => $hash,
            ':ip' => $ip,
            ':hide' => 0,
            ':pwd' => null,
            ':uid' => $uid,
            ':folder_id' => $folderId,
            ':guest_token' => $guest_token
        ];
        
        $sql = "INSERT INTO `pre_file` (`name`,`type`,`size`,`hash`,`addtime`,`ip`,`hide`,`pwd`,`uid`,`folder_id`,`guest_token`) VALUES (:name,:type,:size,:hash,NOW(),:ip,:hide,:pwd,:uid,:folder_id,:guest_token)";
        
        if($DB->exec($sql, $data)) {
            if($uid > 0){
                $DB->exec("UPDATE pre_user SET storage_used=storage_used+:size WHERE uid=:uid", [':size'=>$size, ':uid'=>$uid]);
            }
            echo json_encode(['code'=>0, 'msg'=>'上传成功']);
        } else {
            echo json_encode(['code'=>-1, 'msg'=>'数据库写入失败']);
        }
        break;
        
    default:
        echo json_encode(['code' => -4, 'msg' => 'No Act']);
        break;
}
?>
