import type { Database } from 'bun:sqlite';
import { ensureUserExists } from '../../../db';
import { isGroupId } from '../../../utils/whatsapp';
import { randomTokenBase64Url, sha256Hex } from '../../../utils/crypto';
import { Metrics } from '../../metrics';
import { toIsoSqlUTC } from '../../../utils/datetime';

type Ctx = {
  sender: string;
  groupId: string;
  message: string;
};

type Msg = {
  recipient: string;
  message: string;
  mentions?: string[];
};

export async function handleWeb(context: Ctx, deps: { db: Database }): Promise<Msg[]> {
  // Solo por DM
  if (isGroupId(context.groupId)) {
    return [{
      recipient: context.sender,
      message: 'ℹ️ Este comando se usa por privado. Envíame `t web` por DM.'
    }];
  }

  const base = (process.env.WEB_BASE_URL || '').trim();
  if (!base) {
    return [{
      recipient: context.sender,
      message: '⚠️ La web no está configurada todavía. Contacta con el administrador (falta WEB_BASE_URL).'
    }];
  }

  const ensured = ensureUserExists(context.sender, deps.db);
  if (!ensured) {
    throw new Error('No se pudo asegurar el usuario');
  }

  const now = new Date();
  const nowIso = toIsoSqlUTC(now);
  const expiresIso = toIsoSqlUTC(new Date(now.getTime() + 10 * 60 * 1000)); // 10 minutos

  // Invalidar tokens vigentes (uso único)
  deps.db.prepare(`
        UPDATE web_tokens
        SET used_at = ?
        WHERE user_id = ?
          AND used_at IS NULL
          AND expires_at > ?
      `).run(nowIso, ensured, nowIso);

  // Generar nuevo token y guardar solo el hash
  const token = randomTokenBase64Url(32);
  const tokenHash = await sha256Hex(token);

  deps.db.prepare(`
        INSERT INTO web_tokens (user_id, token_hash, expires_at, metadata)
        VALUES (?, ?, ?, NULL)
      `).run(ensured, tokenHash, expiresIso);

  try { Metrics.inc('web_tokens_issued_total'); } catch { }

  const url = new URL(`/login?token=${encodeURIComponent(token)}`, base).toString();
  return [{
    recipient: context.sender,
    message: `Acceso web: ${url}\nVálido durante 10 minutos. Si caduca, vuelve a enviar "t web".`
  }];
}
