import 'dotenv/config';
import { createClient } from '@supabase/supabase-js';

type SeedProfile = {
    name: string;
    allocated_capital: number;
    risk_per_trade_percent: number;
    symbols: string;
    is_active: boolean;
    strategy_config: Record<string, any>;
};

const supabaseUrl = String(process.env.SUPABASE_URL || '').trim();
const supabaseKey = String(
    process.env.SUPABASE_KEY
    || process.env.SUPABASE_SERVICE_ROLE_KEY
    || process.env.SUPABASE_ANON_KEY
    || ''
).trim();

if (!supabaseUrl || !supabaseKey) {
    throw new Error('Missing Supabase credentials. Expected SUPABASE_URL and SUPABASE_KEY/SUPABASE_SERVICE_ROLE_KEY.');
}

const supabase = createClient(supabaseUrl, supabaseKey);
const args = process.argv.slice(2);
const userIdArg = args.find((arg) => arg.startsWith('--user-id='))?.split('=')[1]?.trim();
const dryRun = args.includes('--dry-run');

const PROFILE_SPLIT = {
    aggressive: 1500,
    conservative: 1500
};

const buildProfiles = (): SeedProfile[] => {
    const frequentMomentum: SeedProfile = {
        name: 'Frequent Momentum Pro',
        allocated_capital: PROFILE_SPLIT.aggressive,
        risk_per_trade_percent: 1.2,
        symbols: 'BTC/USDT, ETH/USDT, SOL/USDT',
        is_active: true,
        strategy_config: {
            rules: [
                { ruleId: 'TrendBiasRule', enabled: true, params: { fastPeriod: 20, slowPeriod: 100 } },
                { ruleId: 'SessionRule', enabled: true, params: { sessions: ['NY', 'LDN'] } },
                { ruleId: 'ZoneRule', enabled: true, params: { timeframe: '15m', zonePercent: 1.2 } },
                { ruleId: 'MomentumRule', enabled: true, params: { timeframe: '15m', rsiPeriod: 9, overbought: 72, oversold: 28 } },
                {
                    ruleId: 'EntryTriggerRule',
                    enabled: true,
                    params: {
                        timeframe: '15m',
                        wickRatioThreshold: 0.45,
                        enableEmaReclaim: true,
                        enableWickRejection: true
                    }
                },
                { ruleId: 'RiskManagementRule', enabled: true, params: { atrPeriod: 10, slMultiplier: 1.2, maxRisk: 1.2 } },
                { ruleId: 'AIAnalysisRule', enabled: false, params: { minConfidence: 70 } }
            ],
            riskLimits: {
                maxDailyLossUsd: 45,
                maxConsecutiveLosses: 3,
                maxOpenTrades: 2
            },
            execution: {
                orderType: 'market',
                cooldownMinutes: 8,
                entryMode: 'both',
                profitExitPercent: 0.8
            }
        }
    };

    const controlledIntraday: SeedProfile = {
        name: 'Controlled Intraday Guard',
        allocated_capital: PROFILE_SPLIT.conservative,
        risk_per_trade_percent: 0.8,
        symbols: 'BTC/USDT, ETH/USDT',
        is_active: true,
        strategy_config: {
            rules: [
                { ruleId: 'TrendBiasRule', enabled: true, params: { fastPeriod: 50, slowPeriod: 200 } },
                { ruleId: 'SessionRule', enabled: true, params: { sessions: ['NY', 'LDN'] } },
                { ruleId: 'ZoneRule', enabled: true, params: { timeframe: '1h', zonePercent: 1.0 } },
                { ruleId: 'MomentumRule', enabled: true, params: { timeframe: '1h', rsiPeriod: 14, overbought: 68, oversold: 32 } },
                {
                    ruleId: 'EntryTriggerRule',
                    enabled: true,
                    params: {
                        timeframe: '1h',
                        wickRatioThreshold: 0.5,
                        enableEmaReclaim: true,
                        enableWickRejection: true
                    }
                },
                { ruleId: 'RiskManagementRule', enabled: true, params: { atrPeriod: 14, slMultiplier: 1.0, maxRisk: 0.9 } },
                { ruleId: 'AIAnalysisRule', enabled: false, params: { minConfidence: 75 } }
            ],
            riskLimits: {
                maxDailyLossUsd: 30,
                maxConsecutiveLosses: 2,
                maxOpenTrades: 2
            },
            execution: {
                orderType: 'market',
                cooldownMinutes: 18,
                entryMode: 'long_only',
                profitExitPercent: 1.0
            }
        }
    };

    return [frequentMomentum, controlledIntraday];
};

