import type { MiddlewareHandler } from 'hono';

import { getDb, pgGet } from '@/shared/db';
import { logger } from '@/shared/logger';

// Matches "Bearer <token>" in Authorization header
const BEARER_RE = /^Bearer\s+(.+)$/i;

export function serviceTokenAuth(expected: string): MiddlewareHandler {
  return async (c, next) => {
    const header = c.req.header('authorization') ?? '';
    const match = BEARER_RE.exec(header);
    if (!match || match[1] !== expected) {
      return c.json({ error: 'unauthorized', code: 'bad_token' }, 401);
    }
    await next();
  };
}

export function deviceTokenAuth(operatorToken?: string): MiddlewareHandler {
  return async (c, next) => {
    try {
      const header = c.req.header('authorization') ?? '';
      const match = BEARER_RE.exec(header);
      if (!match) {
        return c.json({ error: 'unauthorized', code: 'missing_token' }, 401);
      }
      const token = match[1];
      if (operatorToken && token === operatorToken) {
        logger.info('operator token used', { path: c.req.path });
        c.set('deviceId', 'operator');
        c.set('deviceName', 'operator');
        await next();
        return;
      }
      const db = getDb();
      const row = await pgGet<{ id: string; name: string }>(
        db,
        'SELECT id, name FROM macsync.devices WHERE token = $1 AND revoked_at IS NULL',
        [token],
      );
      if (!row) {
        return c.json({ error: 'unauthorized', code: 'bad_token' }, 401);
      }
      c.set('deviceId', row.id);
      c.set('deviceName', row.name);
      await next();
    } catch (err) {
      throw new Error(
        `deviceTokenAuth failed: ${err instanceof Error ? err.message : String(err)}`,
        { cause: err },
      );
    }
  };
}

declare module 'hono' {
  interface ContextVariableMap {
    deviceId: string;
    deviceName: string;
  }
}
