<?php
declare(strict_types=1);

use app\cron\command\MqttServer;
use think\App;
use think\Db;
use think\console\Output;

$storeRoot = '/workspace/zhct/zhctproject/store';

define('APP_PATH', $storeRoot . '/application/');
require $storeRoot . '/env.php';
require $storeRoot . '/thinkphp/base.php';
App::initCommon();

$marker = 'CODEX_MQTT_HY093_' . date('YmdHis') . '_' . mt_rand(1000, 9999);
$now = date('Y-m-d H:i:s');
$payload = [
    'create_time' => '2026-06-16 10:31:23',
    'msgid' => '000261781577083183',
    'action' => 'consume',
    'order_type' => '1',
    'publish_topic' => 'zhct_jsr/zhct_jsr/p2p/GID_zhct_jsr@@@consume_work_0',
    'subscribe_topic' => 'zhct_jsr/zhct_jsr/p2p/GID_zhct_jsr@@@00026',
    'account' => 'admin',
    'key' => 'bdzj8f3as20g7t ycxwnkr59pvh6m1q4e',
    'pwd' => 'Nutr@Sys2026#Adm&74',
    'card_id' => '3455500610',
    'equipment_code' => '00026',
    'dishes' => [
        [
            'uuid' => 'custom_dish',
            'number' => '1',
            'money' => '3.00',
        ],
    ],
    'paycode' => '',
    'money' => '3.00',
    'staff_uuid' => '',
    '_mqtt_device_id' => 'dev2_consume_work_1',
    '_mqtt_sender_device_id' => '00026',
    '_mqtt_topic' => 'zhct_jsr/zhct_jsr/p2p/GID_zhct_jsr@@@consume_work_0',
];

$fixture = [
    'restaurant_id' => 0,
    'equipment_id' => 0,
    'strategy_id' => 0,
    'user_id' => 0,
    'staff_uuid' => '',
    'department_uuid' => '',
];

function codex_guid(): string
{
    if (function_exists('guid')) {
        return (string)guid();
    }
    return strtoupper(sprintf(
        '%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
        mt_rand(0, 0xffff),
        mt_rand(0, 0xffff),
        mt_rand(0, 0xffff),
        mt_rand(0, 0x0fff) | 0x4000,
        mt_rand(0, 0x3fff) | 0x8000,
        mt_rand(0, 0xffff),
        mt_rand(0, 0xffff),
        mt_rand(0, 0xffff)
    ));
}

function codex_insert_from_sample(string $table, array $changes, array $fallback): int
{
    $sample = Db::name($table)->limit(1)->find();
    $row = is_array($sample) && !empty($sample) ? $sample : $fallback;
    unset($row['id']);
    $row = array_merge($row, $changes);
    return (int)Db::name($table)->insertGetId($row);
}

function codex_delete_redis_keys(array $keys): void
{
    try {
        $redis = getRedis();
        if ($redis instanceof Redis) {
            foreach ($keys as $key) {
                $redis->del($key);
            }
        }
    } catch (Throwable $e) {
        echo 'REDIS_KEY_DELETE_WARNING=' . $e->getMessage() . PHP_EOL;
    }
}

echo 'env=' . TP_ENV . PHP_EOL;
echo 'business=' . BUSINESS . PHP_EOL;
echo 'database=' . config('database.database') . PHP_EOL;
echo 'marker=' . $marker . PHP_EOL;
echo 'payload=' . json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) . PHP_EOL;

