import { getContainer } from '@bytelyst/cosmos';
import { randomUUID } from 'node:crypto';
import { config } from '../config/index.js';
import logger from '../utils/logger.js';
import { getLegacySupabaseClient } from './legacySupabaseClient.js';

export interface TradingUserProfile {
    user_id: string;
    first_name: string;
    last_name: string;
    email: string;
    role: string;
    trade_enable: boolean;
    FMP_API_KEY?: string;
    ALPACA_API_KEY?: string;
    ALPACA_SECRET_KEY?: string;
    REAL_ALPACA_API_KEY?: string;
    REAL_ALPACA_SECRET_KEY?: string;
    drop_threshold_for_buy?: number;
    gain_threshold_for_sell?: number;
    market_poll_interval_in_seconds?: number;
}

export interface TradeProfileRecord {
    id: string;
    user_id: string;
    name: string;
    allocated_capital: number;
    risk_per_trade_percent: number;
    symbols: string;
    is_active: boolean;
    strategy_config: Record<string, unknown>;
    created_at?: string;
    updated_at?: string;
}

export const SIMPLE_AUTO_PROFILE_NAME = 'Simple Auto Profile';
const SIMPLE_AUTO_PROFILE_KEY = SIMPLE_AUTO_PROFILE_NAME.toLowerCase();

export interface TradeProfileCapitalSummary {
    allocatedCapital: number;
    isActive: boolean;
    userId?: string;
}

interface TradeProfileDocument extends TradeProfileRecord {
    productId: string;
    type: 'trade_profile';
    createdAt: string;
    updatedAt: string;
}

const PROFILE_CONTAINER = 'trade_profiles';
const USER_PROFILE_CONTAINER = 'trading_users';

interface TradingUserProfileDocument extends TradingUserProfile {
    id: string;
    productId: string;
    type: 'trading_user';
    createdAt: string;
    updatedAt: string;
}

function isCosmosConfigured(): boolean {
    return Boolean(config.COSMOS_ENDPOINT && config.COSMOS_KEY);
}

function getLegacyClient() {
    return getLegacySupabaseClient();
}

function coalesceString(...values: Array<unknown>): string {
    for (const value of values) {
        const normalized = String(value || '').trim();
        if (normalized) return normalized;
    }
    return '';
}

function coalesceNumber(...values: Array<unknown>): number {
    for (const value of values) {
        if (value === null || value === undefined || value === '') continue;
        const normalized = Number(value);
        if (Number.isFinite(normalized)) return normalized;
    }
    return 0;
}

function mergeTradingUserProfiles(
    primary: Partial<TradingUserProfile> | null | undefined,
    fallback: Partial<TradingUserProfile> | null | undefined,
    explicitUserId?: string
): TradingUserProfile | null {
    const userId = coalesceString(primary?.user_id, fallback?.user_id, explicitUserId);
    if (!userId) {
        return null;
    }

    return {
        user_id: userId,
        first_name: coalesceString(primary?.first_name, fallback?.first_name),
        last_name: coalesceString(primary?.last_name, fallback?.last_name),
        email: coalesceString(primary?.email, fallback?.email),
        role: coalesceString(primary?.role, fallback?.role, 'member'),
        trade_enable: Boolean(primary?.trade_enable ?? fallback?.trade_enable ?? true),
        FMP_API_KEY: coalesceString(primary?.FMP_API_KEY, fallback?.FMP_API_KEY),
        ALPACA_API_KEY: coalesceString(primary?.ALPACA_API_KEY, fallback?.ALPACA_API_KEY),
        ALPACA_SECRET_KEY: coalesceString(primary?.ALPACA_SECRET_KEY, fallback?.ALPACA_SECRET_KEY),
        REAL_ALPACA_API_KEY: coalesceString(primary?.REAL_ALPACA_API_KEY, fallback?.REAL_ALPACA_API_KEY),
        REAL_ALPACA_SECRET_KEY: coalesceString(primary?.REAL_ALPACA_SECRET_KEY, fallback?.REAL_ALPACA_SECRET_KEY),
        drop_threshold_for_buy: coalesceNumber(primary?.drop_threshold_for_buy, fallback?.drop_threshold_for_buy, 0),
        gain_threshold_for_sell: coalesceNumber(primary?.gain_threshold_for_sell, fallback?.gain_threshold_for_sell, 0),
        market_poll_interval_in_seconds: coalesceNumber(primary?.market_poll_interval_in_seconds, fallback?.market_poll_interval_in_seconds, 0),
    };
}

