import React, { useState, Component, ReactNode, useEffect } from 'react';
import { createRoot } from 'react-dom/client';
import { BarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer, LineChart, Line, ReferenceLine, ComposedChart, Cell } from 'recharts';
import { UploadCloud, FileText, BrainCircuit, Trophy, Loader2, TrendingUp, Scale, Sigma, AlertTriangle, ShieldCheck, Bug, Settings, Key } from 'lucide-react';
import { GoogleGenAI } from "@google/genai";

console.log("App initializing...");

// Helper to initialize API Key from local storage if available
const loadSavedKey = () => {
    try {
        const saved = localStorage.getItem("GEMINI_API_KEY");
        if (saved && typeof process !== "undefined" && process.env) {
            process.env.API_KEY = saved;
        }
    } catch(e) {}
};
loadSavedKey();

// ==========================================
// 1. TYPES
// ==========================================

interface LogEntry {
    runFolder: string;
    symbol: string;
    rollingStart: string; // YYYY-MM-DD
    trades: number;
    netProfit: number;
    netPips: number;
    winRate: number;
}

interface RunSummary {
    id: string;
    symbol: string;
    totalNetProfit: number;
    maxDDPercent: number | null;
    profitToDDRatio: number;
    winRate: number;
    tradeCount: number;
    expectancy: number;
    isNegative: boolean;
    entries: LogEntry[];
    bestDay: string;
}

interface WeekdayStat {
    weekday: string;
    count: number;
    positiveCount: number;
    winRate: number;
    meanNetProfit: number;
    medianNetProfit: number;
    profitFactorProxy: number;
}

interface DistributionBucket {
    range: string;
    min: number;
    max: number;
    count: number;
}

interface EdgeMetrics {
    probabilityOfProfit: number;
    averageExpectancy: number;
    kellyCriterionProxy: number;
    profitFactorGlobal: number;
    distribution: DistributionBucket[];
}

interface AnalysisResult {
    runs: RunSummary[];
    weekdayStats: WeekdayStat[];
    edgeMetrics: EdgeMetrics;
    bestRun: RunSummary | null;
    bestNoDDRun: RunSummary | null;
    totalFilesProcessed: number;
    rejectedFiles: number;
    debugLog?: string[];
}

type ProgressCallback = (processed: number, total: number) => void;

// ==========================================
// 2. SERVICES (Parser & AI)
// ==========================================

// ROBUST PARSING LOGIC V2
const TOKENS = {
    TRADES: /Trades\s*[:=]\s*([-\d.,]+)/i,
    PROFIT: /NetProfit\s*[:=]\s*([-\d.,]+)/i,
    WINRATE: /WinRate\s*[:=]\s*([-\d.,]+)/i,
    DATE: /(\d{4}[-./]\d{2}[-./]\d{2}|\d{2}[-./]\d{2}[-./]\d{4})/
};

const DD_REGEXES = [
    /max(?:imum)?\s*balance\s*drawdown\s*[:=]\s*(?<dd>[-\d.,]+)\s*%?/i,
    /max(?:imum)?\s*equity\s*drawdown\s*[:=]\s*(?<dd>[-\d.,]+)\s*%?/i,
];
const NEG_TAG_RE = /(?:\[NEG\]|backtest\s*negativo|negative\s*backtest|stop\s*out|margin\s*call|drawdown\s*completo)/i;

const MAX_FILE_SIZE_BYTES = 100 * 1024 * 1024; // 100MB
const ALLOWED_EXTENSIONS = ['.txt', '.log'];

const parseDecimal = (s: string): number => {
    if (!s) return 0;
    let clean = s.trim().replace('%', '');
    const lastComma = clean.lastIndexOf(',');
    const lastDot = clean.lastIndexOf('.');
    if (lastComma > lastDot && lastComma > -1) {
        clean = clean.replace(/\./g, '').replace(',', '.');
    } else if (lastComma > -1) {
        clean = clean.replace(/,/g, '');
    }
    const val = parseFloat(clean);
    return isNaN(val) ? 0 : val;
};

