import { getContainer } from '@bytelyst/cosmos';
import { config } from '../config/index.js';
import logger from '../utils/logger.js';
import { getLegacySupabaseClient } from './legacySupabaseClient.js';
import type { CapitalLedgerRecord } from './CapitalLedger.js';

const CONTAINER_NAME = 'capital_ledgers';

interface CapitalLedgerDocument {
    id: string;
    productId: string;
    profile_id: string;
    allocated_capital: number;
    reserved_for_orders: number;
    reserved_for_positions: number;
    realized_pnl: number;
    updated_at: string;
}

const toNumeric = (value: unknown): number => {
    const numeric = Number(value);
    return Number.isFinite(numeric) ? numeric : 0;
};

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

function getLegacyClient() {
    return getLegacySupabaseClient();
}

function toLedgerRecord(doc: Partial<CapitalLedgerDocument> | null | undefined): CapitalLedgerRecord | null {
    const profileId = String(doc?.profile_id || '').trim();
    if (!profileId) return null;

    return {
        profile_id: profileId,
        allocated_capital: toNumeric(doc?.allocated_capital),
        reserved_for_orders: toNumeric(doc?.reserved_for_orders),
        reserved_for_positions: toNumeric(doc?.reserved_for_positions),
        realized_pnl: toNumeric(doc?.realized_pnl),
        updated_at: String(doc?.updated_at || new Date().toISOString())
    };
}

function toLedgerDocument(record: CapitalLedgerRecord): CapitalLedgerDocument {
    return {
        id: record.profile_id,
        productId: config.PRODUCT_ID,
        ...record
    };
}

async function readFromCosmos(profileId: string): Promise<CapitalLedgerRecord | null> {
    const container = getContainer(CONTAINER_NAME);
    try {
        const { resource } = await container.item(profileId, config.PRODUCT_ID).read<CapitalLedgerDocument>();
        return toLedgerRecord(resource);
    } catch (error) {
        const code = (error as { code?: number })?.code;
        if (code === 404) return null;
        throw error;
    }
}

async function writeToCosmos(record: CapitalLedgerRecord): Promise<CapitalLedgerRecord | null> {
    const container = getContainer(CONTAINER_NAME);
    const { resource } = await container.items.upsert(toLedgerDocument(record));
    return toLedgerRecord(resource as unknown as CapitalLedgerDocument);
}

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

    const { data, error } = await client
        .from('capital_ledgers')
        .select('*')
        .eq('profile_id', profileId)
        .maybeSingle();

    if (error) {
        logger.error(`[CapitalLedgerRepo] Legacy read failed for ${profileId}: ${error.message}`);
        return null;
    }

    return toLedgerRecord(data as CapitalLedgerDocument);
}

export async function getCapitalLedger(profileId: string): Promise<CapitalLedgerRecord | null> {
    if (!profileId) return null;

    if (!isCosmosConfigured()) {
        return readFromLegacy(profileId);
    }

    if (isCosmosConfigured()) {
        try {
            const cosmosRecord = await readFromCosmos(profileId);
            if (cosmosRecord) return cosmosRecord;
            const legacyRecord = await readFromLegacy(profileId);
            if (!legacyRecord) return null;
            await writeToCosmos(legacyRecord);
            logger.info(`[CapitalLedgerRepo] Seeded capital ledger ${profileId} from legacy store into Cosmos.`);
            return legacyRecord;
        } catch (error) {
            logger.warn(`[CapitalLedgerRepo] Cosmos read/seed failed for ${profileId}: ${error instanceof Error ? error.message : 'unknown error'}`);
            return null;
        }
    }
    return null;
}

export async function upsertCapitalLedger(
    record: CapitalLedgerRecord
): Promise<CapitalLedgerRecord | null> {
    if (!record.profile_id) return null;

    if (isCosmosConfigured()) {
        try {
            const saved = await writeToCosmos(record);
            if (saved) return saved;
        } catch (error) {
            logger.warn(`[CapitalLedgerRepo] Cosmos upsert failed, falling back to legacy store: ${error instanceof Error ? error.message : 'unknown error'}`);
        }
    }

    const client = getLegacyClient();
    if (!client) return null;

    const { data, error } = await client
        .from('capital_ledgers')
        .upsert({
            profile_id: record.profile_id,
            allocated_capital: record.allocated_capital,
            reserved_for_orders: record.reserved_for_orders,
            reserved_for_positions: record.reserved_for_positions,
            realized_pnl: record.realized_pnl,
            updated_at: record.updated_at
        }, { onConflict: 'profile_id' })
        .select('*')
        .maybeSingle();

    if (error) {
        logger.error(`[CapitalLedgerRepo] Legacy upsert failed for ${record.profile_id}: ${error.message}`);
        return null;
    }

    return toLedgerRecord(data as CapitalLedgerDocument);
}
