import { createMiddleware } from 'hono/factory';
import { jwtVerify, type JWTVerifyResult } from 'jose';
import type { AuthContext, JWTPayload } from '../types/index';

const JWT_SECRET = new TextEncoder().encode(
  process.env.JWT_SECRET || 'dev-secret-change-in-production-please'
);

// Extend Hono's context with our auth data
declare module 'hono' {
  interface ContextVariableMap {
    auth: AuthContext;
  }
}

/**
 * JWT Authentication Middleware
 * 
 * In dev mode (DEV_MODE=true), allows unauthenticated requests
 * with a default admin context for easier local development.
 */
export const authMiddleware = createMiddleware(async (c, next) => {
  // Dev mode bypass — always authenticated as admin
  if (process.env.DEV_MODE === 'true') {
    c.set('auth', {
      userId: '00000000-0000-0000-0000-000000000000',
      role: 'owner',
      scopes: ['*'],
    });
    return next();
  }

  const authHeader = c.req.header('Authorization');

  // Check for API key auth
  const apiKey = c.req.header('X-API-Key');
  if (apiKey) {
    // TODO: Validate API key against database
    // For now, accept any key in dev
    c.set('auth', {
      userId: 'api-key-user',
      role: 'agent',
      scopes: ['pipelines:read', 'tasks:read', 'tasks:approve'],
    });
    return next();
  }

  if (!authHeader || !authHeader.startsWith('Bearer ')) {
    return c.json(
      {
        success: false,
        error: {
          code: 'UNAUTHORIZED',
          message: 'Missing or invalid Authorization header',
        },
      },
      401
    );
  }

  const token = authHeader.slice(7);

  try {
    const result: JWTVerifyResult = await jwtVerify(token, JWT_SECRET);
    const payload = result.payload as unknown as JWTPayload;

    c.set('auth', {
      userId: payload.sub,
      role: payload.role,
      scopes: payload.scopes || [],
    });

    return next();
  } catch (err) {
    return c.json(
      {
        success: false,
        error: {
          code: 'UNAUTHORIZED',
          message: 'Invalid or expired token',
        },
      },
      401
    );
  }
});

/**
 * Optional auth — sets auth context if token present, continues regardless
 */
export const optionalAuth = createMiddleware(async (c, next) => {
  const authHeader = c.req.header('Authorization');

  if (authHeader?.startsWith('Bearer ')) {
    try {
      const token = authHeader.slice(7);
      const result = await jwtVerify(token, JWT_SECRET);
      const payload = result.payload as unknown as JWTPayload;
      c.set('auth', {
        userId: payload.sub,
        role: payload.role,
        scopes: payload.scopes || [],
      });
    } catch {
      // Token invalid, continue without auth
    }
  }

  // Default dev auth
  if (!c.get('auth') && process.env.DEV_MODE === 'true') {
    c.set('auth', {
      userId: '00000000-0000-0000-0000-000000000000',
      role: 'owner',
      scopes: ['*'],
    });
  }

  return next();
});