function normalizeProfile(row: Partial<TradeProfileRecord> | null | undefined): TradeProfileRecord | null {
    const id = String(row?.id || '').trim();
    const userId = String(row?.user_id || '').trim();
    if (!id || !userId) {
        return null;
    }

    return {
        id,
        user_id: userId,
        name: String(row?.name || 'Untitled Strategy').trim() || 'Untitled Strategy',
        allocated_capital: Number(row?.allocated_capital || 0),
        risk_per_trade_percent: Number(row?.risk_per_trade_percent || 0),
        symbols: String(row?.symbols || 'BTC/USDT'),
        is_active: Boolean(row?.is_active),
        strategy_config: (row?.strategy_config && typeof row.strategy_config === 'object')
            ? row.strategy_config as Record<string, unknown>
            : {},
        created_at: row?.created_at ? String(row.created_at) : undefined,
        updated_at: row?.updated_at ? String(row.updated_at) : undefined,
    };
}

function buildDefaultTradeProfile(userId: string): TradeProfileRecord {
    const timestamp = new Date().toISOString();
    return {
        id: randomUUID(),
        user_id: userId,
        name: 'My First Strategy',
        allocated_capital: 1000,
        risk_per_trade_percent: 1,
        symbols: 'BTC/USDT, ETH/USDT',
        is_active: false,
        strategy_config: {
            rules: [
                { ruleId: 'TrendBiasRule', enabled: true, params: { fastPeriod: 50, slowPeriod: 200 } },
                { ruleId: 'MomentumRule', enabled: true, params: { rsiPeriod: 14, overbought: 70, oversold: 30 } },
                { ruleId: 'ZoneRule', enabled: true, params: { zonePercent: 1.5 } },
                { ruleId: 'SessionRule', enabled: true, params: { sessions: 'London,NY' } },
                { ruleId: 'EntryTriggerRule', enabled: true, params: { showPatterns: true } },
                { ruleId: 'RiskManagementRule', enabled: true, params: { maxRisk: 2.0 } },
                { ruleId: 'AIAnalysisRule', enabled: false, params: { minConfidence: 0.7 } },
            ],
            riskLimits: { maxDailyLossUsd: 50, maxOpenTrades: 3, maxConsecutiveLosses: 2 },
            execution: { orderType: 'market', cooldownMinutes: 30, entryMode: 'both' },
        },
        created_at: timestamp,
        updated_at: timestamp,
    };
}

function parseProfileSymbols(symbolsRaw?: string | null): string[] {
    return String(symbolsRaw || '')
        .split(',')
        .map((value) => value.trim().toUpperCase())
        .filter(Boolean);
}

function buildSimpleAutoProfile(userId: string, symbol?: string): TradeProfileRecord {
    const normalizedSymbol = String(symbol || '').trim().toUpperCase();
    const timestamp = new Date().toISOString();
    return {
        id: randomUUID(),
        user_id: userId,
        name: SIMPLE_AUTO_PROFILE_NAME,
        allocated_capital: 1000,
        risk_per_trade_percent: 1,
        symbols: normalizedSymbol || 'AAPL',
        is_active: true,
        strategy_config: {
            mode: 'simple-auto',
            source: 'simple-tab',
            execution: {
                orderType: 'limit',
                entryMode: 'manual',
            },
        },
        created_at: timestamp,
        updated_at: timestamp,
    };
}