const fetchTargetUsers = async (): Promise<string[]> => {
    if (userIdArg) return [userIdArg];

    const { data, error } = await supabase
        .from('users')
        .select('user_id')
        .eq('trade_enable', true);
    if (error) {
        throw new Error(`Failed to fetch active users: ${error.message}`);
    }

    const ids = (data || [])
        .map((row: any) => String(row?.user_id || '').trim())
        .filter(Boolean);
    return Array.from(new Set(ids));
};

const upsertProfileForUser = async (userId: string, profile: SeedProfile): Promise<'inserted' | 'updated'> => {
    const { data: existing, error: existingError } = await supabase
        .from('trade_profiles')
        .select('id')
        .eq('user_id', userId)
        .eq('name', profile.name)
        .order('created_at', { ascending: true })
        .limit(1);

    if (existingError) {
        throw new Error(`Failed to query existing profile "${profile.name}" for user ${userId}: ${existingError.message}`);
    }

    const payload = {
        user_id: userId,
        name: profile.name,
        allocated_capital: profile.allocated_capital,
        risk_per_trade_percent: profile.risk_per_trade_percent,
        symbols: profile.symbols,
        is_active: profile.is_active,
        strategy_config: profile.strategy_config
    };

    if (existing && existing.length > 0) {
        if (!dryRun) {
            const { error: updateError } = await supabase
                .from('trade_profiles')
                .update(payload)
                .eq('id', existing[0].id);
            if (updateError) {
                throw new Error(`Failed to update profile "${profile.name}" for user ${userId}: ${updateError.message}`);
            }
        }
        return 'updated';
    }

    if (!dryRun) {
        const { error: insertError } = await supabase
            .from('trade_profiles')
            .insert([payload]);
        if (insertError) {
            throw new Error(`Failed to insert profile "${profile.name}" for user ${userId}: ${insertError.message}`);
        }
    }
    return 'inserted';
};

const run = async (): Promise<void> => {
    const users = await fetchTargetUsers();
    const profiles = buildProfiles();

    if (!users.length) {
        console.log(JSON.stringify({ ok: true, dry_run: dryRun, users_targeted: 0, message: 'No active users found.' }, null, 2));
        return;
    }

    let inserted = 0;
    let updated = 0;
    const perUser: Array<{ user_id: string; inserted: number; updated: number }> = [];

    for (const userId of users) {
        let userInserted = 0;
        let userUpdated = 0;
        for (const profile of profiles) {
            const result = await upsertProfileForUser(userId, profile);
            if (result === 'inserted') {
                inserted += 1;
                userInserted += 1;
            } else {
                updated += 1;
                userUpdated += 1;
            }
        }
        perUser.push({ user_id: userId, inserted: userInserted, updated: userUpdated });
    }

    console.log(JSON.stringify({
        ok: true,
        dry_run: dryRun,
        users_targeted: users.length,
        profiles_per_user: profiles.length,
        total_allocation_per_user: PROFILE_SPLIT.aggressive + PROFILE_SPLIT.conservative,
        totals: {
            inserted,
            updated
        },
        per_user: perUser
    }, null, 2));
};

run().catch((error) => {
    console.error(JSON.stringify({
        ok: false,
        error: error instanceof Error ? error.message : String(error)
    }, null, 2));
    process.exit(1);
});
