import type { Provider } from '@supabase/supabase-js';

import { z } from 'zod';

import { createAuthProvidersService } from './auth-providers.service';

const providers: z.ZodType<Provider> = getProviders();

const DynamicAuthConfigSchema = z.object({
  providers: z.object({
    password: z.boolean().describe('Enable password authentication.'),
    magicLink: z.boolean().describe('Enable magic link authentication.'),
    oAuth: providers.array(),
  }),
  displayTermsCheckbox: z
    .boolean()
    .describe('Whether to display the terms checkbox during sign-up.'),
  isMailerAutoconfirmEnabled: z
    .boolean()
    .describe('Whether Supabase sends confirmation email automatically.'),
});

export type DynamicAuthConfig = {
  providers: {
    password: boolean;
    magicLink: boolean;
    oAuth: Provider[];
  };
  displayTermsCheckbox: boolean | undefined;
  isMailerAutoconfirmEnabled: boolean;
};

export async function getDynamicAuthConfig() {
  const authService = createAuthProvidersService();
  const dynamicProviders = await authService.getAuthConfig();

  const config = {
    providers: dynamicProviders.providers,
    displayTermsCheckbox: dynamicProviders.displayTermsCheckbox,
    isMailerAutoconfirmEnabled: dynamicProviders.isMailerAutoconfirmEnabled,
  };

  return DynamicAuthConfigSchema.parse(config);
}

export async function getCachedAuthConfig() {
  if (typeof window !== 'undefined') {
    const cached = sessionStorage.getItem('auth-config');
    if (cached) {
      try {
        const { data, timestamp } = JSON.parse(cached);
        // Cache for 5 minutes
        if (Date.now() - timestamp < 5 * 60 * 1000) {
          return data;
        }
      } catch (error) {
        console.warn('Invalid auth config cache:', error);
      }
    }
  }

  const config = await getDynamicAuthConfig();

  if (typeof window !== 'undefined') {
    try {
      sessionStorage.setItem(
        'auth-config',
        JSON.stringify({
          data: config,
          timestamp: Date.now(),
        }),
      );
    } catch (error) {
      console.warn('Failed to cache auth config:', error);
    }
  }

  return config;
}

export async function getServerAuthConfig() {
  return getDynamicAuthConfig();
}

export async function isProviderEnabled(
  provider: 'password' | 'magicLink' | Provider,
): Promise<boolean> {
  const authService = createAuthProvidersService();
  const settings = await authService.fetchAuthSettings();

  switch (provider) {
    case 'password':
      return authService.isPasswordEnabled({ settings });
    case 'magicLink':
      return authService.isMagicLinkEnabled();
    default:
      return authService.isOAuthProviderEnabled({ provider, settings });
  }
}

function getProviders() {
  return z.enum([
    'apple',
    'azure',
    'bitbucket',
    'discord',
    'facebook',
    'figma',
    'github',
    'gitlab',
    'google',
    'kakao',
    'keycloak',
    'linkedin',
    'linkedin_oidc',
    'notion',
    'slack',
    'spotify',
    'twitch',
    'twitter',
    'workos',
    'zoom',
    'fly',
  ]);
}