try {
    $fixture['staff_uuid'] = codex_guid();
    $fixture['department_uuid'] = codex_guid();
    $identityId = 990002;

    $fixture['restaurant_id'] = codex_insert_from_sample('restaurants', [
        'uuid' => codex_guid(),
        'name' => $marker . '_堂食测试餐厅',
        'status' => 1,
        'is_delete' => 2,
        'stall_type' => 1,
        'is_order' => 1,
        'restaurant_shop_id' => 1,
        'create_by' => 'codex',
        'introduction' => $marker,
    ], [
        'uuid' => codex_guid(),
        'restaurant_shop_id' => 1,
        'status' => 1,
        'name' => $marker . '_堂食测试餐厅',
        'location' => '',
        'responsible' => '',
        'file_path' => '',
        'is_delete' => 2,
        'create_by' => 'codex',
        'introduction' => $marker,
        'is_order' => 1,
        'stall_type' => 1,
        'book_rules' => '',
        'order_rules' => '',
    ]);

    $fixture['equipment_id'] = codex_insert_from_sample('equipment', [
        'code' => $payload['equipment_code'],
        'name' => $marker . '_消费机00026',
        'restaurant_id' => $fixture['restaurant_id'],
        'status' => 1,
        'del_flag' => 0,
        'create_time' => $now,
        'create_by' => 'codex',
        'update_time' => $now,
        'update_by' => 'codex',
    ], [
        'code' => $payload['equipment_code'],
        'name' => $marker . '_消费机00026',
        'type' => 1,
        'restaurant_id' => $fixture['restaurant_id'],
        'status' => 1,
        'del_flag' => 0,
        'matecode' => '',
        'communicationkey' => '',
        'create_time' => $now,
        'create_by' => 'codex',
        'update_time' => $now,
        'update_by' => 'codex',
    ]);

    Db::name('api_auth')->insert([
        'account' => $payload['account'],
        'pwd' => $payload['pwd'],
        'key' => $payload['key'],
        'type' => 1,
        'restaurant_id' => $fixture['restaurant_id'],
        'equipment_id' => $fixture['equipment_id'],
        'start_time' => '2000-01-01 00:00:00',
        'end_time' => '2099-12-31 23:59:59',
        'status' => 1,
        'remark' => $marker,
        'create_by' => 'codex',
        'create_time' => $now,
        'update_time' => $now,
    ]);

    codex_insert_from_sample('staff', [
        'uuid' => $fixture['staff_uuid'],
        'name' => $marker . '_刷卡人员',
        'mobile' => '139' . mt_rand(10000000, 99999999),
        'account' => $marker,
        'identity_category_id' => $identityId,
        'restaurant_id' => $fixture['restaurant_id'],
        'is_show' => 1,
        'status' => 1,
        'create_time' => $now,
        'create_by' => 'codex',
        'personnel_umber' => substr($marker, -16),
    ], [
        'uuid' => $fixture['staff_uuid'],
        'station_uuid' => '',
        'name' => $marker . '_刷卡人员',
        'birthday' => '2000-01-01',
        'sport_uuid' => '',
        'sport_event_uuid' => '',
        'in_time' => '2000-01-01',
        'create_time' => $now,
        'create_by' => 'codex',
        'personnel_umber' => substr($marker, -16),
        'permanent_address' => '',
        'coach_name' => '',
        'sport_year' => '',
        'restaurant_id' => $fixture['restaurant_id'],
        'identity_category_id' => $identityId,
    ]);

    $fixture['user_id'] = codex_insert_from_sample('user', [
        'uuid' => codex_guid(),
        'account' => $marker,
        'name' => $marker . '_刷卡用户',
        'staff_uuid' => $fixture['staff_uuid'],
        'mobile' => '138' . mt_rand(10000000, 99999999),
        'balance' => '0.00',
        'ai_user_id' => 0,
        'is_delete' => 0,
        'create_time' => $now,
        'create_by' => 'codex',
    ], [
        'uuid' => codex_guid(),
        'account' => $marker,
        'pwd' => '',
        'salt' => '',
        'name' => $marker . '_刷卡用户',
        'create_time' => $now,
        'create_by' => 'codex',
        'staff_uuid' => $fixture['staff_uuid'],
        'balance' => '0.00',
        'is_delete' => 0,
        'ai_user_id' => 0,
    ]);

    Db::name('staff_card')->insert([
        'staff_uuid' => $fixture['staff_uuid'],
        'card_id' => $payload['card_id'],
        'card_status' => 1,
        'is_cancel' => 0,
        'cost' => '0.00',
        'store_id' => 10001,
        'create_by' => 'codex',
        'is_delete' => 0,
        'create_time' => $now,
        'update_time' => $now,
    ]);

    Db::name('staff_department')->insert([
        'department_uuid' => $fixture['department_uuid'],
        'staff_uuid' => $fixture['staff_uuid'],
        'is_charge' => 0,
        'create_time' => $now,
        'create_by' => 'codex',
    ]);

    $fixture['strategy_id'] = (int)Db::name('marketing_strategy')->insertGetId([
        'strategy_name' => $marker . '_首单堂食策略',
        'priority' => 1,
        'strategy_type' => 2,
        'strategy_value' => '1.00',
        'is_first_consume_only' => 1,
        'application_scene' => 0,
        'application_scenario' => 1,
        'time_range_mode' => 1,
        'status' => 1,
        'effective_type' => 1,
        'effective_start' => '2026-06-15',
        'effective_end' => '2026-06-17',
        'remark' => $marker,
        'store_id' => 10001,
        'create_by' => 'codex',
        'update_by' => 'codex',
        'is_delete' => 0,
        'create_time' => $now,
        'update_time' => $now,
    ]);

    Db::name('marketing_strategy_identity')->insert([
        'strategy_id' => $fixture['strategy_id'],
        'identity_id' => $identityId,
        'store_id' => 10001,
        'create_time' => $now,
    ]);
    Db::name('marketing_strategy_department')->insert([
        'strategy_id' => $fixture['strategy_id'],
        'department_uuid' => $fixture['department_uuid'],
        'store_id' => 10001,
        'create_time' => $now,
    ]);
    Db::name('marketing_strategy_restaurant')->insert([
        'strategy_id' => $fixture['strategy_id'],
        'restaurant_id' => $fixture['restaurant_id'],
        'store_id' => 10001,
        'create_time' => $now,
    ]);
    Db::name('marketing_strategy_scenario')->insert([
        'strategy_id' => $fixture['strategy_id'],
        'scenario' => 1,
        'store_id' => 10001,
        'create_time' => $now,
    ]);

    codex_delete_redis_keys([
        'consume_orderpay_' . $payload['msgid'],
        'consume_orderpay_staff_' . $fixture['staff_uuid'] . $payload['equipment_code'],
        'consume_orderpay_staff_' . $fixture['staff_uuid'] . $fixture['equipment_id'],
        'zhct:mqtt:consume:' . $payload['card_id'],
        'zhct:mqtt:consume:result:' . $payload['msgid'],
    ]);

    echo 'fixture_restaurant_id=' . $fixture['restaurant_id'] . PHP_EOL;
    echo 'fixture_equipment_id=' . $fixture['equipment_id'] . PHP_EOL;
    echo 'fixture_user_id=' . $fixture['user_id'] . PHP_EOL;
    echo 'fixture_staff_uuid=' . $fixture['staff_uuid'] . PHP_EOL;
    echo 'fixture_strategy_id=' . $fixture['strategy_id'] . PHP_EOL;
    echo 'calling=MqttServer::dispatch(action=consume)' . PHP_EOL;

    App::$trace_id = 'codex_' . substr(md5($marker), 0, 12);
    $server = new MqttServer();
    $method = new ReflectionMethod($server, 'dispatch');
    $method->setAccessible(true);
    $result = $method->invoke($server, $payload, new Output());

    echo 'UNEXPECTED_OK result=' . json_encode($result, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) . PHP_EOL;
    exit(1);
} catch (Throwable $e) {
    echo 'EXPECTED_EXCEPTION_CLASS=' . get_class($e) . PHP_EOL;
    echo 'EXPECTED_EXCEPTION_MESSAGE=' . $e->getMessage() . PHP_EOL;
    exit(strpos($e->getMessage(), 'mixed named and positional parameters') !== false ? 0 : 2);
}
