import { Hono } from 'hono';
import PocketBase from 'pocketbase';

const app = new Hono();

// --- PocketBase singleton ---
const pb = new PocketBase(process.env.PB_URL || 'http://10.10.1.47:8080');

// --- User type ---
export type PBUser = {
  id: string;
  role: 'Admin' | 'Superuser' | string;
  display_name?: string;
  email?: string;
};

// --- Middleware: require Admin or Superuser ---
async function requireAdmin(c: any, next: () => Promise<void>) {
  const authHeader = c.req.header('authorization')?.replace('Bearer ', '');
  if (!authHeader) return c.text('Unauthorized', 401);

  pb.authStore.save(authHeader, null);

  const currentUser = pb.authStore.record as PBUser | null;
  if (!currentUser) return c.text('Unauthorized', 401);

  if (currentUser.role !== 'Admin' && currentUser.role !== 'Superuser') {
    return c.text('Forbidden', 403);
  }

  c.set('currentUser', currentUser);
  await next();
}

// --- Impersonation Endpoint ---
app.post('/api/impersonate', requireAdmin, async (c: any) => {
  const actor = c.get('currentUser') as PBUser;
  if (!actor) return c.text('Unauthorized', 401);

  const { targetUserIdentifier } = await c.req.json(); // can be ID or email

  let targetUser: PBUser | null = null;

  // Try fetching by ID first
  try {
    targetUser = await pb.collection('users').getOne(targetUserIdentifier) as PBUser;
  } catch {
    // If failed, try fetching by email
    const users = await pb.collection('users').getFullList({ sort: '-created' });
    const foundUser = users.find(u => u.email === targetUserIdentifier);

    if (foundUser) {
      targetUser = {
        id: foundUser.id,
        role: foundUser.role,
        display_name: foundUser.display_name,
        email: foundUser.email
      };
    } else {
      targetUser = null;
    }
  }

  if (!targetUser) return c.text('Target user not found', 404);

  // Prevent Admin → Admin impersonation
  if (actor.role === 'Admin' && targetUser.role === 'Admin') {
    return c.text('Admins cannot impersonate other admins', 403);
  }

  // Log impersonation
  await pb.collection('admin_audit_logs').create({
    admin_id: actor.id,
    admin_type: actor.role === 'Superuser' ? 'superuser' : 'user',
    target_user_id: targetUser.id,
    action: 'IMPERSONATE_USER',
    level: actor.role === 'Superuser' ? 'SUPERUSER' : 'ADMIN',
    created_at: new Date().toISOString(),
    target_display_name: targetUser.display_name || null,
    actor_display_name: actor.display_name || null,
  });

  // Issue impersonation token
  const tokenResponse = await pb.send('/api/collections/users/auth-refresh', { method: 'POST' });
  const json = await tokenResponse.json();

  return c.json({ token: json.token });
});

export default app;
export { pb };
