'use server';

import { createClient } from '@/lib/supabase/server';

import { checkIsAdmin } from './track-api-usage';

interface UserCredits {
    user_id: string;
    balance: number;
    total_purchased: number;
    total_used: number;
    daily_limit: number | null;
    google_search_cost: number;
    gemini_ai_cost: number;
    last_reset_at: string;
    updated_at: string;
}

interface CreditTransaction {
    id: string;
    user_id: string;
    amount: number;
    type: 'deduction' | 'addition' | 'admin_adjustment';
    reason?: string;
    api_type?: 'google_search' | 'gemini_ai';
    admin_id?: string;
    balance_after: number;
    created_at: string;
}

/**
 * Get user's credit information
 */
export async function getUserCredits(userId: string): Promise<UserCredits | null> {
    try {
        const supabase = await createClient();

        // Security check: Only self or admin can view credits
        const { data: { user: currentUser } } = await supabase.auth.getUser();
        if (!currentUser) return null;

        const isAdmin = await checkIsAdmin(currentUser.id);

        if (currentUser.id !== userId && !isAdmin) {
            console.error('Unauthorized credit fetch attempt');
            return null;
        }

        const { data, error } = await supabase
            .from('user_credits')
            .select('*')
            .eq('user_id', userId)
            .single();

        if (error) {
            // If user doesn't have credits yet, create entry based on their subscription plan
            if (error.code === 'PGRST116') {
                // Get user's subscription plan credits
                const { data: subscription } = await supabase
                    .from('user_subscriptions')
                    .select(`
                        subscription_plans (
                            monthly_credits
                        )
                    `)
                    .eq('user_id', userId)
                    .single();

                // Extract monthly_credits from plan (default to 10 for starter)
                const planData = subscription?.subscription_plans;
                const plan = Array.isArray(planData) ? planData[0] : planData;
                const startingCredits = plan?.monthly_credits ?? 10;

                const { data: newCredits, error: insertError } = await supabase
                    .from('user_credits')
                    .insert({
                        user_id: userId,
                        balance: startingCredits,
                        total_purchased: 0,
                        total_used: 0
                    })
                    .select()
                    .single();

                if (insertError) {
                    console.error('Error creating user credits:', insertError);
                    return null;
                }

                console.log(`[Credits] Created credits for user with ${startingCredits} balance from plan`);
                return newCredits;
            }

            console.error('Error fetching user credits:', error);
            return null;
        }

        return data;
    } catch (err) {
        console.error('Error in getUserCredits:', err);
        return null;
    }
}

/**
 * Check if user has enough credits
 */
export async function checkCreditBalance(
    userId: string,
    apiType: 'google_search' | 'gemini_ai'
): Promise<{ allowed: boolean; balance: number; cost: number; message?: string }> {
    try {
        const credits = await getUserCredits(userId);

        if (!credits) {
            return {
                allowed: false,
                balance: 0,
                cost: 1,
                message: 'Could not fetch credit information'
            };
        }

        const cost = apiType === 'google_search'
            ? credits.google_search_cost
            : credits.gemini_ai_cost;

        const allowed = credits.balance >= cost;

        return {
            allowed,
            balance: credits.balance,
            cost,
            message: allowed ? undefined : `Insufficient credits. You need ${cost} credits but have ${credits.balance}.`
        };
    } catch (err) {
        console.error('Error in checkCreditBalance:', err);
        return {
            allowed: false,
            balance: 0,
            cost: 1,
            message: 'Error checking credit balance'
        };
    }
}

/**
 * Deduct credits from user's balance
 */