const parseDate = (s: string): string => {
    let clean = s.replace(/\./g, '-').replace(/\//g, '-');
    if (/^\d{4}/.test(clean)) return clean; 
    const parts = clean.split('-');
    if (parts.length === 3) return `${parts[2]}-${parts[1]}-${parts[0]}`;
    return clean;
};

const isValidLogFile = async (file: File): Promise<boolean> => {
    const lowerName = file.name.toLowerCase();
    if (!ALLOWED_EXTENSIONS.some(ext => lowerName.endsWith(ext))) return false;
    if (file.size > MAX_FILE_SIZE_BYTES) return false;
    return true;
};

const processFiles = async (files: File[], onProgress?: ProgressCallback): Promise<AnalysisResult> => {
    const runs = new Map<string, Partial<RunSummary>>();
    let totalFilesProcessed = 0;
    let rejectedFiles = 0;
    const debugLog: string[] = [];
    
    const candidateFiles = files.filter(f => f.name.toLowerCase().endsWith('.txt') || f.name.toLowerCase().endsWith('.log'));
    const BATCH_SIZE = 50;
    
    for (let i = 0; i < candidateFiles.length; i++) {
        const file = candidateFiles[i];
        if (i % BATCH_SIZE === 0) {
            await new Promise(resolve => setTimeout(resolve, 0));
            if (onProgress) onProgress(i, candidateFiles.length);
        }

        const isValid = await isValidLogFile(file);
        if (!isValid) {
            rejectedFiles++;
            continue;
        }

        try {
            let text = await file.text();
            if (text.indexOf('\u0000') > -1) text = text.replace(/\u0000/g, '');
            const lines = text.split(/\r?\n/);
            let maxDD: number | null = null;
            let isNeg = false;
            let symbol = "Unknown";
            const entries: LogEntry[] = [];
            
            if (i === 0) {
                 debugLog.push(`Processing File: ${file.name}`);
                 debugLog.push(`First 5 lines raw content:`);
                 debugLog.push(...lines.slice(0, 5).map(l => l.substring(0, 100)));
            }
            
            const f = file as any;
            const relPath = f.webkitRelativePath || '';
            const runId = (relPath && relPath.length > 0) ? relPath.substring(0, relPath.lastIndexOf('/')) : file.name.replace(/\.[^/.]+$/, "");

            for (const line of lines) {
                if (!line.trim()) continue;
                if (!isNeg && NEG_TAG_RE.test(line)) isNeg = true;
                for (const rgx of DD_REGEXES) {
                    const m = line.match(rgx);
                    if (m && m.groups?.dd) {
                        const v = parseDecimal(m.groups.dd);
                        if (!isNaN(v)) maxDD = maxDD === null ? v : Math.max(maxDD, v);
                    }
                }
                if (line.includes('Symbol=')) {
                    const m = line.match(/Symbol\s*=\s*([^\s]+)/i);
                    if (m) symbol = m[1];
                }
                if (TOKENS.TRADES.test(line) && TOKENS.PROFIT.test(line)) {
                     const mTrades = line.match(TOKENS.TRADES);
                     const mProfit = line.match(TOKENS.PROFIT);
                     
                     if (mTrades && mProfit) {
                         let dateStr = "N/A";
                         const allDates = [...line.matchAll(/(\d{4}[-./]\d{2}[-./]\d{2}|\d{2}[-./]\d{2}[-./]\d{4})/g)];
                         if (allDates.length > 0) {
                             if (allDates.length >= 2) dateStr = parseDate(allDates[1][0]);
                             else dateStr = parseDate(allDates[0][0]);
                         }
                         const winRateMatch = line.match(TOKENS.WINRATE);
                         const winRate = winRateMatch ? parseDecimal(winRateMatch[1]) : 0;
                         const trades = parseDecimal(mTrades[1]);
                         const profit = parseDecimal(mProfit[1]);

                         if (!isNaN(profit)) {
                             entries.push({
                                runFolder: runId, symbol: symbol, rollingStart: dateStr,
                                trades: trades, netProfit: profit, netPips: 0, winRate: winRate
                            });
                         }
                     }
                }
            }

            if (entries.length > 0) {
                entries.forEach(e => { if(symbol !== "Unknown") e.symbol = symbol; });
                const totalNetProfit = entries.reduce((sum, e) => sum + e.netProfit, 0);
                const summary: RunSummary = {
                    id: runId, 
                    symbol: symbol !== "Unknown" ? symbol : entries[0].symbol || "Unknown",
                    totalNetProfit,
                    maxDDPercent: maxDD,
                    profitToDDRatio: (maxDD && maxDD > 0) ? totalNetProfit / maxDD : 0,
                    winRate: entries.reduce((sum, e) => sum + e.winRate, 0) / entries.length,
                    tradeCount: entries.reduce((sum, e) => sum + e.trades, 0),
                    expectancy: entries.length > 0 ? totalNetProfit / entries.reduce((sum, e) => sum + e.trades, 0) : 0,
                    isNegative: isNeg || totalNetProfit <= 0,
                    entries,
                    bestDay: entries[0]?.rollingStart || "N/A"
                };
                
                if (runs.has(runId)) {
                    const existing = runs.get(runId)!;
                    if (existing.entries) {
                        existing.entries.push(...entries);
                        existing.totalNetProfit = (existing.totalNetProfit || 0) + totalNetProfit;
                        existing.tradeCount = (existing.tradeCount || 0) + summary.tradeCount;
                        existing.maxDDPercent = Math.max(existing.maxDDPercent || 0, maxDD || 0);
                        existing.winRate = existing.entries.reduce((sum, e) => sum + e.winRate, 0) / existing.entries.length;
                    }
                } else {
                    runs.set(runId, summary);
                }
            }
        } catch (e) {
            console.error("Error parsing file:", file.name, e);
            debugLog.push(`Error parsing ${file.name}: ${e}`);
        }
        totalFilesProcessed++;
    }

    const allRuns = Array.from(runs.values()) as RunSummary[];
    const validRuns = allRuns.filter(r => r.totalNetProfit !== undefined);
    const positiveRuns = validRuns.filter(r => r.totalNetProfit > 0);
    
    const distribution: DistributionBucket[] = [];
    if (validRuns.length > 0) {
        const profits = validRuns.map(r => r.totalNetProfit).sort((a, b) => a - b);
        const min = profits[0];
        const max = profits[profits.length-1];
        const buckets = 20;
        const step = max === min ? 100 : (max - min) / buckets;
        
        for(let i=0; i<buckets; i++) {
            const low = min + (i*step);
            const high = min + ((i+1)*step);
            distribution.push({
                range: `${low.toFixed(0)} - ${high.toFixed(0)}`,
                min: low, max: high,
                count: profits.filter(p => p >= low && (i === buckets-1 ? p <= high : p < high)).length
            });
        }
    }

    const daysMap = new Map<string, {count: number, pos: number, profit: number[]}>();
    validRuns.forEach(run => {
        run.entries.forEach(entry => {
            const d = new Date(entry.rollingStart);
            if (!isNaN(d.getTime())) {
                const dayName = d.toLocaleDateString('en-US', { weekday: 'long' });
                if (!daysMap.has(dayName)) daysMap.set(dayName, { count: 0, pos: 0, profit: [] });
                const stat = daysMap.get(dayName)!;
                stat.count++;
                if (entry.netProfit > 0) stat.pos++;
                stat.profit.push(entry.netProfit);
            }
        });
    });

    const weekdayStats: WeekdayStat[] = Array.from(daysMap.entries()).map(([day, data]) => {
        data.profit.sort((a, b) => a - b);
        const sumP = data.profit.reduce((a, b) => a+b, 0);
        return {
            weekday: day,
            count: data.count,
            positiveCount: data.pos,
            winRate: data.count > 0 ? (data.pos / data.count) * 100 : 0,
            meanNetProfit: data.count > 0 ? sumP / data.count : 0,
            medianNetProfit: data.profit[Math.floor(data.profit.length / 2)] || 0,
            profitFactorProxy: 0 
        };
    }).sort((a,b) => {
        const days = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'];
        return days.indexOf(a.weekday) - days.indexOf(b.weekday);
    });

    const grossProfit = validRuns.filter(r => r.totalNetProfit > 0).reduce((sum, r) => sum + r.totalNetProfit, 0);
    const grossLoss = Math.abs(validRuns.filter(r => r.totalNetProfit < 0).reduce((sum, r) => sum + r.totalNetProfit, 0));

    return {
        runs: allRuns,
        weekdayStats,
        edgeMetrics: {
            probabilityOfProfit: validRuns.length ? (positiveRuns.length / validRuns.length) * 100 : 0,
            averageExpectancy: validRuns.reduce((s, r) => s + (r.expectancy || 0), 0) / (validRuns.length || 1),
            profitFactorGlobal: grossLoss > 0 ? grossProfit / grossLoss : grossProfit,
            kellyCriterionProxy: 0,
            distribution
        },
        bestRun: positiveRuns.sort((a, b) => b.profitToDDRatio - a.profitToDDRatio)[0] || null,
        bestNoDDRun: null,
        totalFilesProcessed,
        rejectedFiles,
        debugLog
    };
};

const generateAnalysisInsight = async (data: AnalysisResult): Promise<string> => {
    // API Key must be handled via process.env
    // We assume the Dashboard component has already ensured process.env.API_KEY is populated via user input or config
    if (!process.env.API_KEY) {
        throw new Error("API Key missing. Please configure it in the settings.");
    }

    try {
        const ai = new GoogleGenAI({ apiKey: process.env.API_KEY });
        const prompt = `
            Act as a senior trading system analyst. Analyze this cTrader optimization data.
            
            METRICS:
            - Total Runs: ${data.runs.length}
            - Edge (Prob. of Profit): ${data.edgeMetrics.probabilityOfProfit.toFixed(1)}%
            - Global Profit Factor: ${data.edgeMetrics.profitFactorGlobal.toFixed(2)}
            - Avg Expectancy: $${data.edgeMetrics.averageExpectancy.toFixed(2)}
            - Best Run Profit: $${data.bestRun?.totalNetProfit}
            
            WEEKDAY STATS (Median Profit / Win Rate):
            ${data.weekdayStats.map(w => `- ${w.weekday}: $${w.medianNetProfit.toFixed(0)} / ${w.winRate.toFixed(0)}%`).join('\n')}

            Task: Provide a professional, concise strategic assessment (approx 150 words).
            1. ROBUSTNESS: Is this strategy curve-fitted or robust? (Hint: Look at Profit Factor and Prob of Profit).
            2. ACTIVATION: Is there a specific day to turn it on? Or should it be abandoned?
            3. WARNINGS: Highlight any critical risks (e.g. low win rate, negative expectancy).
        `;

        const response = await ai.models.generateContent({
            model: 'gemini-2.5-flash',
            contents: prompt,
        });
        return response.text || "No analysis generated by AI.";
    } catch (error: any) {
        console.error("AI Gen Error:", error);
        throw error;
    }
};

// ==========================================
// 3. COMPONENTS
// ==========================================

const FileUpload: React.FC<{ onFilesSelected: (files: File[]) => void }> = ({ onFilesSelected }) => {
    const handleFileChange = (event: React.ChangeEvent<HTMLInputElement>) => {
        if (event.target.files && event.target.files.length > 0) {
            onFilesSelected(Array.from(event.target.files));
        }
    };

    return (
        <div className="w-full max-w-2xl mx-auto mt-10 animate-fade-in">
            <label 
                htmlFor="file-upload"
                className="flex flex-col items-center justify-center w-full h-64 border-2 border-dashed rounded-xl cursor-pointer bg-slate-800 border-slate-600 hover:border-blue-500 hover:bg-slate-750 transition-all duration-300 group shadow-lg relative overflow-hidden"
            >
                <div className="absolute inset-0 bg-blue-500/5 opacity-0 group-hover:opacity-100 transition-opacity" />
                <div className="flex flex-col items-center justify-center pt-5 pb-6 text-slate-400 group-hover:text-blue-400 z-10">
                    <div className="bg-slate-700/50 p-4 rounded-full mb-4 group-hover:scale-110 transition-transform duration-300">
                        <UploadCloud className="w-10 h-10" />
                    </div>
                    <p className="mb-2 text-lg font-semibold"><span className="font-bold">Click to upload</span> or drag folder</p>
                    <p className="text-sm text-slate-500 mb-4">Select your "Optimization" folder</p>
                    <div className="flex items-center gap-4 text-xs text-slate-500 bg-slate-900/50 py-2 px-4 rounded-lg border border-slate-700/50">
                        <div className="flex items-center gap-1.5"><ShieldCheck className="w-3.5 h-3.5 text-emerald-500" /><span>Client-Side Secure</span></div>
                        <div className="w-px h-3 bg-slate-700" />
                        <div className="flex items-center gap-1.5"><FileText className="w-3.5 h-3.5" /><span>.txt logs only</span></div>
                    </div>
                </div>
                <input id="file-upload" type="file" className="hidden" multiple 
                    // @ts-ignore 
                    webkitdirectory="" onChange={handleFileChange} accept=".txt,.log" />
            </label>
        </div>
    );
};

const WeekdayPerformanceChart: React.FC<{ data: WeekdayStat[] }> = ({ data }) => {
    return (
        <div className="h-80 w-full">
            <ResponsiveContainer width="100%" height="100%">
                <ComposedChart data={data}>
                    <CartesianGrid strokeDasharray="3 3" stroke="#334155" />
                    <XAxis dataKey="weekday" stroke="#94a3b8" fontSize={12} />
                    <YAxis yAxisId="left" stroke="#94a3b8" />
                    <YAxis yAxisId="right" orientation="right" stroke="#94a3b8" unit="%" />
                    <Tooltip contentStyle={{ backgroundColor: '#1e293b', borderColor: '#475569', color: '#f8fafc' }} />
                    <Legend />
                    <Bar yAxisId="left" dataKey="medianNetProfit" name="Median Profit" fill="#3b82f6" barSize={40} radius={[4, 4, 0, 0]} />
                    <Line yAxisId="right" type="monotone" dataKey="winRate" name="Win Rate" stroke="#10b981" strokeWidth={2} />
                </ComposedChart>
            </ResponsiveContainer>
        </div>
    );
};

const DistributionChart: React.FC<{ data: DistributionBucket[] }> = ({ data }) => {
    return (
        <div className="h-80 w-full">
            <ResponsiveContainer width="100%" height="100%">
                <BarChart data={data}>
                    <CartesianGrid strokeDasharray="3 3" stroke="#334155" />
                    <XAxis dataKey="range" stroke="#94a3b8" fontSize={10} tickFormatter={(v, i) => i%4===0 ? v.split(' - ')[0] : ''} />
                    <YAxis stroke="#94a3b8" />
                    <Tooltip contentStyle={{ backgroundColor: '#1e293b', borderColor: '#475569', color: '#f8fafc' }} cursor={{fill: 'transparent'}} />
                    <Bar dataKey="count" name="Frequency">
                        {data.map((entry, index) => (<Cell key={`cell-${index}`} fill={entry.min < 0 ? '#ef4444' : '#10b981'} />))}
                    </Bar>
                </BarChart>
            </ResponsiveContainer>
        </div>
    );
};

const RunHistoryChart: React.FC<{ run: RunSummary }> = ({ run }) => {
    const data = run.entries.map(e => ({ date: e.rollingStart, profit: e.netProfit })).sort((a, b) => new Date(a.date).getTime() - new Date(b.date).getTime());
    return (
        <div className="h-80 w-full">
            <ResponsiveContainer width="100%" height="100%">
                <LineChart data={data}>
                    <CartesianGrid strokeDasharray="3 3" stroke="#334155" />
                    <XAxis dataKey="date" stroke="#94a3b8" minTickGap={30} />
                    <YAxis stroke="#94a3b8" />
                    <Tooltip contentStyle={{ backgroundColor: '#1e293b', borderColor: '#475569', color: '#f8fafc' }} />
                    <ReferenceLine y={0} stroke="#ef4444" />
                    <Line type="monotone" dataKey="profit" stroke="#8b5cf6" dot={false} strokeWidth={2} />
                </LineChart>
            </ResponsiveContainer>
        </div>
    );
};

const Dashboard: React.FC<{ data: AnalysisResult; onReset: () => void }> = ({ data, onReset }) => {
    const [activeTab, setActiveTab] = useState<'overview' | 'edge' | 'runs'>('overview');
    const [aiSummary, setAiSummary] = useState<string | null>(null);
    const [isLoadingAi, setIsLoadingAi] = useState(false);
    
    // Manage API Key state for UI
    const [apiKey, setApiKey] = useState(() => {
        try {
            return process.env.API_KEY || localStorage.getItem("GEMINI_API_KEY") || "";
        } catch(e) { return ""; }
    });

    const handleSaveKey = (e: React.ChangeEvent<HTMLInputElement>) => {
        const val = e.target.value;
        setApiKey(val);
        try {
            localStorage.setItem("GEMINI_API_KEY", val);
            process.env.API_KEY = val;
        } catch(e) {}
    };

    const handleGenerateAi = async () => {
        setIsLoadingAi(true);
        try {
            const summary = await generateAnalysisInsight(data);
            setAiSummary(summary);
        } catch (e: any) {
            setAiSummary(`Error: ${e.message}. Please check your connection or API Key.`);
        } finally {
            setIsLoadingAi(false);
        }
    };

    const hasKey = !!apiKey && apiKey.length > 5;

    return (
        <div className="w-full max-w-7xl mx-auto p-6 space-y-8">
            <div className="flex flex-col md:flex-row justify-between items-start md:items-center border-b border-slate-700 pb-6 gap-4">
                <div>
                    <h1 className="text-3xl font-bold text-white">Analysis Results</h1>
                    <div className="flex items-center gap-3 text-slate-400 mt-1">
                        <span className="bg-slate-800 px-2 py-0.5 rounded text-xs border border-slate-700 font-mono">{data.totalFilesProcessed} Valid Files</span>
                        {data.rejectedFiles > 0 && <span className="bg-red-900/30 text-red-400 px-2 py-0.5 rounded text-xs border border-red-900/50 font-mono">{data.rejectedFiles} Rejected</span>}
                        <span className="bg-slate-800 px-2 py-0.5 rounded text-xs border border-slate-700 font-mono">{data.runs.length} Runs</span>
                    </div>
                </div>
                <button onClick={onReset} className="px-4 py-2 text-sm font-medium text-slate-300 bg-slate-800 rounded-lg hover:bg-slate-700 transition-colors">New Upload</button>
            </div>

            <div className="grid grid-cols-1 md:grid-cols-4 gap-4">
                <div className="bg-slate-800 p-5 rounded-xl border border-slate-700">
                    <div className="flex items-center gap-3 mb-2 text-emerald-400"><TrendingUp className="w-5 h-5" /><h3 className="font-semibold text-sm">Prob. of Profit</h3></div>
                    <p className="text-2xl font-bold text-white">{data.edgeMetrics.probabilityOfProfit.toFixed(1)}%</p>
                </div>
                <div className="bg-slate-800 p-5 rounded-xl border border-slate-700">
                    <div className="flex items-center gap-3 mb-2 text-blue-400"><Scale className="w-5 h-5" /><h3 className="font-semibold text-sm">Profit Factor</h3></div>
                    <p className="text-2xl font-bold text-white">{data.edgeMetrics.profitFactorGlobal.toFixed(2)}</p>
                </div>
                <div className="bg-slate-800 p-5 rounded-xl border border-slate-700">
                    <div className="flex items-center gap-3 mb-2 text-purple-400"><Sigma className="w-5 h-5" /><h3 className="font-semibold text-sm">Avg Expectancy</h3></div>
                    <p className="text-2xl font-bold text-white">${data.edgeMetrics.averageExpectancy.toFixed(2)}</p>
                </div>
                <div className="bg-slate-800 p-5 rounded-xl border border-slate-700">
                    <div className="flex items-center gap-3 mb-2 text-amber-400"><Trophy className="w-5 h-5" /><h3 className="font-semibold text-sm">Best Run</h3></div>
                    <p className="text-2xl font-bold text-white">${data.bestRun?.totalNetProfit.toFixed(0) || 0}</p>
                </div>
            </div>

            <div className="flex gap-6 border-b border-slate-700 px-1">
                {['overview', 'edge', 'runs'].map(tab => (
                    <button key={tab} onClick={() => setActiveTab(tab as any)} className={`pb-3 font-medium capitalize transition-colors ${activeTab === tab ? 'text-blue-400 border-b-2 border-blue-400' : 'text-slate-400 hover:text-slate-200'}`}>{tab}</button>
                ))}
            </div>

            {activeTab === 'overview' && (
                <div className="grid grid-cols-1 lg:grid-cols-2 gap-6 animate-fade-in">
                    <div className="bg-slate-800 p-6 rounded-xl border border-slate-700">
                        <h3 className="text-lg font-semibold text-white mb-6">Weekday Performance</h3>
                        <WeekdayPerformanceChart data={data.weekdayStats} />
                    </div>
                    <div className="bg-slate-800 p-6 rounded-xl border border-slate-700 flex flex-col">
                        <div className="flex justify-between items-center mb-6">
                            <div className="flex items-center gap-2 text-purple-400"><BrainCircuit className="w-5 h-5" /><h3 className="text-lg font-semibold">AI Insight</h3></div>
                            {hasKey && !aiSummary && (
                                <button onClick={handleGenerateAi} disabled={isLoadingAi} className="px-4 py-2 bg-purple-600 hover:bg-purple-500 text-white text-sm rounded-lg disabled:opacity-50 transition-colors">
                                    {isLoadingAi ? 'Analyzing...' : 'Generate Report'}
                                </button>
                            )}
                        </div>
                        
                        <div className="flex-1 overflow-y-auto max-h-80 text-slate-300 text-sm whitespace-pre-wrap custom-scrollbar p-4 bg-slate-900/50 rounded border border-slate-700/50 leading-relaxed relative">
                            {!hasKey ? (
                                <div className="flex flex-col gap-4 items-center justify-center h-full text-center py-4">
                                    <div className="bg-slate-800 p-3 rounded-full"><Key className="w-6 h-6 text-slate-400" /></div>
                                    <div className="space-y-1">
                                        <p className="text-white font-medium">Gemini API Key Required</p>
                                        <p className="text-xs text-slate-500 max-w-xs mx-auto">Enter your API key below to enable AI analysis. It will be stored securely in your browser's local storage.</p>
                                    </div>
                                    <input 
                                        type="password" 
                                        placeholder="Paste your Gemini API Key here" 
                                        value={apiKey}
                                        onChange={handleSaveKey}
                                        className="w-full max-w-sm bg-slate-800 border border-slate-600 rounded px-4 py-2 text-sm text-white focus:border-purple-500 focus:ring-1 focus:ring-purple-500 outline-none transition-all placeholder:text-slate-600"
                                    />
                                    <div className="text-[10px] text-slate-600">
                                        Don't have a key? <a href="https://aistudio.google.com/app/apikey" target="_blank" rel="noopener noreferrer" className="text-blue-400 hover:text-blue-300 underline">Get one for free from Google AI Studio</a>
                                    </div>
                                </div>
                            ) : isLoadingAi ? (
                                <div className="flex items-center gap-2 text-slate-500"><Loader2 className="w-4 h-4 animate-spin" /> Analyzing data patterns...</div>
                            ) : (
                                aiSummary || <span className="text-slate-500 italic">Ready to analyze. Click generate above.</span>
                            )}
                        </div>
                    </div>
                </div>
            )}

            {activeTab === 'edge' && (
                <div className="space-y-6 animate-fade-in">
                     <div className="bg-slate-800 p-6 rounded-xl border border-slate-700">
                        <h3 className="text-lg font-semibold text-white mb-2">Profit Distribution (Bell Curve)</h3>
                        <DistributionChart data={data.edgeMetrics.distribution} />
                    </div>
                     {data.bestRun && (
                         <div className="bg-slate-800 p-6 rounded-xl border border-slate-700">
                            <h3 className="text-lg font-semibold text-white mb-2">Best Run Equity Curve</h3>
                            <RunHistoryChart run={data.bestRun} />
                        </div>
                    )}
                </div>
            )}

            {activeTab === 'runs' && (
                <div className="bg-slate-800 rounded-xl border border-slate-700 overflow-hidden animate-fade-in">
                    <div className="overflow-x-auto custom-scrollbar">
                        <table className="w-full text-left text-sm text-slate-400">
                            <thead className="bg-slate-900 text-slate-200 font-semibold uppercase text-xs tracking-wider">
                                <tr><th className="p-4">Run ID</th><th className="p-4 text-right">Net Profit</th><th className="p-4 text-right">Profit/DD</th><th className="p-4 text-right">Win Rate</th></tr>
                            </thead>
                            <tbody className="divide-y divide-slate-700">
                                {data.runs.sort((a, b) => b.totalNetProfit - a.totalNetProfit).slice(0, 100).map((run, idx) => (
                                    <tr key={idx} className="hover:bg-slate-750 transition-colors">
                                        <td className="p-4 truncate max-w-xs font-mono text-xs" title={run.id}>{run.id.split('/').pop()}</td>
                                        <td className={`p-4 text-right font-medium ${run.totalNetProfit >= 0 ? 'text-emerald-400' : 'text-rose-400'}`}>${run.totalNetProfit.toFixed(2)}</td>
                                        <td className="p-4 text-right">{run.profitToDDRatio.toFixed(2)}</td>
                                        <td className="p-4 text-right">{run.winRate.toFixed(1)}%</td>
                                    </tr>
                                ))}
                            </tbody>
                        </table>
                    </div>
                </div>
            )}
        </div>
    );
};

class ErrorBoundary extends Component<{ children: ReactNode }, { hasError: boolean, error: Error | null }> {
  constructor(props: { children: ReactNode }) { super(props); this.state = { hasError: false, error: null }; }
  static getDerivedStateFromError(error: Error) { return { hasError: true, error }; }
  render() {
    if (this.state.hasError) {
      return (
        <div className="min-h-screen bg-slate-900 text-slate-200 flex flex-col items-center justify-center p-6">
            <AlertTriangle className="w-16 h-16 text-red-500 mb-4" />
            <h1 className="text-2xl font-bold mb-2">Application Error</h1>
            <pre className="text-red-400 font-mono text-xs bg-slate-800 p-4 rounded mb-4 max-w-2xl overflow-auto border border-red-900/50">{this.state.error?.message}</pre>
            <button onClick={() => window.location.reload()} className="px-4 py-2 bg-blue-600 rounded text-white hover:bg-blue-500">Reload Application</button>
        </div>
      );
    }
    return this.props.children;
  }
}

const AppContent: React.FC = () => {
    const [status, setStatus] = useState<'idle' | 'processing' | 'done'>('idle');
    const [progress, setProgress] = useState<{processed: number, total: number}>({processed: 0, total: 0});
    const [result, setResult] = useState<AnalysisResult | null>(null);
    const [showDebug, setShowDebug] = useState(false);

    const handleFilesSelected = async (files: File[]) => {
        setStatus('processing');
        setTimeout(async () => {
            try {
                const data = await processFiles(files, (processed, total) => {
                    setProgress({ processed, total });
                });
                setResult(data);
                setStatus('done');
            } catch (error) {
                console.error("Processing failed", error);
                setStatus('idle');
                alert("Error processing files.");
            }
        }, 50);
    };

    return (
        <div className="min-h-screen bg-slate-900 text-slate-200 selection:bg-blue-500 selection:text-white font-sans">
            <div className="w-full bg-slate-800/80 border-b border-slate-700/50 backdrop-blur-md sticky top-0 z-50 shadow-lg">
                <div className="max-w-7xl mx-auto px-4 h-16 flex items-center justify-between">
                    <div className="flex items-center gap-2 cursor-pointer" onClick={() => {setStatus('idle'); setResult(null);}}>
                        <div className="w-8 h-8 bg-gradient-to-br from-blue-600 to-cyan-500 rounded-lg flex items-center justify-center shadow-lg shadow-blue-900/20"><span className="font-bold text-white text-lg">c</span></div>
                        <span className="font-bold text-xl tracking-tight text-white hidden md:block">cTrader<span className="text-blue-400 font-light">Analyzer</span></span>
                    </div>
                    <div className="flex items-center gap-3">
                        <div className="text-xs font-mono text-slate-500 bg-slate-800/50 px-2 py-1 rounded border border-slate-700 hidden sm:block">v1.4.3</div>
                    </div>
                </div>
            </div>

            <main className="p-6">
                {status === 'idle' && (
                    <div className="flex flex-col items-center justify-center min-h-[70vh] animate-fade-in">
                        <div className="mb-12 relative group cursor-default">
                            <div className="absolute -inset-1 bg-gradient-to-r from-blue-600 to-cyan-500 rounded-3xl blur opacity-25 group-hover:opacity-50 transition duration-1000 group-hover:duration-200"></div>
                            <div className="relative px-10 py-8 bg-slate-800 ring-1 ring-slate-900/5 rounded-3xl flex items-center gap-6 shadow-2xl transform transition-transform hover:-translate-y-1">
                                <div className="w-20 h-20 rounded-2xl bg-gradient-to-br from-[#0055ff] to-[#00aaff] flex items-center justify-center shadow-inner border border-white/10">
                                     <svg viewBox="0 0 24 24" className="w-12 h-12 text-white fill-current" style={{filter: 'drop-shadow(0 2px 4px rgba(0,0,0,0.3))'}}>
                                        <path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zm-2-5.5l4-2.5-4-2.5v5z" fillOpacity="0" /> 
                                        <path d="M20 12c0-4.41-3.59-8-8-8v16c4.41 0 8-3.59 8-8z" opacity="0.3"/>
                                        <text x="50%" y="50%" textAnchor="middle" dy=".35em" fontSize="18" fontWeight="bold" fontFamily="sans-serif">c</text>
                                     </svg>
                                </div>
                                <div className="flex flex-col">
                                    <h1 className="text-6xl font-bold text-white tracking-tighter leading-none font-sans">cTrader</h1>
                                    <span className="text-2xl text-cyan-400 font-light tracking-[0.3em] uppercase mt-1 pl-1">Analyzer</span>
                                </div>
                            </div>
                        </div>
                        <FileUpload onFilesSelected={handleFilesSelected} />
                    </div>
                )}

                {status === 'processing' && (
                    <div className="flex flex-col items-center justify-center min-h-[70vh] animate-fade-in">
                        <Loader2 className="w-12 h-12 text-blue-500 animate-spin mb-6" />
                        <h2 className="text-xl font-semibold text-white mb-1">Crunching Numbers...</h2>
                        <div className="w-64 h-2 bg-slate-800 rounded-full overflow-hidden border border-slate-700 shadow-inner mt-6">
                            <div className="h-full bg-gradient-to-r from-blue-600 to-cyan-500 transition-all duration-300 ease-out" style={{ width: `${progress.total > 0 ? (progress.processed / progress.total) * 100 : 0}%` }} />
                        </div>
                        <p className="text-xs text-slate-500 mt-3 font-mono">{progress.processed} / {progress.total} files</p>
                    </div>
                )}

                {status === 'done' && result && (
                    <>
                        {result.runs.length === 0 ? (
                            <div className="flex flex-col items-center justify-center min-h-[50vh] text-center">
                                <Bug className="w-16 h-16 text-amber-500 mb-4" />
                                <h2 className="text-2xl font-bold text-white mb-2">No Data Found</h2>
                                <p className="text-slate-400 max-w-md mb-6">Files were read but we couldn't extract any trades or profit data. This usually means the log format is different than expected.</p>
                                <button onClick={() => setShowDebug(!showDebug)} className="text-sm text-blue-400 hover:text-blue-300 underline mb-6">
                                    {showDebug ? "Hide Debug Info" : "Show Debug Info (Send this to support)"}
                                </button>
                                {showDebug && (
                                    <div className="bg-slate-950 p-4 rounded border border-slate-800 text-left font-mono text-xs text-slate-400 w-full max-w-2xl overflow-auto max-h-64 custom-scrollbar">
                                        <div className="font-bold text-slate-300 mb-2 border-b border-slate-800 pb-1">Debug Log (First 5 lines of first file):</div>
                                        {result.debugLog?.map((l, i) => <div key={i} className="break-all border-b border-slate-800/50 py-1">{l}</div>)}
                                    </div>
                                )}
                                <button onClick={() => {setStatus('idle'); setResult(null);}} className="px-6 py-2 bg-slate-800 hover:bg-slate-700 rounded-lg text-white transition-colors mt-4">Try Again</button>
                            </div>
                        ) : (
                            <Dashboard data={result} onReset={() => { setStatus('idle'); setResult(null); }} />
                        )}
                    </>
                )}
            </main>
        </div>
    );
};

const container = document.getElementById('root');
if (container) {
    const root = createRoot(container);
    root.render(<ErrorBoundary><AppContent /></ErrorBoundary>);
}