-- ============================================
-- 优化的压力测试数据生成脚本
-- 使用批量生成 + 临时表，避免循环中的随机查询
-- ============================================

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ============================================
-- 1. 批量生成用户数据
-- ============================================
DROP PROCEDURE IF EXISTS generate_users_batch;
DELIMITER $$
CREATE PROCEDURE generate_users_batch(IN batch_size INT)
BEGIN
    DECLARE batch_limit INT DEFAULT 1000;
    DECLARE batches INT;
    DECLARE current_batch INT DEFAULT 0;
    DECLARE batch_start INT;
    DECLARE batch_end INT;
    DECLARE current_limit INT;

    SET batches = CEIL(batch_size / batch_limit);

    WHILE current_batch < batches DO
        SET batch_start = current_batch * batch_limit + 1;
        SET batch_end = LEAST((current_batch + 1) * batch_limit, batch_size);
        SET current_limit = batch_end - batch_start + 1;

        -- 使用 INSERT ... SELECT 批量生成
        INSERT INTO users (phone, nickname, realname_status, risk_status, credit_score, status, created_at)
        SELECT
            CONCAT('138', LPAD(seq, 8, '0')) as phone,
            CONCAT('测试用户', seq) as nickname,
            CASE WHEN seq % 10 = 0 THEN 'unverified' ELSE 'verified' END as realname_status,
            CASE WHEN seq % 100 = 0 THEN 'frozen' ELSE 'normal' END as risk_status,
            80 + (seq % 20) as credit_score,
            'active' as status,
            DATE_SUB(NOW(), INTERVAL (seq % 365) DAY) as created_at
        FROM (
            SELECT @row := @row + 1 AS seq
            FROM
                (SELECT 0 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4
                 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) t1,
                (SELECT 0 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4
                 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) t2,
                (SELECT 0 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4
                 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) t3,
                (SELECT @row := batch_start - 1) r
            LIMIT current_limit
        ) seqs
        ON DUPLICATE KEY UPDATE id=id;

        SET current_batch = current_batch + 1;
        COMMIT;
    END WHILE;

    -- 批量生成实名记录（为已实名用户）
    INSERT INTO user_realname (user_id, provider, status, masked_name, masked_id_no, verified_at)
    SELECT
        u.id,
        'mock',
        'success',
        CONCAT('张*', CHAR(65 + (u.id % 26))),
        CONCAT('3301**********', LPAD(u.id % 10000, 4, '0')),
        DATE_SUB(NOW(), INTERVAL (u.id % 300) DAY)
    FROM users u
    WHERE u.realname_status = 'verified'
      AND NOT EXISTS (SELECT 1 FROM user_realname WHERE user_id = u.id);

    -- 批量生成钱包账户
    INSERT INTO wallet_accounts (user_id, available_balance_cent, frozen_balance_cent, status)
    SELECT
        u.id,
        (u.id % 10) * 10000,
        (u.id % 5) * 5000,
        'active'
    FROM users u
    WHERE NOT EXISTS (SELECT 1 FROM wallet_accounts WHERE user_id = u.id);

    COMMIT;
END$$
DELIMITER ;

