<?php
ob_start();
include(dirname(__DIR__) . '/includes/common.php');
ob_end_clean();

if($islogin==1){}else exit('{"code":-1,"msg":"请先登录"}');

@header('Content-Type: application/json; charset=UTF-8');
$act = isset($_GET['act']) ? daddslashes($_GET['act']) : null;

switch($act) {

case 'get_qq_list':
    $page = intval($_POST['page'] ?? 1);
    $pagesize = intval($_POST['pagesize'] ?? 30);
    if ($pagesize < 10) $pagesize = 30;
    if ($pagesize > 500) $pagesize = 500;
    $offset = $pagesize * ($page - 1);
    $qq = daddslashes($_POST['qq'] ?? '');
    $status = $_POST['status'] ?? '';

    $where = "1=1";
    if ($qq) $where .= " AND qq LIKE '%{$qq}%'";
    if ($status === '2') {
        $where .= " AND vip_time < NOW()";
    } elseif ($status !== '') {
        $where .= " AND login_status='" . intval($status) . "'";
    }

    $total = $DB->getColumn("SELECT COUNT(*) FROM " . DBQZ . "qzone_qq WHERE {$where}");
    $pages = $total > 0 ? ceil($total / $pagesize) : 1;

    $data = $DB->getAll("SELECT * FROM " . DBQZ . "qzone_qq WHERE {$where} ORDER BY id DESC LIMIT {$offset},{$pagesize}");

    exit(json_encode(['code' => 1, 'data' => $data, 'total' => $total, 'pages' => $pages]));
break;

case 'find_qq':
    $qq = daddslashes($_POST['qq'] ?? '');
    if (!$qq) exit(json_encode(['code' => -1, 'msg' => 'QQ号不能为空']));

    $row = $DB->getRow("SELECT id, qq FROM " . DBQZ . "qzone_qq WHERE qq='{$qq}'");
    if (!$row) exit(json_encode(['code' => -1, 'msg' => '未找到该QQ号']));

    exit(json_encode(['code' => 1, 'data' => $row]));
break;

case 'delete_qq':
    $id = intval($_POST['id']);
    if (!$id) exit(json_encode(['code' => -1, 'msg' => '参数错误']));

    $DB->exec("DELETE FROM " . DBQZ . "qzone_qq WHERE id='{$id}'");
    $DB->exec("DELETE FROM " . DBQZ . "qzone_config WHERE qid='{$id}'");
    $DB->exec("DELETE FROM " . DBQZ . "qzone_log WHERE qid='{$id}'");

    exit(json_encode(['code' => 1, 'msg' => '删除成功']));
break;

case 'batch_delete_qq':
    $ids = $_POST['ids'] ?? '';
    if (!$ids) exit(json_encode(['code' => -1, 'msg' => '参数错误']));

    $idArr = array_filter(array_map('intval', explode(',', $ids)));
    if (empty($idArr)) exit(json_encode(['code' => -1, 'msg' => '参数错误']));

    $idStr = implode(',', $idArr);

    $DB->exec("DELETE FROM " . DBQZ . "qzone_qq WHERE id IN ({$idStr})");
    $DB->exec("DELETE FROM " . DBQZ . "qzone_config WHERE qid IN ({$idStr})");
    $DB->exec("DELETE FROM " . DBQZ . "qzone_log WHERE qid IN ({$idStr})");

    exit(json_encode(['code' => 1, 'msg' => '批量删除成功']));
break;

case 'batch_set_vip':
    $ids = $_POST['ids'] ?? '';
    $days = intval($_POST['days']);
    if (!$ids) exit(json_encode(['code' => -1, 'msg' => '参数错误']));

    $idArr = array_filter(array_map('intval', explode(',', $ids)));
    if (empty($idArr)) exit(json_encode(['code' => -1, 'msg' => '参数错误']));

    $count = 0;
    foreach ($idArr as $id) {
        $currentVip = $DB->getColumn("SELECT vip_time FROM " . DBQZ . "qzone_qq WHERE id='{$id}'");

        if ($days >= 0) {
            $startTime = strtotime($currentVip) > time() ? $currentVip : date('Y-m-d H:i:s');
            $newVipTime = date('Y-m-d H:i:s', strtotime($startTime) + $days * 86400);
        } else {
            if (strtotime($currentVip) > time()) {
                $newVipTime = date('Y-m-d H:i:s', strtotime($currentVip) + $days * 86400);
                if (strtotime($newVipTime) < time()) {
                    $newVipTime = date('Y-m-d H:i:s', time() - 86400);
                }
            } else {
                $newVipTime = $currentVip;
            }
        }

        $DB->exec("UPDATE " . DBQZ . "qzone_qq SET vip_time='{$newVipTime}' WHERE id='{$id}'");
        $count++;
    }

    exit(json_encode(['code' => 1, 'msg' => '批量操作成功', 'count' => $count]));
break;

case 'set_vip':
    $qid = intval($_POST['qid']);
    $days = intval($_POST['days']);
    if (!$qid) exit(json_encode(['code' => -1, 'msg' => '参数错误']));

    $currentVip = $DB->getColumn("SELECT vip_time FROM " . DBQZ . "qzone_qq WHERE id='{$qid}'");

    if ($days >= 0) {
        $startTime = strtotime($currentVip) > time() ? $currentVip : date('Y-m-d H:i:s');
        $newVipTime = date('Y-m-d H:i:s', strtotime($startTime) + $days * 86400);
    } else {
        if (strtotime($currentVip) > time()) {
            $newVipTime = date('Y-m-d H:i:s', strtotime($currentVip) + $days * 86400);
            if (strtotime($newVipTime) < time()) {
                $newVipTime = date('Y-m-d H:i:s', time() - 86400);
            }
        } else {
            $newVipTime = $currentVip;
        }
    }

    $DB->exec("UPDATE " . DBQZ . "qzone_qq SET vip_time='{$newVipTime}' WHERE id='{$qid}'");

    $msg = $days >= 0 ? '增加' . $days . '天成功' : '减少' . abs($days) . '天成功';
    exit(json_encode(['code' => 1, 'msg' => $msg, 'vip_time' => $newVipTime]));
break;

case 'save_config':
    $qzone_val = isset($_POST['qzone_enabled']) ? '1' : '0';
    $freeSsmzCycle = intval($_POST['qzone_free_ssmz_cycle'] ?? 60);
    if ($freeSsmzCycle < 20) $freeSsmzCycle = 20;
    if ($freeSsmzCycle > 86400) $freeSsmzCycle = 86400;
    $freeSsmpCycle = intval($_POST['qzone_free_ssmp_cycle'] ?? 60);
    if ($freeSsmpCycle < 20) $freeSsmpCycle = 20;
    if ($freeSsmpCycle > 86400) $freeSsmpCycle = 86400;
    $freeHourlySsmz = intval($_POST['qzone_free_hourly_ssmz'] ?? 0);
    $freeHourlySsmp = intval($_POST['qzone_free_hourly_ssmp'] ?? 0);
    if ($freeHourlySsmz < 0) $freeHourlySsmz = 0;
    if ($freeHourlySsmp < 0) $freeHourlySsmp = 0;
    if ($freeHourlySsmz > 9999) $freeHourlySsmz = 9999;
    if ($freeHourlySsmp > 9999) $freeHourlySsmp = 9999;
    $configs = [
        'qzone_enabled' => $qzone_val,
        'qzone_tail_pl' => daddslashes($_POST['qzone_tail_pl'] ?? ''),
        'qzone_tail_zdfss' => daddslashes($_POST['qzone_tail_zdfss'] ?? ''),
        'qzone_free_ssmz_cycle' => strval($freeSsmzCycle),
        'qzone_free_ssmp_cycle' => strval($freeSsmpCycle),
        'qzone_free_hourly_ssmz' => strval($freeHourlySsmz),
        'qzone_free_hourly_ssmp' => strval($freeHourlySsmp),
        'qzone_ssmz_vip' => isset($_POST['qzone_ssmz_vip']) ? '1' : '0',
        'qzone_ssmz_hourly_vip' => isset($_POST['qzone_ssmz_hourly_vip']) ? '1' : '0',
        'qzone_ssmp_vip' => isset($_POST['qzone_ssmp_vip']) ? '1' : '0',
        'qzone_ssmp_hourly_vip' => isset($_POST['qzone_ssmp_hourly_vip']) ? '1' : '0',
        'qzone_ssmz_cycle_vip' => isset($_POST['qzone_ssmz_cycle_vip']) ? '1' : '0',
        'qzone_ssmp_cycle_vip' => isset($_POST['qzone_ssmp_cycle_vip']) ? '1' : '0',
        'qzone_zdfss_vip' => isset($_POST['qzone_zdfss_vip']) ? '1' : '0',
        'qzone_zdfss_delete_vip' => isset($_POST['qzone_zdfss_delete_vip']) ? '1' : '0',
        'qzone_zfss_vip' => isset($_POST['qzone_zfss_vip']) ? '1' : '0',
        'qzone_sign_vip' => isset($_POST['qzone_sign_vip']) ? '1' : '0',
        'qzone_clear_ss_vip' => isset($_POST['qzone_clear_ss_vip']) ? '1' : '0',
        'qzone_clear_ly_vip' => isset($_POST['qzone_clear_ly_vip']) ? '1' : '0',
        'qzone_cloud_update_status' => isset($_POST['qzone_cloud_update_status']) ? '1' : '0',
        'qzone_cloud_cookie' => isset($_POST['qzone_cloud_cookie']) ? '1' : '0'
    ];

    foreach ($configs as $k => $v) {
        $DB->exec("REPLACE INTO bot_config SET k='{$k}', v='{$v}'");
    }

    exit(json_encode(['code' => 1, 'msg' => '保存成功']));
break;

case 'save_nodes':
    $raw = $_POST['nodes'] ?? '';
    $arr = json_decode($raw, true);
    if (!is_array($arr)) $arr = [];
    $out = [];
    foreach ($arr as $n) {
        $name = trim($n['name'] ?? '');
        $type = isset($n['type']) ? $n['type'] : 'url';
        $sort = isset($n['sort']) ? intval($n['sort']) : 0;
        $enabled = isset($n['enabled']) ? intval($n['enabled']) : 1;
        if ($enabled !== 0) $enabled = 1;

        if ($type === 'socks5') {
            $socks5_host = trim($n['socks5_host'] ?? '');
            $socks5_port = intval($n['socks5_port'] ?? 0);
            $socks5_user = trim($n['socks5_user'] ?? '');
            $socks5_pass = trim($n['socks5_pass'] ?? '');
            if ($name !== '' && $socks5_host !== '' && $socks5_port > 0) {
                $out[] = [
                    'name' => $name,
                    'type' => 'socks5',
                    'sort' => $sort,
                    'enabled' => $enabled,
                    'socks5_host' => $socks5_host,
                    'socks5_port' => $socks5_port,
                    'socks5_user' => $socks5_user,
                    'socks5_pass' => $socks5_pass
                ];
            }
        } else {
            $url = trim($n['url'] ?? '');
            if ($name !== '' && $url !== '') {
                $out[] = ['name' => $name, 'url' => $url, 'sort' => $sort, 'enabled' => $enabled];
            }
        }
    }
    $json = addslashes(json_encode($out));
    $DB->exec("REPLACE INTO bot_config SET k='qzone_node_list', v='{$json}'");
    $main_name = isset($_POST['main_name']) ? trim($_POST['main_name']) : '';
    $main_name = addslashes($main_name);
    $DB->exec("REPLACE INTO bot_config SET k='qzone_node_main_name', v='{$main_name}'");
    $main_enabled = isset($_POST['main_enabled']) ? intval($_POST['main_enabled']) : 1;
    if ($main_enabled !== 0) $main_enabled = 1;
    $main_sort = isset($_POST['main_sort']) ? intval($_POST['main_sort']) : 0;
    $DB->exec("REPLACE INTO bot_config SET k='qzone_node_main_enabled', v='{$main_enabled}'");
    $DB->exec("REPLACE INTO bot_config SET k='qzone_node_main_sort', v='{$main_sort}'");
    exit(json_encode(['code' => 1, 'msg' => '保存成功']));
break;

case 'get_nodes':
    $nodeList = [];
    $nodeJson = $DB->getColumn("SELECT v FROM bot_config WHERE k='qzone_node_list'");
    if ($nodeJson) {
        $nodeList = json_decode($nodeJson, true);
        if (!is_array($nodeList)) $nodeList = [];
    }
    $main_name = $DB->getColumn("SELECT v FROM bot_config WHERE k='qzone_node_main_name'");
    $main_enabled = $DB->getColumn("SELECT v FROM bot_config WHERE k='qzone_node_main_enabled'");
    $main_sort = $DB->getColumn("SELECT v FROM bot_config WHERE k='qzone_node_main_sort'");
    @header('Content-Type: application/json; charset=UTF-8');
    exit(json_encode([
        'code' => 1,
        'nodes' => $nodeList,
        'main_name' => $main_name ?: '主站',
        'main_enabled' => $main_enabled ?: 1,
        'main_sort' => intval($main_sort ?: 0)
    ]));
break;

case 'get_config':
    $conf = [];
    $res = $DB->getAll("SELECT k, v FROM bot_config WHERE k LIKE 'qzone_%'");
    foreach ($res as $row) {
        $conf[$row['k']] = $row['v'];
    }

    // 获取节点配置（合并到一个查询中）
    $nodeList = [];
    $nodeJson = $DB->getColumn("SELECT v FROM bot_config WHERE k='qzone_node_list'");
    if ($nodeJson) {
        $nodeList = json_decode($nodeJson, true);
        if (!is_array($nodeList)) $nodeList = [];
    }
    $main_name = $conf['qzone_node_main_name'] ?? '主站';
    $main_enabled = $conf['qzone_node_main_enabled'] ?? 1;
    $main_sort = intval($conf['qzone_node_main_sort'] ?? 0);

    @header('Content-Type: application/json; charset=UTF-8');
    exit(json_encode([
        'code' => 1,
        'config' => $conf,
        'nodes' => $nodeList,
        'main_name' => $main_name,
        'main_enabled' => $main_enabled,
        'main_sort' => $main_sort
    ]));
break;

case 'download_node_file':
    $root = dirname(__DIR__);
    $nodePhp = $root . '/user/qzone_node.php';
    $loginLib = $root . '/includes/lib/qzone/QzoneLoginService.php';
    if (!file_exists($nodePhp) || !file_exists($loginLib)) {
        @header('Content-Type: application/json; charset=UTF-8');
        exit(json_encode(['code' => -1, 'msg' => '节点文件缺失']));
    }
    if (!class_exists('ZipArchive')) {
        @header('Content-Type: application/json; charset=UTF-8');
        exit(json_encode(['code' => -1, 'msg' => '服务器未启用 ZipArchive']));
    }
    $zipName = 'qzone_node_' . date('YmdHis') . '.zip';
    $tmpZip = rtrim(sys_get_temp_dir(), DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . 'qzone_node_' . uniqid() . '.zip';
    $zip = new ZipArchive();
    if ($zip->open($tmpZip, ZipArchive::CREATE | ZipArchive::OVERWRITE) !== true) {
        @header('Content-Type: application/json; charset=UTF-8');
        exit(json_encode(['code' => -1, 'msg' => '无法创建压缩包']));
    }
    $zip->addFile($nodePhp, 'qzone_node.php');
    $zip->addEmptyDir('lib');
    $zip->addFile($loginLib, 'lib/QzoneLoginService.php');
    $readme = "秒赞扫码登录节点包（无需数据库，解压即用）\r\n\r\n部署步骤：\r\n1. 将本压缩包解压到服务器任意目录（需 PHP 环境，无需 MySQL）。\r\n2. 确保目录内包含 qzone_node.php 和 lib/QzoneLoginService.php。\r\n3. 将访问地址填到主站后台「秒赞系统设置」->「节点设置」-> 节点 URL，例如：https://你的节点域名/路径/qzone_node.php\r\n4. 用户端扫码时可选择该节点，主站负责写库，节点只负责拉取二维码和扫码结果。\r\n";
    $zip->addFromString('readme.txt', $readme);
    $zip->close();
    @header('Content-Type: application/octet-stream');
    @header('Content-Disposition: attachment; filename="' . $zipName . '"');
    @header('Content-Length: ' . filesize($tmpZip));
    readfile($tmpZip);
    @unlink($tmpZip);
    exit;
break;

case 'get_log_list':
    $page = intval($_POST['page'] ?? 1);
    $pagesize = 50;
    $offset = $pagesize * ($page - 1);
    $qq = daddslashes($_POST['qq'] ?? '');
    $type = daddslashes($_POST['type'] ?? '');

    $where = "1=1";
    if ($qq) {
        $qid = $DB->getColumn("SELECT id FROM " . DBQZ . "qzone_qq WHERE qq='{$qq}'");
        if ($qid) $where .= " AND qid='{$qid}'";
        else $where .= " AND 0";
    }
    if ($type) $where .= " AND type='{$type}'";

    $total = $DB->getColumn("SELECT COUNT(*) FROM " . DBQZ . "qzone_log WHERE {$where}");
    $pages = $total > 0 ? ceil($total / $pagesize) : 1;

    $data = $DB->getAll("SELECT l.*, q.qq FROM " . DBQZ . "qzone_log l LEFT JOIN " . DBQZ . "qzone_qq q ON l.qid=q.id WHERE {$where} ORDER BY l.id DESC LIMIT {$offset},{$pagesize}");

    exit(json_encode(['code' => 1, 'data' => $data, 'total' => $total, 'pages' => $pages]));
break;

case 'sync_cloud_time':
    $cloud_table_exists = $DB->getColumn("SHOW TABLES LIKE 'pre_qq'", 0);
    if (!$cloud_table_exists) {
        exit(json_encode(['code' => -1, 'msg' => '云端QQ表不存在']));
    }

    $cloud_qqs = [];
    $stmt = $DB->query("SELECT qq, zid, endtime_arr FROM pre_qq WHERE endtime_arr IS NOT NULL AND endtime_arr != ''");
    while ($row = $stmt->fetch()) {
        $zid = intval($row['zid']);
        $endtime_arr = json_decode($row['endtime_arr'], true);
        if (!is_array($endtime_arr) || empty($endtime_arr)) continue;

        $max_time = null;
        $max_cid = null;
        foreach ($endtime_arr as $cid => $endtime) {
            if ($endtime && $endtime !== '0000-00-00 00:00:00') {
                $time_ts = strtotime($endtime);
                if ($time_ts > 0) {
                    if ($max_time === null || $time_ts > $max_time) {
                        $max_time = $time_ts;
                        $max_cid = $cid;
                    }
                }
            }
        }

        if ($max_time && $max_time > time()) {
            $cloud_qqs[$row['qq']] = [
                'vip_time' => date('Y-m-d H:i:s', $max_time),
                'cid' => $max_cid,
                'zid' => $zid
            ];
        }
    }

    if (empty($cloud_qqs)) {
        exit(json_encode(['code' => 0, 'msg' => '没有找到云端有效的QQ']));
    }

    $qzone_qqs = [];
    $stmt = $DB->query("SELECT qq FROM " . DBQZ . "qzone_qq");
    if ($stmt) {
        while ($row = $stmt->fetch()) {
            $qzone_qqs[$row['qq']] = true;
        }
    }

    $all_cids = [];
    $stmt = $DB->query("SELECT id FROM " . DBQZ . "qzone_class ORDER BY days DESC LIMIT 1");
    $default_cid = 1;
    if ($stmt) {
        $max_cid_row = $stmt->fetch();
        $default_cid = $max_cid_row ? $max_cid_row['id'] : 1;
    }

    $added = 0;
    foreach ($cloud_qqs as $qq => $info) {
        if (isset($qzone_qqs[$qq])) continue;

        $user_id = intval($info['zid']);

        $DB->exec("INSERT INTO " . DBQZ . "qzone_qq (user_id, qq, vip_time, login_status, login_time) VALUES ({$user_id}, '{$qq}', '{$info['vip_time']}', 1, NOW())");
        $added++;
    }

    exit(json_encode(['code' => 1, 'added' => $added]));
break;

case 'clear_log':
    $DB->query("TRUNCATE TABLE " . DBQZ . "qzone_log");
    exit(json_encode(['code' => 1, 'msg' => '日志已清空']));
break;

default:
    exit(json_encode(['code' => -1, 'msg' => '无效操作']));
break;
}