function normalizeTradingUserProfile(
    row: Partial<TradingUserProfile> | null | undefined,
    fallbackUserId?: string
): TradingUserProfile | null {
    const userId = String(row?.user_id || fallbackUserId || '').trim();
    if (!userId) {
        return null;
    }

    return {
        user_id: userId,
        first_name: String(row?.first_name || ''),
        last_name: String(row?.last_name || ''),
        email: String(row?.email || ''),
        role: String(row?.role || 'member'),
        trade_enable: Boolean(row?.trade_enable ?? true),
        FMP_API_KEY: row?.FMP_API_KEY,
        ALPACA_API_KEY: row?.ALPACA_API_KEY,
        ALPACA_SECRET_KEY: row?.ALPACA_SECRET_KEY,
        REAL_ALPACA_API_KEY: row?.REAL_ALPACA_API_KEY,
        REAL_ALPACA_SECRET_KEY: row?.REAL_ALPACA_SECRET_KEY,
        drop_threshold_for_buy: Number(row?.drop_threshold_for_buy ?? 0),
        gain_threshold_for_sell: Number(row?.gain_threshold_for_sell ?? 0),
        market_poll_interval_in_seconds: Number(row?.market_poll_interval_in_seconds ?? 0),
    };
}

function toTradingUserProfileDocument(profile: TradingUserProfile): TradingUserProfileDocument {
    const now = new Date().toISOString();
    return {
        ...profile,
        id: profile.user_id,
        productId: config.PRODUCT_ID,
        type: 'trading_user',
        createdAt: now,
        updatedAt: now,
    };
}

async function getTradingUserProfileFromCosmos(userId: string): Promise<TradingUserProfile | null> {
    if (!isCosmosConfigured() || !userId) {
        return null;
    }

    const container = getContainer(USER_PROFILE_CONTAINER);
    const { resources } = await container.items.query<TradingUserProfileDocument>({
        query: 'SELECT TOP 1 * FROM c WHERE c.productId = @productId AND c.type = @type AND c.user_id = @userId',
        parameters: [
            { name: '@productId', value: config.PRODUCT_ID },
            { name: '@type', value: 'trading_user' },
            { name: '@userId', value: userId },
        ],
    }).fetchAll();

    return normalizeTradingUserProfile(resources[0], userId);
}

async function upsertTradingUserProfileToCosmos(profile: TradingUserProfile): Promise<void> {
    if (!isCosmosConfigured()) return;
    const container = getContainer(USER_PROFILE_CONTAINER);
    await container.items.upsert<TradingUserProfileDocument>(toTradingUserProfileDocument(profile));
}

async function listProfilesFromCosmos(userId: string): Promise<TradeProfileRecord[]> {
    if (!isCosmosConfigured()) {
        return [];
    }

    const container = getContainer(PROFILE_CONTAINER);
    const { resources } = await container.items.query<TradeProfileDocument>({
        query: 'SELECT * FROM c WHERE c.productId = @productId AND c.user_id = @userId AND c.type = @type ORDER BY c.createdAt DESC',
        parameters: [
            { name: '@productId', value: config.PRODUCT_ID },
            { name: '@userId', value: userId },
            { name: '@type', value: 'trade_profile' },
        ],
    }).fetchAll();

    return resources
        .map((resource) => normalizeProfile({
            ...resource,
            created_at: resource.createdAt,
            updated_at: resource.updatedAt,
        }))
        .filter((profile): profile is TradeProfileRecord => Boolean(profile));
}

async function listAllProfilesFromCosmos(): Promise<TradeProfileRecord[]> {
    if (!isCosmosConfigured()) {
        return [];
    }

    const container = getContainer(PROFILE_CONTAINER);
    const { resources } = await container.items.query<TradeProfileDocument>({
        query: 'SELECT * FROM c WHERE c.productId = @productId AND c.type = @type ORDER BY c.createdAt DESC',
        parameters: [
            { name: '@productId', value: config.PRODUCT_ID },
            { name: '@type', value: 'trade_profile' },
        ],
    }).fetchAll();

    return resources
        .map((resource) => normalizeProfile({
            ...resource,
            created_at: resource.createdAt,
            updated_at: resource.updatedAt,
        }))
        .filter((profile): profile is TradeProfileRecord => Boolean(profile));
}