-- ============================================
-- 2. 批量生成游戏账号和商品
-- ============================================
DROP PROCEDURE IF EXISTS generate_listings_batch;
DELIMITER $$
CREATE PROCEDURE generate_listings_batch(IN batch_size INT)
BEGIN
    DECLARE batch_limit INT DEFAULT 1000;
    DECLARE batches INT;
    DECLARE current_batch INT DEFAULT 0;
    DECLARE verified_user_count INT DEFAULT 0;

    -- 创建临时表存储已实名用户ID
    DROP TEMPORARY TABLE IF EXISTS tmp_verified_users;
    CREATE TEMPORARY TABLE tmp_verified_users (
        id BIGINT PRIMARY KEY,
        row_num INT
    );

    INSERT INTO tmp_verified_users (id, row_num)
    SELECT id, (@rn := @rn + 1) as row_num
    FROM users, (SELECT @rn := 0) init
    WHERE realname_status = 'verified'
    ORDER BY id;

    SELECT COUNT(*) INTO verified_user_count FROM tmp_verified_users;

    SET batches = CEIL(batch_size / batch_limit);

    WHILE current_batch < batches DO
        -- 批量生成游戏账号
        INSERT INTO game_accounts (
            owner_id, game_name, server_region, login_platform,
            title, description, rank_level, haf_coin_amount, status
        )
        SELECT
            u.id as owner_id,
            'delta_force',
            CASE (seq % 4)
                WHEN 0 THEN '亚服'
                WHEN 1 THEN '美服'
                WHEN 2 THEN '欧服'
                ELSE '国服'
            END,
            CASE (seq % 3)
                WHEN 0 THEN 'Steam'
                WHEN 1 THEN 'Epic'
                ELSE 'WeGame'
            END,
            CONCAT('账号', seq, ' 高分段'),
            CONCAT('这是一个测试账号，编号', seq),
            CASE (seq % 5)
                WHEN 0 THEN '青铜'
                WHEN 1 THEN '白银'
                WHEN 2 THEN '黄金'
                WHEN 3 THEN '铂金'
                ELSE '钻石'
            END,
            (seq % 100) * 10000,
            'published'
        FROM (
            SELECT @row2 := @row2 + 1 AS seq
            FROM
                (SELECT 0 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4
                 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) t1,
                (SELECT 0 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4
                 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) t2,
                (SELECT 0 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4
                 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) t3,
                (SELECT @row2 := current_batch * batch_limit) r
            LIMIT batch_limit
        ) seqs
        INNER JOIN tmp_verified_users u ON u.row_num = (seq % verified_user_count) + 1
        WHERE seq <= batch_size;

        -- 批量生成租号商品
        INSERT INTO rental_listings (
            listing_no, account_id, owner_id, price_cent, deposit_amount_cent,
            in_transaction, status, review_status, published_at
        )
        SELECT
            CONCAT(
                DATE_FORMAT(DATE_SUB(NOW(), INTERVAL (ga.id % 90) DAY), '%Y%m%d'),
                LPAD(FLOOR((ga.id - 1) / 90) + 1, 4, '0')
            ) as listing_no,
            ga.id as account_id,
            ga.owner_id,
            500 + ((ga.id % 20) * 50) as price_cent,
            10000 + ((ga.id % 10) * 5000) as deposit_amount_cent,
            CASE WHEN ga.id % 10 = 0 THEN 1 ELSE 0 END as in_transaction,
            CASE
                WHEN ga.id % 20 = 0 THEN 'offline'
                WHEN ga.id % 15 = 0 THEN 'draft'
                ELSE 'published'
            END as status,
            CASE
                WHEN ga.id % 15 = 0 THEN 'pending'
                WHEN ga.id % 30 = 0 THEN 'rejected'
                ELSE 'approved'
            END as review_status,
            DATE_SUB(NOW(), INTERVAL (ga.id % 90) DAY) as published_at
        FROM game_accounts ga
        WHERE ga.id > (SELECT COALESCE(MAX(account_id), 0) FROM rental_listings)
        LIMIT batch_limit;

        SET current_batch = current_batch + 1;
        COMMIT;
    END WHILE;

    INSERT INTO listing_no_sequences (biz_date, next_seq)
    SELECT LEFT(listing_no, 8), MAX(CAST(SUBSTRING(listing_no, 9) AS UNSIGNED))
    FROM rental_listings
    GROUP BY LEFT(listing_no, 8)
    ON DUPLICATE KEY UPDATE next_seq = GREATEST(next_seq, VALUES(next_seq));

    COMMIT;

    DROP TEMPORARY TABLE IF EXISTS tmp_verified_users;
END$$
DELIMITER ;

