'use server';

import { createClient } from '@/lib/supabase/server';
import { checkIsAdmin } from './track-api-usage';
import { addCredits, getUserCredits } from './credit-service';
import { AdminCreditUpdateSchema, AdminSettingsSchema } from '@/types/whisky';

interface UserWithCredits {
    id: string;
    email: string;
    username: string;
    balance: number;
    total_purchased: number;
    total_used: number;
    daily_limit: number | null;
    google_search_cost: number;
    gemini_ai_cost: number;
    last_active?: string;
}

/**
 * Get all users with their credit information (admin only)
 */
export async function getAllUsersWithCredits(): Promise<UserWithCredits[]> {
    try {
        const supabase = await createClient();

        // Check if current user is admin
        const { data: { user } } = await supabase.auth.getUser();
        if (!user) {
            console.log('[getAllUsersWithCredits] No user found');
            return [];
        }

        const isAdmin = await checkIsAdmin(user.id);
        if (!isAdmin) {
            console.log('[getAllUsersWithCredits] User is not admin');
            return [];
        }

        console.log('[getAllUsersWithCredits] Fetching profiles...');
        // Get all users with their profiles
        const { data: profiles, error: profilesError } = await supabase
            .from('profiles')
            .select('id, username');

        if (profilesError) {
            console.error('Error fetching profiles:', profilesError);
            return [];
        }

        console.log('[getAllUsersWithCredits] Found profiles:', profiles?.length);

        // Get all user credits
        const { data: credits, error: creditsError } = await supabase
            .from('user_credits')
            .select('*');

        if (creditsError) {
            console.error('Error fetching credits:', creditsError);
        }

        console.log('[getAllUsersWithCredits] Found credits:', credits?.length);

        // Combine data - we'll use profile id as email fallback
        const usersWithCredits: UserWithCredits[] = profiles?.map(profile => {
            const userCredits = credits?.find(c => c.user_id === profile.id);

            return {
                id: profile.id,
                email: profile.id.substring(0, 8) + '...', // Show partial ID as placeholder
                username: profile.username || 'Unknown',
                balance: userCredits?.balance || 0,
                total_purchased: userCredits?.total_purchased || 0,
                total_used: userCredits?.total_used || 0,
                daily_limit: userCredits?.daily_limit || null,
                google_search_cost: userCredits?.google_search_cost || 1,
                gemini_ai_cost: userCredits?.gemini_ai_cost || 1,
                last_active: undefined
            };
        }) || [];

        console.log('[getAllUsersWithCredits] Returning users:', usersWithCredits.length);
        return usersWithCredits;
    } catch (err) {
        console.error('Error in getAllUsersWithCredits:', err);
        return [];
    }
}

/**
 * Update user's credit balance (admin only)
 */
export async function updateUserCredits(
    userId: string,
    newBalance: number,
    reason: string
): Promise<{ success: boolean; error?: string }> {
    try {
        const validated = AdminCreditUpdateSchema.parse({ userId, newBalance, reason });
        const supabase = await createClient();

        // Check if current user is admin
        const { data: { user } } = await supabase.auth.getUser();
        if (!user) return { success: false, error: 'Not authenticated' };

        const isAdmin = await checkIsAdmin(user.id);
        if (!isAdmin) return { success: false, error: 'Not authorized' };

        // Get current credits - if not found, create entry first
        let currentCredits = await getUserCredits(validated.userId);

        if (!currentCredits) {
            // Create credits entry for user who doesn't have one
            console.log(`[updateUserCredits] Creating credits entry for user ${validated.userId}`);
            const { data: newCredits, error: insertError } = await supabase
                .from('user_credits')
                .insert({
                    user_id: validated.userId,
                    balance: 0,
                    total_purchased: 0,
                    total_used: 0
                })
                .select()
                .single();

            if (insertError) {
                console.error('Error creating user credits:', insertError);
                return { success: false, error: 'Failed to create user credits' };
            }

            currentCredits = newCredits;
        }

        if (!currentCredits) {
            return { success: false, error: 'Konto konnte nicht erstellt werden' };
        }

        const difference = validated.newBalance - currentCredits.balance;

        // Use addCredits which handles the transaction logging
        const result = await addCredits(validated.userId, difference, validated.reason, user.id);

        return result;
    } catch (err) {
        console.error('Error in updateUserCredits:', err);
        return { success: false, error: err instanceof Error ? err.message : 'Failed to update credits' };
    }
}