async function listProfilesFromSupabase(userId: string): Promise<TradeProfileRecord[]> {
    const client = getLegacyClient();
    if (!client) {
        return [];
    }

    try {
        const { data, error } = await client
            .from('trade_profiles')
            .select('id,user_id,name,allocated_capital,risk_per_trade_percent,symbols,is_active,strategy_config,created_at,updated_at')
            .eq('user_id', userId)
            .order('created_at', { ascending: false });

        if (error || !Array.isArray(data)) {
            return [];
        }

        return data
            .map((row) => normalizeProfile(row as TradeProfileRecord))
            .filter((profile): profile is TradeProfileRecord => Boolean(profile));
    } catch (error) {
        logger.warn(`[Profiles] Legacy profile read failed: ${error instanceof Error ? error.message : 'unknown error'}`);
        return [];
    }
}

async function seedProfilesToCosmos(profiles: TradeProfileRecord[]): Promise<TradeProfileRecord[]> {
    if (!isCosmosConfigured() || profiles.length === 0) {
        return profiles;
    }

    const container = getContainer(PROFILE_CONTAINER);
    await Promise.all(profiles.map((profile) => container.items.upsert<TradeProfileDocument>({
        ...profile,
        productId: config.PRODUCT_ID,
        type: 'trade_profile',
        createdAt: profile.created_at || new Date().toISOString(),
        updatedAt: profile.updated_at || new Date().toISOString(),
    })));
    return profiles;
}

async function listAllProfilesFromSupabase(): Promise<TradeProfileRecord[]> {
    const client = getLegacyClient();
    if (!client) {
        return [];
    }

    try {
        const { data, error } = await client
            .from('trade_profiles')
            .select('id,user_id,name,allocated_capital,risk_per_trade_percent,symbols,is_active,strategy_config,created_at,updated_at')
            .order('created_at', { ascending: false });

        if (error || !Array.isArray(data)) {
            return [];
        }

        return data
            .map((row) => normalizeProfile(row as TradeProfileRecord))
            .filter((profile): profile is TradeProfileRecord => Boolean(profile));
    } catch (error) {
        logger.warn(`[Profiles] Legacy global profile read failed: ${error instanceof Error ? error.message : 'unknown error'}`);
        return [];
    }
}

async function getProfileFromCosmos(profileId: string): Promise<TradeProfileRecord | null> {
    if (!isCosmosConfigured() || !profileId) {
        return null;
    }

    const container = getContainer(PROFILE_CONTAINER);
    const { resources } = await container.items.query<TradeProfileDocument>({
        query: 'SELECT TOP 1 * FROM c WHERE c.productId = @productId AND c.type = @type AND c.id = @id',
        parameters: [
            { name: '@productId', value: config.PRODUCT_ID },
            { name: '@type', value: 'trade_profile' },
            { name: '@id', value: profileId },
        ],
    }).fetchAll();

    const resource = resources[0];
    if (!resource) {
        return null;
    }

    return normalizeProfile({
        ...resource,
        created_at: resource.createdAt,
        updated_at: resource.updatedAt,
    });
}

async function getProfileFromSupabase(profileId: string): Promise<TradeProfileRecord | null> {
    const client = getLegacyClient();
    if (!client || !profileId) {
        return null;
    }

    try {
        const { data, error } = await client
            .from('trade_profiles')
            .select('id,user_id,name,allocated_capital,risk_per_trade_percent,symbols,is_active,strategy_config,created_at,updated_at')
            .eq('id', profileId)
            .maybeSingle();

        if (error || !data) {
            return null;
        }

        return normalizeProfile(data as TradeProfileRecord);
    } catch (error) {
        logger.warn(`[Profiles] Legacy profile lookup failed: ${error instanceof Error ? error.message : 'unknown error'}`);
        return null;
    }
}

async function mirrorProfileToSupabase(profile: TradeProfileRecord): Promise<void> {
    const client = getLegacyClient();
    if (!client) return;

    try {
        const { error } = await client
            .from('trade_profiles')
            .upsert({
                ...profile,
                created_at: profile.created_at || new Date().toISOString(),
                updated_at: profile.updated_at || new Date().toISOString(),
            }, { onConflict: 'id' });

        if (error) {
            logger.warn(`[Profiles] Legacy profile mirror failed: ${error.message}`);
        }
    } catch (error) {
        logger.warn(`[Profiles] Legacy profile mirror failed: ${error instanceof Error ? error.message : 'unknown error'}`);
    }
}

