<?php
declare(strict_types=1);

const AI_ROOT = '/workspace/zhct/zhctproject/ai_api';
const STORE_ROOT = '/workspace/zhct/zhctproject/store';
const APPKEY = '1234567890abcdef';

function failManual(string $message): void
{
    fwrite(STDERR, '[FAIL] ' . $message . PHP_EOL);
    exit(1);
}

function parseIniEnvManual(string $path): array
{
    $data = parse_ini_file($path, true, INI_SCANNER_RAW);
    if (!is_array($data)) {
        failManual('无法读取环境配置：' . $path);
    }
    return $data;
}

function pdoManual(array $section): PDO
{
    $dsn = sprintf(
        'mysql:host=%s;port=%s;dbname=%s;charset=%s',
        $section['HOSTNAME'],
        $section['HOSTPORT'] ?? '3306',
        $section['DATABASE'],
        $section['CHARSET'] ?? 'utf8'
    );
    return new PDO($dsn, $section['USERNAME'], $section['PASSWORD'], [
        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
        PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
    ]);
}

function oneManual(PDO $pdo, string $sql, array $params = []): array
{
    $stmt = $pdo->prepare($sql);
    $stmt->execute($params);
    $row = $stmt->fetch();
    return $row ?: [];
}

function runManual(PDO $pdo, string $sql, array $params = []): void
{
    $stmt = $pdo->prepare($sql);
    $stmt->execute($params);
}

function applyPrepayMigrationManual(PDO $zhct): void
{
    $exists = oneManual($zhct, "SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'ydy_prepay_order'");
    if ($exists) {
        return;
    }
    $sql = file_get_contents(STORE_ROOT . '/db/v2/v2.0.35.sql');
    if ($sql === false) {
        failManual('无法读取预扣款建表 SQL');
    }
    $lines = array_filter(explode("\n", $sql), static function (string $line): bool {
        return strpos(ltrim($line), '--') !== 0;
    });
    foreach (array_filter(array_map('trim', explode(';', implode("\n", $lines)))) as $statement) {
        if ($statement !== '') {
            $zhct->exec($statement);
        }
    }
}

function upsertConfigManual(PDO $zhct, string $key, string $value, string $desc): void
{
    $row = oneManual($zhct, "SELECT id FROM ydy_config WHERE config_key = :key AND restaurant_id = 1 LIMIT 1", [':key' => $key]);
    if ($row) {
        runManual($zhct, "UPDATE ydy_config SET config_value = :value, config_desc = :desc, status = 1, update_by = 'codex_gui' WHERE id = :id", [
            ':value' => $value,
            ':desc' => $desc,
            ':id' => $row['id'],
        ]);
        return;
    }
    runManual($zhct, "INSERT INTO ydy_config(config_key, config_value, config_desc, create_by, status, create_time, update_time, restaurant_id, is_show, update_by)
        VALUES(:key, :value, :desc, 'codex_gui', 1, NOW(), NOW(), 1, 0, 'codex_gui')", [
        ':key' => $key,
        ':value' => $value,
        ':desc' => $desc,
    ]);
}

function signManual(string $timestamp, string $randstr): string
{
    $values = [APPKEY, $timestamp, $randstr];
    sort($values, SORT_STRING);
    return sha1(implode('', $values));
}

function seedTokenManual(int $aiUserId, string $prefix): string
{
    chdir(AI_ROOT);
    require AI_ROOT . '/env.php';
    require AI_ROOT . '/vendor/autoload.php';
    $app = (new think\App())->setEnvName(TP_ENV);
    $app->initialize();
    $token = $prefix . 'TOKEN_' . $aiUserId;
    think\facade\Cache::set($token, [
        'user' => ['user_id' => $aiUserId],
        'password_version' => 0,
        'login_type' => 'account',
    ], 7200);
    return $token;
}

$prefix = 'CQHW_GUI_' . date('Ymd_His') . '_';
$shortSuffix = date('His');
$env = parseIniEnvManual(AI_ROOT . '/.env.local');
$ai = pdoManual($env['DATABASE']);
$zhct = pdoManual($env['DATABASE_ZHCT']);

applyPrepayMigrationManual($zhct);
upsertConfigManual($zhct, 'coffee_machine_appkey', APPKEY, '咖啡机第三方支付接口默认appkey');

