import { Context, Next } from 'hono';
import { jwtVerify } from 'jose';
import { getStaffUserById, isUserSuspended } from '@/src/dbService';
import { ApiError } from '@/src/lib/api-error';
import { getEncodedJwtSecret } from '@/src/lib/env-exporter';

interface UserContext {
  userId: number;
  name?: string;
  email?: string;
  mobile?: string;
}

interface StaffContext {
  id: number;
  name: string;
}

export const authenticateUser = async (c: Context, next: Next) => {
  try {
    const authHeader = c.req.header('authorization');

    if (!authHeader?.startsWith('Bearer ')) {
      throw new ApiError('Authorization token required', 401);
    }

    const token = authHeader.substring(7);
    console.log(c.req.header)

    const { payload } = await jwtVerify(token, getEncodedJwtSecret());
    const decoded = payload as any;

    // Check if this is a staff token (has staffId)
    if (decoded.staffId) {
      /*
      // Old implementation - direct DB queries:
      import { db } from '@/src/db/db_index'
      import { staffUsers } from '@/src/db/schema'
      import { eq } from 'drizzle-orm';

      const staff = await db.query.staffUsers.findFirst({
        where: eq(staffUsers.id, decoded.staffId),
      });
      */

      // This is a staff token, verify staff exists
      const staff = await getStaffUserById(decoded.staffId);

      if (!staff) {
        throw new ApiError('Invalid staff token', 401);
      }

      c.set('staffUser', {
        id: staff.id,
        name: staff.name,
      });
    } else {
      // This is a regular user token
      c.set('user', decoded);

      /*
      // Old implementation - direct DB queries:
      import { db } from '@/src/db/db_index'
      import { userDetails } from '@/src/db/schema'
      import { eq } from 'drizzle-orm';

      const details = await db.query.userDetails.findFirst({
        where: eq(userDetails.userId, decoded.userId),
      });

      if (details?.isSuspended) {
        throw new ApiError('Account suspended', 403);
      }
      */

      // Check if user is suspended
      const suspended = await isUserSuspended(decoded.userId);

      if (suspended) {
        throw new ApiError('Account suspended', 403);
      }
    }

    await next();
  } catch (error) {
    throw error;
  }
};
