import { createServerClient } from "@supabase/ssr";
import { createClient as createSupabaseClient, SupabaseClient } from "@supabase/supabase-js";
import { cookies } from "next/headers";

/**
 * Cookie-based server client WITH user context.
 * Use this in Server Components, Server Actions, and Route Handlers
 * where you need to know who the logged-in user is.
 * 
 * @returns Promise resolving to Supabase client with server-side cookie handling
 * 
 * @example
 * const supabase = await createClient();
 * const { data: { user } } = await supabase.auth.getUser();
 */
export async function createClient() {
  const cookieStore = await cookies();

  return createServerClient(
    process.env.NEXT_PUBLIC_SUPABASE_URL!,
    process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
    {
      cookies: {
        getAll() {
          return cookieStore.getAll().map(cookie => {
            // Fix for malformed JWT strings causing "Cannot create property 'user' on string"
            if (cookie.name.includes("-auth-token") && cookie.value) {
              let rawValue = cookie.value.trim();
              if (rawValue.startsWith('"%22') || rawValue.startsWith('%22')) {
                rawValue = decodeURIComponent(rawValue);
              }
              if (rawValue.startsWith('"') && rawValue.endsWith('"')) {
                rawValue = rawValue.slice(1, -1);
              }
              if (rawValue.startsWith("eyJ")) {
                return {
                  ...cookie,
                  value: JSON.stringify({
                    access_token: rawValue,
                    refresh_token: "", // Mock refresh token to prevent crash
                    user: {} // Mock user object so property assignment doesn't throw
                  })
                };
              }
            }
            return cookie;
          });
        },
        setAll(cookiesToSet) {
          try {
            cookiesToSet.forEach(({ name, value, options }) =>
              cookieStore.set(name, value, options)
            );
          } catch {
            // Cookies can only be set in Server Actions or Route Handlers
          }
        },
      },
    }
  );
}

// Lazy-initialized admin client to avoid build-time errors (H11 fix)
let _supabaseAdmin: SupabaseClient | null = null;

/**
 * Admin client with service key — bypasses RLS.
 * Use ONLY for admin operations (email verification, etc.)
 * NEVER use this to read user data in server components.
 * 
 * Throws if SUPABASE_SERVICE_KEY is not configured.
 */
export function getSupabaseAdmin(): SupabaseClient {
  if (_supabaseAdmin) {
    return _supabaseAdmin;
  }

  const serviceKey = process.env.SUPABASE_SERVICE_KEY;
  const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL;

  if (!serviceKey) {
    throw new Error(
      'SUPABASE_SERVICE_KEY is not configured. ' +
      'Please add it to your .env.local file. ' +
      'See SUPABASE-KEY-ROTATION-GUIDE.md for details.'
    );
  }

  if (!supabaseUrl) {
    throw new Error(
      'NEXT_PUBLIC_SUPABASE_URL is not configured. ' +
      'Please add it to your .env.local file.'
    );
  }

  _supabaseAdmin = createSupabaseClient(supabaseUrl, serviceKey, {
    auth: {
      autoRefreshToken: false,
      persistSession: false,
    },
  });

  return _supabaseAdmin;
}

/**
 * Helper to verify email addresses (admin operation)
 * Bypasses normal email verification process - use with caution
 * 
 * @param userId - User ID to verify
 * @returns Promise resolving to user data
 * @throws Error if verification fails
 * 
 * @example
 * await verifyEmail('user-123');
 * // User's email is now marked as verified
 */
export async function verifyEmail(userId: string) {
  const admin = getSupabaseAdmin();
  const { data, error } = await admin.auth.admin.updateUserById(
    userId,
    { email_confirm: true }
  );

  if (error) throw error;
  return data;
}

/**
 * Helper to check if user has verified their email (admin operation)
 * 
 * @param userId - User ID to check
 * @returns Promise resolving to true if email is verified
 * 
 * @example
 * const isVerified = await isEmailVerified('user-123');
 * if (isVerified) {
 *   // Allow access to verified-only features
 * }
 */
export async function isEmailVerified(userId: string): Promise<boolean> {
  const admin = getSupabaseAdmin();
  const { data, error } = await admin.auth.admin.getUserById(userId);

  if (error) return false;
  return !!data.user?.email_confirmed_at;
}