$now = time();
$mobile = '138' . substr((string)$now, -8);
$nick = $prefix . 'USER';
runManual($ai, "INSERT INTO yoshop_user(mobile, nick_name, balance, platform, business, channel, is_delete, store_id, create_time, update_time)
    VALUES(:mobile, :nick_name, 100.00, 'MP-WEIXIN', 'zhct', '10000', 0, 10001, :now, :now)", [
    ':mobile' => $mobile,
    ':nick_name' => $nick,
    ':now' => $now,
]);
$aiUserId = (int)$ai->lastInsertId();
runManual($ai, "INSERT INTO yoshop_user_oauth(user_id, oauth_type, oauth_id, unionid, store_id, is_delete, create_time, update_time)
    VALUES(:user_id, 'MP-WEIXIN', :oauth_id, '', 10001, 0, :now, :now)", [
    ':user_id' => $aiUserId,
    ':oauth_id' => $prefix . 'OPENID',
    ':now' => $now,
]);

runManual($zhct, "INSERT INTO ydy_user(uuid, department_uuid, station_uuid, account, pwd, salt, name, sex, mobile, email, type, status, user_type, demo, create_time, create_by, staff_uuid, login_check, third_type, openid, nickname, is_wx, balance, pay_money, member_type, is_delete, source, ai_mobile, ai_user_id, password_status, password_version)
    VALUES(UUID(), '', '', :account, 'codex_gui_pwd', 'codexgui', :name, 1, :mobile, '', 1, 1, 1, 'codex gui test', NOW(), 'codex_gui', '', 0, 2, :openid, :nickname, 1, 0.00, 0.00, 1, 0, 1, :mobile, :ai_user_id, 2, 0)", [
    ':account' => $prefix . 'ACCOUNT',
    ':name' => $nick,
    ':mobile' => $mobile,
    ':openid' => $prefix . 'OPENID',
    ':nickname' => $nick,
    ':ai_user_id' => $aiUserId,
]);
$zhctUserId = (int)$zhct->lastInsertId();

$machid = 'CQHW_GUI_MACH_' . $shortSuffix;
runManual($zhct, "INSERT INTO ydy_equipment(code, name, type, sn, restaurant_id, status, matecode, communicationkey, del_flag, mate_flag, hearttime, face_time, create_time, create_by, update_time, update_by)
    VALUES(:code, :name, 60, :sn, 1, 1, '', '', 0, 1, 0, '2001-01-01 00:00:00', NOW(), 'codex_gui', NOW(), 'codex_gui')", [
    ':code' => 'CQHW_GUI_COFFEE_' . $shortSuffix,
    ':name' => $prefix . '咖啡机',
    ':sn' => $machid,
]);
$equipmentId = (int)$zhct->lastInsertId();

$timestamp = (string)time();
$randstr = $prefix . 'RAND_A';
$orderId = $prefix . 'ORDER_10001';
$body = [
    'orderid' => $orderId,
    'machid' => $machid,
    'trackno' => 'GUI-LATTE-01',
    'name' => $prefix . '拿铁',
    'price' => '1200',
    'channelid' => 'BALANCE',
    'timestamp' => $timestamp,
    'randstr' => $randstr,
    'sign' => signManual($timestamp, $randstr),
];

$token = seedTokenManual($aiUserId, $prefix);
$result = [
    'prefix' => $prefix,
    'api_base' => 'http://127.0.0.1',
    'interface_a_path' => '/api/prepayOrder/code',
    'mini_scan_path' => '/aizhct/api/PrepayOrder/scan',
    'headers_for_miniapp_scan' => [
        'Access-Token' => $token,
        'storeId' => '10001',
        'platform' => 'MP-WEIXIN',
    ],
    'body_for_apifox_interface_a' => $body,
    'seed' => [
        'ai_user_id' => $aiUserId,
        'zhct_user_id' => $zhctUserId,
        'equipment_id' => $equipmentId,
        'machid' => $machid,
        'mobile' => $mobile,
    ],
];

$out = '/tmp/cqhw_gui_fixture_' . date('Ymd_His') . '.json';
file_put_contents($out, json_encode($result, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT));
echo json_encode($result + ['fixture_file' => $out], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT) . PHP_EOL;
