import { auth } from '@/lib/auth';
import { fetchGeoInfo } from '@/lib/geoip';
import { db } from '@/lib/prisma';
import type { AppEnv } from '@/types/hono';
import { createMiddleware } from 'hono/factory';

type SessionWithGeo = {
  id: string;
  ipAddress: string | null;
  userAgent: string | null;
  country: string | null;
  city: string | null;
  countryCode: string | null;
  latitude: number | null;
  longitude: number | null;
};

export const requireAuth = createMiddleware<AppEnv>(async (c, next) => {
  const session = await auth.api.getSession({
    headers: c.req.raw.headers,
  });

  if (!session) {
    return c.json({ message: 'Unauthorized' }, 401);
  }

  const user = session.user as { banned?: boolean; banReason?: string | null };

  if (user.banned) {
    return c.json(
      {
        message: 'Tu cuenta ha sido bloqueada.',
        ...(user.banReason ? { reason: user.banReason } : {}),
      },
      403
    );
  }

  const s = session.session as unknown as SessionWithGeo;

  c.set('user', session.user);
  c.set('session', session.session);

  if (s.ipAddress && !s.country) {
    resolveSessionGeo(s.id, s.ipAddress);
  }

  await next();
});

async function resolveSessionGeo(sessionId: string, ipAddress: string) {
  try {
    const geo = await fetchGeoInfo(ipAddress);
    if (!geo) return;
    await db.session.update({
      where: { id: sessionId },
      data: {
        country: geo.country,
        city: geo.city,
        countryCode: geo.countryCode,
        latitude: geo.lat,
        longitude: geo.lon,
      },
    });
  } catch {
    // Silently fail — geo enrichment is best-effort
  }
}