-- ============================================
-- 3. 批量生成订单数据（优化版）
-- ============================================
DROP PROCEDURE IF EXISTS generate_orders_batch;
DELIMITER $$
CREATE PROCEDURE generate_orders_batch(IN batch_size INT)
BEGIN
    DECLARE batch_limit INT DEFAULT 1000;
    DECLARE batches INT;
    DECLARE current_batch INT DEFAULT 0;
    DECLARE available_listing_count INT DEFAULT 0;
    DECLARE verified_user_count INT DEFAULT 0;

    -- 创建临时表：可用商品
    DROP TEMPORARY TABLE IF EXISTS tmp_available_listings;
    CREATE TEMPORARY TABLE tmp_available_listings (
        id BIGINT PRIMARY KEY,
        account_id BIGINT,
        owner_id BIGINT,
        price_cent BIGINT,
        deposit_amount_cent BIGINT,
        row_num INT
    );

    INSERT INTO tmp_available_listings (id, account_id, owner_id, price_cent, deposit_amount_cent, row_num)
    SELECT id, account_id, owner_id, price_cent, deposit_amount_cent, (@rn := @rn + 1)
    FROM rental_listings, (SELECT @rn := 0) init
    WHERE status IN ('published', 'active') AND review_status = 'approved'
    ORDER BY id;

    SELECT COUNT(*) INTO available_listing_count FROM tmp_available_listings;

    -- 创建临时表：已实名用户
    DROP TEMPORARY TABLE IF EXISTS tmp_verified_users;
    CREATE TEMPORARY TABLE tmp_verified_users (
        id BIGINT PRIMARY KEY,
        row_num INT
    );

    INSERT INTO tmp_verified_users (id, row_num)
    SELECT id, (@rn2 := @rn2 + 1)
    FROM users, (SELECT @rn2 := 0) init
    WHERE realname_status = 'verified'
    ORDER BY id;

    SELECT COUNT(*) INTO verified_user_count FROM tmp_verified_users;

    SET batches = CEIL(batch_size / batch_limit);

    WHILE current_batch < batches DO
        INSERT INTO rental_orders (
            order_no, listing_id, account_id, owner_id, renter_id,
            estimated_duration_hours, rent_amount_cent, owner_rent_amount_cent,
            deposit_amount_cent, deposit_original_amount_cent, platform_fee_cent, status, handoff_status,
            settlement_status, rented_at, created_at
        )
        SELECT
            CONCAT('ORD', DATE_FORMAT(NOW(), '%Y%m%d'), LPAD(seq, 8, '0')) as order_no,
            l.id as listing_id,
            l.account_id,
            l.owner_id,
            r.id as renter_id,
            24 as estimated_duration_hours,
            l.price_cent * 24 as rent_amount_cent,
            ROUND(l.price_cent * 24 * 0.95) as owner_rent_amount_cent,
            l.deposit_amount_cent,
            l.deposit_amount_cent,
            ROUND(l.price_cent * 24 * 0.05) as platform_fee_cent,
            CASE (seq % 10)
                WHEN 0 THEN 'pending_payment'
                WHEN 1 THEN 'cancelled'
                WHEN 2 THEN 'closed'
                ELSE 'completed'
            END as status,
            CASE (seq % 10)
                WHEN 0 THEN 'none'
                WHEN 1 THEN 'none'
                WHEN 2 THEN 'owner_delivered'
                ELSE 'owner_received'
            END as handoff_status,
            CASE (seq % 10)
                WHEN 0 THEN 'unsettled'
                WHEN 1 THEN 'unsettled'
                ELSE 'settled'
            END as settlement_status,
            DATE_SUB(NOW(), INTERVAL (seq % 60) DAY) as rented_at,
            DATE_SUB(NOW(), INTERVAL (seq % 60) DAY) as created_at
        FROM (
            SELECT @row3 := @row3 + 1 AS seq
            FROM
                (SELECT 0 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4
                 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) t1,
                (SELECT 0 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4
                 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) t2,
                (SELECT 0 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4
                 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) t3,
                (SELECT @row3 := current_batch * batch_limit) r
            LIMIT batch_limit
        ) seqs
        INNER JOIN tmp_available_listings l ON l.row_num = (seq % available_listing_count) + 1
        INNER JOIN tmp_verified_users r ON r.row_num = (seq % verified_user_count) + 1
        WHERE seq <= batch_size AND r.id != l.owner_id
        LIMIT batch_limit;

        SET current_batch = current_batch + 1;
        COMMIT;
    END WHILE;

    DROP TEMPORARY TABLE IF EXISTS tmp_available_listings;
    DROP TEMPORARY TABLE IF EXISTS tmp_verified_users;
