/**
 * Auth Routes - Login, logout, token refresh
 */

import { Hono } from 'hono';
import { tokenService } from '../services/tokenService';
import { authMiddleware, getUserId } from '../middleware/auth';
import { BadRequestError } from '../middleware/errorHandler';
import type { LoginCallbackRequest, TokenType } from '@shared/types/auth';
import { HTTP_STATUS } from '../config/constants';

const auth = new Hono();

/**
 * POST /api/auth/login-callback
 * Called after OAuth flow to store tokens in cache
 */
auth.post('/login-callback', async (c) => {
  const body = await c.req.json<LoginCallbackRequest>();

  if (!body.pbToken || !body.graphToken || !body.user) {
    throw new BadRequestError('Missing required token data');
  }

  // Store tokens in cache
  await tokenService.storeTokens(
    body.user.id,
    body.pbToken,
    body.graphToken,
    body.refreshTokenPb ?? '',
    body.refreshTokenGraph ?? ''
  );

  // Start background refresh loop
  tokenService.startRefreshLoop(body.user.id);

  const expiresAt = Date.now() + 3600 * 1000; // 1 hour

  return c.json({
    success: true,
    user: body.user,
    expiresAt_pb: expiresAt,
    expiresAt_graph: expiresAt,
  });
});

/**
 * POST /api/auth/logout
 * Clear tokens and stop refresh loop
 */
auth.post('/logout', authMiddleware, async (c) => {
  const userId = getUserId(c);

  await tokenService.clearUserTokens(userId);

  return c.json({ success: true });
});

/**
 * GET /api/refresh-token
 * Get fresh token from cache or refresh
 */
auth.get('/refresh-token', authMiddleware, async (c) => {
  const userId = getUserId(c);
  const type = c.req.query('type') as TokenType | undefined;

  if (!type || !['pb', 'graph'].includes(type)) {
    throw new BadRequestError('Invalid token type. Must be "pb" or "graph"');
  }

  const result = await tokenService.getToken(userId, type);

  if (!result) {
    return c.json(
      { error: 'Token not available' },
      HTTP_STATUS.UNAUTHORIZED
    );
  }

  return c.json(result);
});

/**
 * POST /api/refresh-token
 * Alternative POST endpoint for token refresh
 */
auth.post('/refresh-token', authMiddleware, async (c) => {
  const userId = getUserId(c);
  const body = await c.req.json<{ type: TokenType }>();

  if (!body.type || !['pb', 'graph'].includes(body.type)) {
    throw new BadRequestError('Invalid token type. Must be "pb" or "graph"');
  }

  const result = await tokenService.getToken(userId, body.type);

  if (!result) {
    return c.json(
      { error: 'Token not available' },
      HTTP_STATUS.UNAUTHORIZED
    );
  }

  return c.json(result);
});

export default auth;