export async function deductCredits(
    userId: string,
    apiType: 'google_search' | 'gemini_ai',
    reason?: string
): Promise<{ success: boolean; newBalance?: number; error?: string }> {
    try {
        const supabase = await createClient();

        // Get current credits
        const credits = await getUserCredits(userId);
        if (!credits) {
            return { success: false, error: 'Could not fetch credit information' };
        }

        // Security check: Only self or admin can deduct credits
        const { data: { user: currentUser } } = await supabase.auth.getUser();
        if (!currentUser) return { success: false, error: 'Nicht authentifiziert' };

        const isAdmin = await checkIsAdmin(currentUser.id);

        if (currentUser.id !== userId && !isAdmin) {
            return { success: false, error: 'Nicht autorisiert' };
        }

        const cost = apiType === 'google_search'
            ? credits.google_search_cost
            : credits.gemini_ai_cost;

        // Check if user has enough credits
        if (credits.balance < cost) {
            return {
                success: false,
                error: `Nicht genügend Credits. Du benötigst ${cost}, hast aber nur ${credits.balance}.`
            };
        }

        const newBalance = credits.balance - cost;

        // Update user credits
        const { error: updateError } = await supabase
            .from('user_credits')
            .update({
                balance: newBalance,
                total_used: credits.total_used + cost,
                updated_at: new Date().toISOString()
            })
            .eq('user_id', userId);

        if (updateError) {
            console.error('Error updating user credits:', updateError);
            return { success: false, error: 'Failed to update credits' };
        }

        // Log transaction
        const { error: transactionError } = await supabase
            .from('credit_transactions')
            .insert({
                user_id: userId,
                amount: -cost,
                type: 'deduction',
                reason: reason || `${apiType} API call`,
                api_type: apiType,
                balance_after: newBalance
            });

        if (transactionError) {
            console.error('Error logging credit transaction:', transactionError);
            // Don't fail the operation if logging fails
        }

        return { success: true, newBalance };
    } catch (err) {
        console.error('Error in deductCredits:', err);
        return { success: false, error: 'Failed to deduct credits' };
    }
}

/**
 * Add credits to user's balance
 */
export async function addCredits(
    userId: string,
    amount: number,
    reason: string,
    adminId?: string
): Promise<{ success: boolean; newBalance?: number; error?: string }> {
    try {
        const supabase = await createClient();

        // Security check
        const { data: { user: currentUser } } = await supabase.auth.getUser();
        if (!currentUser) return { success: false, error: 'Nicht authentifiziert' };

        const isAdmin = await checkIsAdmin(currentUser.id);

        if (!isAdmin && adminId) {
            return { success: false, error: 'Nur Administratoren können Credits anpassen.' };
        }

        // Get current credits
        const credits = await getUserCredits(userId);
        if (!credits) {
            return { success: false, error: 'Could not fetch credit information' };
        }

        const newBalance = credits.balance + amount;

        // Update user credits
        const { error: updateError } = await supabase
            .from('user_credits')
            .update({
                balance: newBalance,
                total_purchased: adminId ? credits.total_purchased + amount : credits.total_purchased,
                updated_at: new Date().toISOString()
            })
            .eq('user_id', userId);

        if (updateError) {
            console.error('Error updating user credits:', updateError);
            return { success: false, error: 'Failed to update credits' };
        }

        // Log transaction
        const { error: transactionError } = await supabase
            .from('credit_transactions')
            .insert({
                user_id: userId,
                amount: amount,
                type: adminId ? 'admin_adjustment' : 'addition',
                reason: reason,
                admin_id: adminId,
                balance_after: newBalance
            });

        if (transactionError) {
            console.error('Error logging credit transaction:', transactionError);
        }

        return { success: true, newBalance };
    } catch (err) {
        console.error('Error in addCredits:', err);
        return { success: false, error: 'Failed to add credits' };
    }
}

/**
 * Get user's credit transaction history
 */
export async function getCreditTransactions(
    userId: string,
    limit: number = 50
): Promise<CreditTransaction[]> {
    try {
        const supabase = await createClient();

        const { data, error } = await supabase
            .from('credit_transactions')
            .select('*')
            .eq('user_id', userId)
            .order('created_at', { ascending: false })
            .limit(limit);

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

        return data || [];
    } catch (err) {
        console.error('Error in getCreditTransactions:', err);
        return [];
    }
}