END$$
DELIMITER ;

-- ============================================
-- 4. 批量生成钱包流水
-- ============================================
DROP PROCEDURE IF EXISTS generate_wallet_ledger_batch;
DELIMITER $$
CREATE PROCEDURE generate_wallet_ledger_batch(IN batch_size INT)
BEGIN
    DECLARE batch_limit INT DEFAULT 1000;
    DECLARE batches INT;
    DECLARE current_batch INT DEFAULT 0;
    DECLARE user_count INT DEFAULT 0;
    DECLARE order_count INT DEFAULT 0;

    -- 创建临时表：用户列表
    DROP TEMPORARY TABLE IF EXISTS tmp_users;
    CREATE TEMPORARY TABLE tmp_users (
        id BIGINT PRIMARY KEY,
        row_num INT
    );

    INSERT INTO tmp_users (id, row_num)
    SELECT id, (@rn := @rn + 1)
    FROM users, (SELECT @rn := 0) init
    ORDER BY id;

    SELECT COUNT(*) INTO user_count FROM tmp_users;

    -- 创建临时表：订单列表
    DROP TEMPORARY TABLE IF EXISTS tmp_orders;
    CREATE TEMPORARY TABLE tmp_orders (
        id BIGINT PRIMARY KEY,
        row_num INT
    );

    INSERT INTO tmp_orders (id, row_num)
    SELECT id, (@rn2 := @rn2 + 1)
    FROM rental_orders, (SELECT @rn2 := 0) init
    ORDER BY id;

    SELECT COUNT(*) INTO order_count FROM tmp_orders;

    SET batches = CEIL(batch_size / batch_limit);

    WHILE current_batch < batches DO
        INSERT INTO wallet_ledger (
            ledger_no, user_id, order_id, direction, amount_cent,
            balance_after_cent, balance_type, biz_type, biz_no, remark, created_at
        )
        SELECT
            CONCAT('LDG', DATE_FORMAT(NOW(), '%Y%m%d%H%i%s'), LPAD(seq, 6, '0')) as ledger_no,
            u.id as user_id,
            IF(seq % 2 = 0, o.id, NULL) as order_id,
            CASE WHEN seq % 2 = 0 THEN 'in' ELSE 'out' END as direction,
            ((seq % 500) * 100) + seq as amount_cent,
            100000 + ((seq % 1000) * 100) as balance_after_cent,
            CASE WHEN seq % 5 = 0 THEN 'frozen' ELSE 'available' END as balance_type,
            CASE (seq % 6)
                WHEN 0 THEN 'rent_payment'
                WHEN 1 THEN 'deposit_freeze'
                WHEN 2 THEN 'settlement'
                WHEN 3 THEN 'refund'
                WHEN 4 THEN 'recharge'
                ELSE 'withdraw'
            END as biz_type,
            CONCAT('BIZ', LPAD(seq, 10, '0')) as biz_no,
            CONCAT('测试流水', seq) as remark,
            DATE_SUB(NOW(), INTERVAL (seq % 180) DAY) as created_at
        FROM (
            SELECT @row4 := @row4 + 1 AS seq
            FROM
                (SELECT 0 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4
                 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) t1,
                (SELECT 0 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4
                 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) t2,
                (SELECT 0 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4
                 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) t3,
                (SELECT @row4 := current_batch * batch_limit) r
            LIMIT batch_limit
        ) seqs
        INNER JOIN tmp_users u ON u.row_num = (seq % user_count) + 1
        LEFT JOIN tmp_orders o ON o.row_num = (seq % order_count) + 1
        WHERE seq <= batch_size
        LIMIT batch_limit;

        SET current_batch = current_batch + 1;
        COMMIT;
    END WHILE;

    DROP TEMPORARY TABLE IF EXISTS tmp_users;
    DROP TEMPORARY TABLE IF EXISTS tmp_orders;
