import { NextAuthOptions } from 'next-auth';
import CredentialsProvider from 'next-auth/providers/credentials';
import KeycloakProvider from 'next-auth/providers/keycloak';

/** Prefer NEXTAUTH_URL (public origin behind NPM) so redirects match the browser host. */
function canonicalAuthBaseUrl(fallback: string): string {
  const raw = process.env.NEXTAUTH_URL?.trim();
  if (!raw) return fallback.replace(/\/$/, '');
  try {
    return new URL(raw).origin;
  } catch {
    return fallback.replace(/\/$/, '');
  }
}

function isPrivateOrLocalHost(hostname: string): boolean {
  if (hostname === 'localhost' || hostname === '127.0.0.1') return true;
  if (hostname.startsWith('192.168.')) return true;
  if (hostname.startsWith('10.')) return true;
  return /^172\.(1[6-9]|2\d|3[0-1])\./.test(hostname);
}

// Check if Keycloak is configured
const isKeycloakConfigured = 
  process.env.KEYCLOAK_URL && 
  process.env.KEYCLOAK_CLIENT_ID && 
  process.env.KEYCLOAK_CLIENT_SECRET;

const providers = [];

// Add Keycloak provider if configured
if (isKeycloakConfigured) {
  providers.push(
    KeycloakProvider({
      clientId: process.env.KEYCLOAK_CLIENT_ID!,
      clientSecret: process.env.KEYCLOAK_CLIENT_SECRET!,
      issuer: `${process.env.KEYCLOAK_URL}/realms/${process.env.KEYCLOAK_REALM || 'master'}`,
    })
  );
} else {
  // Development mode: Use credentials provider
  providers.push(
    CredentialsProvider({
      name: 'Credentials',
      credentials: {
        email: { label: 'Email', type: 'email', placeholder: 'dev@example.com' },
        password: { label: 'Password', type: 'password' },
      },
      async authorize(credentials) {
        // In development, accept any credentials
        if (process.env.NODE_ENV === 'development') {
          return {
            id: 'dev-user',
            email: credentials?.email || 'dev@example.com',
            name: 'Development User',
            role: 'ADMIN',
          };
        }
        return null;
      },
    })
  );
}

export const authOptions: NextAuthOptions = {
  providers,
  callbacks: {
    async redirect({ url, baseUrl }) {
      const canonical = canonicalAuthBaseUrl(baseUrl);
      if (url.startsWith('/')) return `${canonical}${url}`;
      try {
        const target = new URL(url);
        if (target.origin === canonical) return url;
        if (isPrivateOrLocalHost(target.hostname)) {
          return `${canonical}${target.pathname}${target.search}${target.hash}`;
        }
        return canonical;
      } catch {
        return canonical;
      }
    },
    async jwt({ token, account, profile, user }) {
      if (account) {
        token.accessToken = account.access_token;
        token.refreshToken = account.refresh_token;
        token.idToken = account.id_token;
      }
      
      // For credentials provider, add user info
      if (user) {
        token.id = user.id;
        token.email = user.email;
        token.name = user.name;
      }
      
      // Extract roles from Keycloak token
      if (profile && 'realm_access' in profile) {
        const realmAccess = profile.realm_access as { roles?: string[] };
        token.roles = realmAccess.roles || [];
      }
      
      return token;
    },
    async session({ session, token }) {
      if (token) {
        session.accessToken = token.accessToken as string;
        session.roles = token.roles as string[];
        if (token.id) {
          session.user = {
            ...session.user,
            id: token.id as string,
            email: token.email as string,
            name: token.name as string,
          };
        }
      }
      return session;
    },
  },
  // Do not set pages.signIn to /api/auth/signin — that is the API handler and causes ERR_TOO_MANY_REDIRECTS.
  pages: {
    error: '/api/auth/error',
  },
  session: {
    strategy: 'jwt',
    maxAge: 24 * 60 * 60, // 24 hours
  },
};