/**
 * Set user's daily limit (admin only)
 */
export async function setUserDailyLimit(
    userId: string,
    dailyLimit: number | null
): Promise<{ success: boolean; error?: string }> {
    try {
        const validated = AdminSettingsSchema.parse({ userId, dailyLimit });
        const supabase = await createClient();

        // Check if current user is admin
        const { data: { user } } = await supabase.auth.getUser();
        if (!user) return { success: false, error: 'Not authenticated' };

        const isAdmin = await checkIsAdmin(user.id);
        if (!isAdmin) return { success: false, error: 'Not authorized' };

        const { error } = await supabase
            .from('user_credits')
            .update({ daily_limit: validated.dailyLimit })
            .eq('user_id', validated.userId);

        if (error) {
            console.error('Error setting daily limit:', error);
            return { success: false, error: 'Failed to set daily limit' };
        }

        return { success: true };
    } catch (err) {
        console.error('Error in setUserDailyLimit:', err);
        return { success: false, error: err instanceof Error ? err.message : 'Failed to set daily limit' };
    }
}

/**
 * Set user's API costs (admin only)
 */
export async function setUserApiCosts(
    userId: string,
    googleSearchCost: number,
    geminiAiCost: number
): Promise<{ success: boolean; error?: string }> {
    try {
        const validated = AdminSettingsSchema.parse({ userId, googleSearchCost, geminiAiCost });
        const supabase = await createClient();

        // Check if current user is admin
        const { data: { user } } = await supabase.auth.getUser();
        if (!user) return { success: false, error: 'Not authenticated' };

        const isAdmin = await checkIsAdmin(user.id);
        if (!isAdmin) return { success: false, error: 'Not authorized' };

        const { error } = await supabase
            .from('user_credits')
            .update({
                google_search_cost: validated.googleSearchCost,
                gemini_ai_cost: validated.geminiAiCost
            })
            .eq('user_id', validated.userId);

        if (error) {
            console.error('Error setting API costs:', error);
            return { success: false, error: 'Failed to set API costs' };
        }

        return { success: true };
    } catch (err) {
        console.error('Error in setUserApiCosts:', err);
        return { success: false, error: err instanceof Error ? err.message : 'Failed to set API costs' };
    }
}

/**
 * Bulk add credits to multiple users (admin only)
 */
export async function bulkAddCredits(
    userIds: string[],
    amount: number,
    reason: string
): Promise<{ success: boolean; processed: number; failed: number; error?: string }> {
    try {
        const supabase = await createClient();

        // Check if current user is admin
        const { data: { user } } = await supabase.auth.getUser();
        if (!user) return { success: false, processed: 0, failed: 0, error: 'Not authenticated' };

        const isAdmin = await checkIsAdmin(user.id);
        if (!isAdmin) return { success: false, processed: 0, failed: 0, error: 'Not authorized' };

        let processed = 0;
        let failed = 0;

        for (const userId of userIds) {
            const result = await addCredits(userId, amount, reason, user.id);
            if (result.success) {
                processed++;
            } else {
                failed++;
            }
        }

        return {
            success: true,
            processed,
            failed
        };
    } catch (err) {
        console.error('Error in bulkAddCredits:', err);
        return { success: false, processed: 0, failed: 0, error: 'Failed to bulk add credits' };
    }
}