END$$
DELIMITER ;

-- ============================================
-- 5. 批量生成聊天会话和消息
-- ============================================
DROP PROCEDURE IF EXISTS generate_chat_data_batch;
DELIMITER $$
CREATE PROCEDURE generate_chat_data_batch(IN message_count INT)
BEGIN
    DECLARE batch_limit INT DEFAULT 1000;
    DECLARE batches INT;
    DECLARE current_batch INT DEFAULT 0;
    DECLARE conversation_count INT DEFAULT 0;
    DECLARE user_count INT DEFAULT 0;

    -- 先生成聊天会话（基于订单）
    INSERT INTO chat_conversations (order_id, type, title, status, last_message_at)
    SELECT
        ro.id,
        'order_group',
        CONCAT('订单', ro.order_no, '群聊'),
        'active',
        ro.created_at
    FROM rental_orders ro
    WHERE NOT EXISTS (SELECT 1 FROM chat_conversations WHERE order_id = ro.id)
    LIMIT 1000
    ON DUPLICATE KEY UPDATE order_id=order_id;

    DROP TEMPORARY TABLE IF EXISTS tmp_conversations;
    CREATE TEMPORARY TABLE tmp_conversations (
        id BIGINT PRIMARY KEY,
        row_num INT
    );

    INSERT INTO tmp_conversations (id, row_num)
    SELECT id, (@rn := @rn + 1)
    FROM chat_conversations, (SELECT @rn := 0) init
    ORDER BY id;

    SELECT COUNT(*) INTO conversation_count FROM tmp_conversations;

    DROP TEMPORARY TABLE IF EXISTS tmp_users;
    CREATE TEMPORARY TABLE tmp_users (
        id BIGINT PRIMARY KEY,
        row_num INT
    );

    INSERT INTO tmp_users (id, row_num)
    SELECT id, (@rn2 := @rn2 + 1)
    FROM users, (SELECT @rn2 := 0) init
    ORDER BY id;

    SELECT COUNT(*) INTO user_count FROM tmp_users;

    SET batches = CEIL(message_count / batch_limit);

    WHILE current_batch < batches DO
        INSERT INTO chat_messages (
            conversation_id, sender_type, sender_id, sender_role,
            content_type, content, created_at
        )
        SELECT
            c.id as conversation_id,
            'user' as sender_type,
            u.id as sender_id,
            CASE WHEN seq % 2 = 0 THEN 'owner' ELSE 'renter' END as sender_role,
            'text' as content_type,
            CONCAT('这是测试消息', seq, '，内容随机生成用于压力测试') as content,
            DATE_SUB(NOW(), INTERVAL (seq % 30) DAY) as created_at
        FROM (
            SELECT @row5 := @row5 + 1 AS seq
            FROM
                (SELECT 0 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4
                 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) t1,
                (SELECT 0 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4
                 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) t2,
                (SELECT 0 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4
                 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) t3,
                (SELECT @row5 := current_batch * batch_limit) r
            LIMIT batch_limit
        ) seqs
        INNER JOIN tmp_conversations c ON c.row_num = (seq % conversation_count) + 1
        INNER JOIN tmp_users u ON u.row_num = (seq % user_count) + 1
        WHERE seq <= message_count
        LIMIT batch_limit;

        SET current_batch = current_batch + 1;
        COMMIT;
    END WHILE;

    DROP TEMPORARY TABLE IF EXISTS tmp_conversations;
    DROP TEMPORARY TABLE IF EXISTS tmp_users;
END$$
DELIMITER ;

-- ============================================
-- 本文件只创建存储过程，不直接生成数据。
-- 请使用 scripts/stress_test.sh data 按参数生成
-- ============================================

SET FOREIGN_KEY_CHECKS = 1;