async function deleteProfileFromSupabase(profileId: string, userId: string): Promise<void> {
    const client = getLegacyClient();
    if (!client) return;

    try {
        const { error } = await client
            .from('trade_profiles')
            .delete()
            .eq('id', profileId)
            .eq('user_id', userId);

        if (error) {
            logger.warn(`[Profiles] Legacy profile delete failed: ${error.message}`);
        }
    } catch (error) {
        logger.warn(`[Profiles] Legacy profile delete failed: ${error instanceof Error ? error.message : 'unknown error'}`);
    }
}

export async function listTradeProfilesForUser(userId: string): Promise<TradeProfileRecord[]> {
    if (!isCosmosConfigured()) {
        return listProfilesFromSupabase(userId);
    }

    try {
        const cosmosProfiles = await listProfilesFromCosmos(userId);
        if (cosmosProfiles.length > 0) {
            return cosmosProfiles;
        }
        const seededProfiles = await seedProfilesToCosmos(await listProfilesFromSupabase(userId));
        if (seededProfiles.length > 0) {
            logger.info(`[Profiles] Seeded ${seededProfiles.length} user profiles from legacy store into Cosmos for user ${userId}.`);
        }
        return seededProfiles;
    } catch (error) {
        logger.warn(`[Profiles] Cosmos profile read/seed failed for user ${userId}: ${error instanceof Error ? error.message : 'unknown error'}`);
        return [];
    }
}

export async function listAllTradeProfiles(): Promise<TradeProfileRecord[]> {
    if (!isCosmosConfigured()) {
        return listAllProfilesFromSupabase();
    }

    try {
        const cosmosProfiles = await listAllProfilesFromCosmos();
        if (cosmosProfiles.length > 0) {
            return cosmosProfiles;
        }
        const seededProfiles = await seedProfilesToCosmos(await listAllProfilesFromSupabase());
        if (seededProfiles.length > 0) {
            logger.info(`[Profiles] Seeded ${seededProfiles.length} profiles from legacy store into Cosmos.`);
        }
        return seededProfiles;
    } catch (error) {
        logger.warn(`[Profiles] Cosmos global profile read/seed failed: ${error instanceof Error ? error.message : 'unknown error'}`);
        return [];
    }
}

export async function listActiveTradeProfiles(): Promise<TradeProfileRecord[]> {
    const profiles = await listAllTradeProfiles();
    return profiles.filter((profile) => Boolean(profile.is_active));
}

export async function getTradeProfileById(profileId: string): Promise<TradeProfileRecord | null> {
    const normalizedId = String(profileId || '').trim();
    if (!normalizedId) {
        return null;
    }

    if (!isCosmosConfigured()) {
        return getProfileFromSupabase(normalizedId);
    }

    try {
        const cosmosProfile = await getProfileFromCosmos(normalizedId);
        if (cosmosProfile) {
            return cosmosProfile;
        }
        const legacyProfile = await getProfileFromSupabase(normalizedId);
        if (!legacyProfile) {
            return null;
        }
        await seedProfilesToCosmos([legacyProfile]);
        logger.info(`[Profiles] Seeded profile ${normalizedId} from legacy store into Cosmos.`);
        return legacyProfile;
    } catch (error) {
        logger.warn(`[Profiles] Cosmos profile lookup/seed failed for ${normalizedId}: ${error instanceof Error ? error.message : 'unknown error'}`);
        return null;
    }
}

export async function getTradeProfileCapital(profileId: string): Promise<TradeProfileCapitalSummary | null> {
    const profile = await getTradeProfileById(profileId);
    if (!profile) {
        return null;
    }

    return {
        allocatedCapital: Number(profile.allocated_capital || 0),
        isActive: Boolean(profile.is_active),
        userId: profile.user_id || undefined,
    };
}

export async function getTradeProfileForUser(profileId: string, userId: string): Promise<TradeProfileRecord | null> {
    const profile = await getTradeProfileById(profileId);
    if (!profile || String(profile.user_id || '').trim() !== String(userId || '').trim()) {
        return null;
    }
    return profile;
}

