import { Request, Response, NextFunction } from 'express';
import { createClient } from '@supabase/supabase-js';
import { queryOne } from '../db';
import { logger } from '../logger';

export interface AuthUser {
  id: string;
  email: string;
  role: 'admin' | 'user';
  full_name: string | null;
  avatar_url: string | null;
}

declare global {
  // eslint-disable-next-line @typescript-eslint/no-namespace
  namespace Express {
    interface Request {
      authUser?: AuthUser;
    }
  }
}

function supabaseAdmin() {
  return createClient(
    process.env.SUPABASE_URL || 'http://ec-kong:8000',
    process.env.SUPABASE_SERVICE_ROLE_KEY || '',
    { auth: { autoRefreshToken: false, persistSession: false } }
  );
}

export function requireAuth(requiredRole?: 'admin') {
  return async (req: Request, res: Response, next: NextFunction) => {
    const auth = req.headers.authorization;
    if (!auth?.startsWith('Bearer ')) {
      return res.status(401).json({ error: 'Missing authorization header' });
    }
    const token = auth.slice(7);

    try {
      // Verify JWT via GoTrue — works for both anon and service_role tokens
      const { data: { user }, error } = await supabaseAdmin().auth.getUser(token);
      if (error || !user) {
        return res.status(401).json({ error: 'Invalid or expired token' });
      }

      const profile = await queryOne<AuthUser>(
        'SELECT id, email, role, full_name, avatar_url FROM profiles WHERE id = $1',
        [user.id]
      );

      if (!profile) {
        // Auto-create profile if somehow missing (e.g. seeding lag)
        await queryOne(
          "INSERT INTO profiles (id, email, role) VALUES ($1,$2,'user') ON CONFLICT (id) DO NOTHING RETURNING *",
          [user.id, user.email]
        );
        req.authUser = {
          id: user.id,
          email: user.email ?? '',
          role: 'user',
          full_name: null,
          avatar_url: null,
        };
      } else {
        req.authUser = profile;
      }

      if (requiredRole && req.authUser.role !== requiredRole) {
        return res.status(403).json({ error: 'Admin access required' });
      }

      next();
    } catch (err) {
      logger.error(err, '[auth middleware]');
      return res.status(401).json({ error: 'Authentication failed' });
    }
  };
}
