import { tradingRuntime } from './runtime';

export type CanonicalLifecycleState = 'OPEN' | 'PARTIAL_EXIT' | 'CLOSED' | 'ORPHAN_EXIT';
export type CanonicalSide = 'BUY' | 'SELL';

export interface CanonicalLifecycleProfileMeta {
    id: string;
    userId?: string;
    name: string;
    allocatedCapital: number;
    isActive: boolean;
}

export interface CanonicalLifecycleRow {
    id: string;
    profileId: string;
    profileName: string;
    tradeId: string;
    symbol: string;
    side: CanonicalSide;
    state: CanonicalLifecycleState;
    entryQty: number;
    exitQty: number;
    matchedQty: number;
    openQty: number;
    entryAvgPrice: number;
    exitAvgPrice: number;
    openEntryAvgPrice: number;
    openNotional: number;
    realizedPnl: number;
    realizedPnlPercent: number;
    unrealizedPnl: number;
    currentPrice: number;
    stopLoss?: number;
    takeProfit?: number;
    subTag?: string;
    hasSyntheticOrder: boolean;
    lastEventAt: number;
}

export interface CanonicalOpenPosition {
    id: string;
    profileId: string;
    profileName: string;
    tradeId: string;
    symbol: string;
    side: CanonicalSide;
    size: number;
    entryPrice: number;
    currentPrice: number;
    pnl: number;
    pnlPercent: number;
    stopLoss?: number;
    takeProfit?: number;
    subTag?: string;
    lastEventAt: number;
}

export interface CanonicalRealizedTrade {
    id: string;
    profileId: string;
    profileName: string;
    tradeId: string;
    symbol: string;
    side: CanonicalSide;
    size: number;
    entryPrice: number;
    exitPrice: number;
    pnl: number;
    pnlPercent: number;
    closedAt: number;
    state: CanonicalLifecycleState;
    subTag?: string;
}

export interface CanonicalLifecycleAggregate {
    profileId: string;
    profileName: string;
    allocatedCapital: number;
    isActive: boolean;
    openTrades: number;
    openNotional: number;
    realizedPnl: number;
    unrealizedPnl: number;
    netPnl: number;
    tradeCount: number;
    wins: number;
    winRate: number;
    lastClosedTradeAt: number;
}

export interface CanonicalLifecycleSnapshot {
    generatedAt: number;
    diagnostics: {
        orderRows: number;
        lifecycleRows: number;
        openPositions: number;
        realizedTrades: number;
        truncated: boolean;
    };
    profiles: CanonicalLifecycleProfileMeta[];
    lifecycleRows: CanonicalLifecycleRow[];
    openPositions: CanonicalOpenPosition[];
    realizedTrades: CanonicalRealizedTrade[];
    aggregates: {
        total: {
            openTrades: number;
            openNotional: number;
            realizedPnl: number;
            unrealizedPnl: number;
            netPnl: number;
            tradeCount: number;
            wins: number;
            winRate: number;
        };
        byProfile: Record<string, CanonicalLifecycleAggregate>;
    };
}

type CanonicalLifecycleApiResponse = {
    success: boolean;
    snapshot?: CanonicalLifecycleSnapshot;
    error?: string;
};

export const fetchCanonicalLifecycleSnapshot = async (args: {
    token: string;
    profileId?: string;
    maxRows?: number;
}): Promise<CanonicalLifecycleSnapshot | null> => {
    const token = String(args.token || '').trim();
    if (!token) return null;

    const apiUrl = String(tradingRuntime.tradingApiUrl || '').trim();
    if (!apiUrl) return null;

    const params = new URLSearchParams();
    const profileId = String(args.profileId || '').trim();
    if (profileId) params.set('profileId', profileId);
    if (Number.isFinite(Number(args.maxRows)) && Number(args.maxRows) > 0) {
        params.set('maxRows', String(Math.floor(Number(args.maxRows))));
    }
    const query = params.toString();
    const endpoint = `${apiUrl}/api/lifecycle/canonical${query ? `?${query}` : ''}`;

    const response = await fetch(endpoint, {
        headers: {
            Authorization: `Bearer ${token}`
        }
    });

    let payload: CanonicalLifecycleApiResponse | null = null;
    try {
        payload = (await response.json()) as CanonicalLifecycleApiResponse;
    } catch {
        payload = null;
    }

    if (!response.ok) {
        throw new Error(String(payload?.error || `Canonical lifecycle request failed (${response.status})`));
    }
    if (!payload?.success) {
        throw new Error(String(payload?.error || 'Canonical lifecycle request returned unsuccessful response'));
    }
    if (!payload.snapshot) {
        throw new Error('Canonical lifecycle response missing snapshot payload');
    }
    return payload.snapshot;
};