export async function ensureDefaultTradeProfileForUser(userId: string): Promise<TradeProfileRecord[]> {
    const profiles = await listTradeProfilesForUser(userId);
    if (profiles.length > 0) {
        return profiles;
    }

    const created = await saveTradeProfileForUser(buildDefaultTradeProfile(userId), userId);
    return [created];
}

export async function ensureSimpleAutoProfileForUser(userId: string, symbol?: string): Promise<TradeProfileRecord> {
    const normalizedSymbol = String(symbol || '').trim().toUpperCase();
    const profiles = await listTradeProfilesForUser(userId);
    const existing = profiles.find((profile) => String(profile.name || '').trim().toLowerCase() === SIMPLE_AUTO_PROFILE_KEY);

    if (!existing) {
        return saveTradeProfileForUser(buildSimpleAutoProfile(userId, normalizedSymbol), userId);
    }

    const symbolSet = new Set(parseProfileSymbols(existing.symbols));
    if (normalizedSymbol) {
        symbolSet.add(normalizedSymbol);
    }
    const nextSymbols = Array.from(symbolSet).join(', ');
    const nextIsActive = true;
    const didChange = existing.symbols !== nextSymbols || !existing.is_active;
    if (!didChange) {
        return existing;
    }

    return saveTradeProfileForUser({
        ...existing,
        symbols: nextSymbols,
        is_active: nextIsActive,
    }, userId);
}

export async function saveTradeProfileForUser(
    input: Partial<TradeProfileRecord>,
    userId: string
): Promise<TradeProfileRecord> {
    const now = new Date().toISOString();
    const normalized = normalizeProfile({
        ...input,
        id: String(input.id || randomUUID()),
        user_id: userId,
        created_at: input.created_at || now,
        updated_at: now,
    });

    if (!normalized) {
        throw new Error('Invalid trade profile payload');
    }

    if (isCosmosConfigured()) {
        try {
            const container = getContainer(PROFILE_CONTAINER);
            await container.items.upsert<TradeProfileDocument>({
                ...normalized,
                productId: config.PRODUCT_ID,
                type: 'trade_profile',
                createdAt: normalized.created_at || now,
                updatedAt: normalized.updated_at || now,
            });
        } catch (error) {
            logger.warn(`[Profiles] Cosmos profile upsert failed: ${error instanceof Error ? error.message : 'unknown error'}`);
        }
    }

    await mirrorProfileToSupabase(normalized);
    return normalized;
}

export async function deleteTradeProfileForUser(
    profileId: string,
    userId: string
): Promise<void> {
    if (!profileId || !userId) {
        return;
    }

    if (isCosmosConfigured()) {
        try {
            const container = getContainer(PROFILE_CONTAINER);
            await container.item(profileId, userId).delete();
        } catch (error) {
            logger.warn(`[Profiles] Cosmos profile delete failed: ${error instanceof Error ? error.message : 'unknown error'}`);
        }
    }

    await deleteProfileFromSupabase(profileId, userId);
}

