#!/usr/bin/env node
/**
 * One-off billing compensation for duplicate charges / rate overcharge.
 *
 * Usage:
 *   node scripts/compensate-user-billing.mjs wx_mk4zzaps
 *   node scripts/compensate-user-billing.mjs wx_mk4zzaps --apply
 *   node scripts/compensate-user-billing.mjs wx_mk4zzaps --apply --include-rate-adjustment
 */
import crypto from 'node:crypto';
import fs from 'node:fs';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
import mysql from 'mysql2/promise';

const root = path.join(path.dirname(fileURLToPath(import.meta.url)), '..');

function loadEnvFile(filePath) {
  if (!fs.existsSync(filePath)) return;
  for (const line of fs.readFileSync(filePath, 'utf8').split('\n')) {
    const trimmed = line.trim();
    if (!trimmed || trimmed.startsWith('#')) continue;
    const eq = trimmed.indexOf('=');
    if (eq < 0) continue;
    const key = trimmed.slice(0, eq).trim();
    const value = trimmed.slice(eq + 1).trim();
    if (!process.env[key]) process.env[key] = value;
  }
}

loadEnvFile(path.join(root, '.env'));

const username = process.argv[2];
const apply = process.argv.includes('--apply');
const includeRateAdjustment = process.argv.includes('--include-rate-adjustment');

if (!username) {
  console.error('Usage: node scripts/compensate-user-billing.mjs <username> [--apply] [--include-rate-adjustment]');
  process.exit(1);
}

if (!process.env.DATABASE_URL) {
  console.error('DATABASE_URL is not configured');
  process.exit(1);
}

/** wx_mk4zzaps duplicate Finish billing (2026-06-16 session 20260616_600). */
const DUPLICATE_COST_CENTS = 1735;
const DUPLICATE_TOKENS = 838567;
/** Unique bills at 2/6 分/1k vs documented DeepSeek ×1 default (0.101/0.202 分/1k). */
const RATE_OVERCHARGE_CENTS = 1467;

async function main() {
  const pool = mysql.createPool(process.env.DATABASE_URL);
  try {
    const [users] = await pool.query(
      `SELECT u.id, u.username, u.display_name, u.status,
              COALESCE(w.balance_cents, 0) AS balance_cents,
              COALESCE(w.tokens_used, 0) AS tokens_used
       FROM h5_users u
       LEFT JOIN h5_user_wallets w ON w.user_id = u.id
       WHERE u.username = ?
       LIMIT 1`,
      [username],
    );
    const user = users[0];
    if (!user) {
      console.error(`User not found: ${username}`);
      process.exit(1);
    }

    const amountCents = DUPLICATE_COST_CENTS + (includeRateAdjustment ? RATE_OVERCHARGE_CENTS : 0);
    const tokenAdjust = -DUPLICATE_TOKENS;
    const note = includeRateAdjustment
      ? `补偿：重复扣费 ¥${(DUPLICATE_COST_CENTS / 100).toFixed(2)} + 费率差额 ¥${(RATE_OVERCHARGE_CENTS / 100).toFixed(2)}`
      : `补偿：重复扣费 ¥${(DUPLICATE_COST_CENTS / 100).toFixed(2)}（session 20260616_600）`;

    console.log('User:', user.username, user.display_name ?? '', `(${user.id})`);
    console.log('Current status:', user.status);
    console.log('Current balance:', `¥${(Number(user.balance_cents) / 100).toFixed(2)}`);
    console.log('Current tokens_used:', Number(user.tokens_used).toLocaleString());
    console.log('');
    console.log('Compensation plan:');
    console.log('  balance +', `¥${(amountCents / 100).toFixed(2)}`, `(${amountCents} cents)`);
    if (tokenAdjust !== 0) {
      console.log('  tokens_used', tokenAdjust.toLocaleString(), '(remove duplicate token count)');
    }
    console.log('  note:', note);
    console.log('  reactivate account if suspended:', user.status === 'suspended' ? 'yes' : 'no');

    if (!apply) {
      console.log('');
      console.log('Dry run only. Re-run with --apply to execute.');
      return;
    }

    const now = Date.now();
    const conn = await pool.getConnection();
    try {
      await conn.beginTransaction();
      await conn.query(
        `INSERT INTO h5_user_wallets (user_id, balance_cents, tokens_used, updated_at)
         VALUES (?, ?, 0, ?)
         ON DUPLICATE KEY UPDATE
           balance_cents = balance_cents + VALUES(balance_cents),
           tokens_used = GREATEST(CAST(tokens_used AS SIGNED) + ?, 0),
           updated_at = VALUES(updated_at)`,
        [user.id, amountCents, now, tokenAdjust],
      );
      await conn.query(
        `INSERT INTO h5_billing_ledger
         (user_id, type, amount_cents, tokens, note, operator_id, created_at)
         VALUES (?, 'adjust', ?, ?, ?, NULL, ?)`,
        [user.id, amountCents, tokenAdjust, note, now],
      );
      if (user.status === 'suspended') {
        await conn.query(`UPDATE h5_users SET status = 'active', updated_at = ? WHERE id = ?`, [
          now,
          user.id,
        ]);
      }
      await conn.commit();
    } catch (err) {
      await conn.rollback();
      throw err;
    } finally {
      conn.release();
    }

    const [updatedRows] = await pool.query(
      `SELECT u.status, COALESCE(w.balance_cents, 0) AS balance_cents,
              COALESCE(w.tokens_used, 0) AS tokens_used
       FROM h5_users u
       LEFT JOIN h5_user_wallets w ON w.user_id = u.id
       WHERE u.id = ?
       LIMIT 1`,
      [user.id],
    );
    const updated = updatedRows[0];
    console.log('');
    console.log('Applied.');
    console.log('New status:', updated.status);
    console.log('New balance:', `¥${(Number(updated.balance_cents) / 100).toFixed(2)}`);
    console.log('New tokens_used:', Number(updated.tokens_used).toLocaleString());
  } finally {
    await pool.end();
  }
}

main().catch((err) => {
  console.error(err);
  process.exit(1);
});