export async function getCurrentUserProfile(
    userId: string,
    fallback: Partial<TradingUserProfile> = {}
): Promise<TradingUserProfile> {
    if (isCosmosConfigured()) {
        try {
            const cosmosProfile = await getTradingUserProfileFromCosmos(userId);
            if (cosmosProfile) {
                return mergeTradingUserProfiles(cosmosProfile, fallback, userId) || cosmosProfile;
            }
        } catch (error) {
            logger.warn(`[Profiles] Cosmos user profile read failed for ${userId}: ${error instanceof Error ? error.message : 'unknown error'}`);
        }
    }

    const client = getLegacyClient();
    if (client) {
        try {
            const { data, error } = await client
                .from('users')
                .select('user_id,first_name,last_name,email,role,trade_enable,FMP_API_KEY,ALPACA_API_KEY,ALPACA_SECRET_KEY,REAL_ALPACA_API_KEY,REAL_ALPACA_SECRET_KEY,drop_threshold_for_buy,gain_threshold_for_sell,market_poll_interval_in_seconds')
                .eq('user_id', userId)
                .maybeSingle();

            if (!error && data) {
                const normalized = mergeTradingUserProfiles(data as any, fallback, userId);
                if (!normalized) {
                    throw new Error(`Invalid user profile for ${userId}`);
                }
                await upsertTradingUserProfileToCosmos(normalized);
                return normalized;
            }
        } catch (error) {
            logger.warn(`[Profiles] Legacy user profile read failed: ${error instanceof Error ? error.message : 'unknown error'}`);
        }
    }

    return mergeTradingUserProfiles({}, fallback, userId) || {
        user_id: userId,
        first_name: '',
        last_name: '',
        email: '',
        role: 'member',
        trade_enable: Boolean(fallback.trade_enable ?? true),
        FMP_API_KEY: '',
        ALPACA_API_KEY: '',
        ALPACA_SECRET_KEY: '',
        REAL_ALPACA_API_KEY: '',
        REAL_ALPACA_SECRET_KEY: '',
        drop_threshold_for_buy: 0,
        gain_threshold_for_sell: 0,
        market_poll_interval_in_seconds: 0,
    };
}

export async function saveCurrentUserProfile(
    userId: string,
    input: Partial<TradingUserProfile>,
    fallback: Partial<TradingUserProfile> = {}
): Promise<TradingUserProfile> {
    const existing = await getCurrentUserProfile(userId, fallback);
    const merged: TradingUserProfile = {
        ...existing,
        ...input,
        user_id: userId,
        email: String(input.email ?? existing.email ?? fallback.email ?? ''),
        role: String(input.role ?? existing.role ?? fallback.role ?? 'member'),
        first_name: String(input.first_name ?? existing.first_name ?? fallback.first_name ?? ''),
        last_name: String(input.last_name ?? existing.last_name ?? fallback.last_name ?? ''),
        trade_enable: Boolean(input.trade_enable ?? existing.trade_enable ?? fallback.trade_enable ?? true),
        drop_threshold_for_buy: Number(input.drop_threshold_for_buy ?? existing.drop_threshold_for_buy ?? fallback.drop_threshold_for_buy ?? 0),
        gain_threshold_for_sell: Number(input.gain_threshold_for_sell ?? existing.gain_threshold_for_sell ?? fallback.gain_threshold_for_sell ?? 0),
        market_poll_interval_in_seconds: Number(input.market_poll_interval_in_seconds ?? existing.market_poll_interval_in_seconds ?? fallback.market_poll_interval_in_seconds ?? 0),
    };

    try {
        await upsertTradingUserProfileToCosmos(merged);
    } catch (error) {
        logger.warn(`[Profiles] Cosmos user profile save failed: ${error instanceof Error ? error.message : 'unknown error'}`);
    }

    const client = getLegacyClient();
    if (client) {
        try {
            const { error } = await client
                .from('users')
                .upsert({
                    user_id: userId,
                    first_name: merged.first_name,
                    last_name: merged.last_name,
                    email: merged.email,
                    role: merged.role,
                    trade_enable: merged.trade_enable,
                    FMP_API_KEY: merged.FMP_API_KEY ?? null,
                    ALPACA_API_KEY: merged.ALPACA_API_KEY ?? null,
                    ALPACA_SECRET_KEY: merged.ALPACA_SECRET_KEY ?? null,
                    REAL_ALPACA_API_KEY: merged.REAL_ALPACA_API_KEY ?? null,
                    REAL_ALPACA_SECRET_KEY: merged.REAL_ALPACA_SECRET_KEY ?? null,
                    drop_threshold_for_buy: merged.drop_threshold_for_buy,
                    gain_threshold_for_sell: merged.gain_threshold_for_sell,
                    market_poll_interval_in_seconds: merged.market_poll_interval_in_seconds,
                }, { onConflict: 'user_id' });

            if (error) {
                throw new Error(error.message);
            }
        } catch (error) {
            logger.warn(`[Profiles] Legacy user profile save failed: ${error instanceof Error ? error.message : 'unknown error'}`);
        }
    }

    return merged;
}
