#!/usr/bin/env python3
import cgi
import sys
sys.path.insert(0, '/opt/ngon/apps')
sys.path.insert(0, '/var/www/html/ngon')
from managers.auth_manager import AuthManager, generate_login_page_html
from links import generate_dropdown_html, generate_dropdown_css, generate_dropdown_js

_form = cgi.FieldStorage()
_auth = AuthManager('miner_trends')
_auth_required, _should_exit, _headers = _auth.require_auth(_form)

if _should_exit:
    print("Content-Type: application/json")
    if _headers:
        print(_headers)
    print("")
    if _auth_required:
        print('{"success": false, "error": "Authentication required"}')
    else:
        print('{"success": true}')
    sys.exit(0)

if _auth_required:
    print("Content-Type: text/html")
    print("")
    print(generate_login_page_html("Miner Trends"))
    sys.exit(0)

_user_access = AuthManager.get_user_access()


"""
Miner Trends Dashboard
Historical analysis of miner performance across all pods with interactive charts and trend analysis.
"""

import cgi
import json
import os
import sqlite3
from datetime import datetime, timedelta
import cgitb
from collections import defaultdict
import statistics

cgitb.enable()

# Configuration
DB_PATH = "/opt/ngon/data/miner_history.db"
MASTER_CONFIG_PATH = "/opt/ngon/config/master_config.json"

def load_pod_to_site_mapping():
    """Load pod-to-site mapping from master config."""
    try:
        with open(MASTER_CONFIG_PATH, 'r') as f:
            master_config = json.load(f)
        
        pod_to_site = {}
        
        for site_name, site_data in master_config.get('sites', {}).items():
            # Check pods directly under the site
            for pod_name in site_data.get('pods', {}):
                pod_to_site[pod_name] = site_name
            
            # Check pods under generator groups
            for group_name, group_data in site_data.get('generator_groups', {}).items():
                for pod_name in group_data.get('pods', {}):
                    pod_to_site[pod_name] = site_name
        
        return pod_to_site
    except Exception as e:
        print(f"<!-- Warning: Could not load pod-to-site mapping: {e} -->")
        return {}

def load_pod_config():
    """Load pod config (miner_count, miner_type) from master_config.json."""
    try:
        with open(MASTER_CONFIG_PATH, 'r') as f:
            config = json.load(f)

        pod_config = {}
        for site_name, site_data in config.get('sites', {}).items():
            for group_name, group_data in site_data.get('generator_groups', {}).items():
                for pod_name, pod_data in group_data.get('pods', {}).items():
                    pod_config[pod_name] = {
                        'miner_count': pod_data.get('miner_count', 0),
                        'miner_type': pod_data.get('miner_type', 'Unknown')
                    }
        return pod_config
    except Exception:
        return {}


def load_historical_from_db(days_back=30):
    """Load historical data from SQLite, returning same format as old JSON loader.

    Returns (list_of_hourly_dicts, error_string_or_None).
    Each dict has 'file_timestamp' (datetime) and 'pods' (dict of pod data).
    """
    pod_config = load_pod_config()
    cutoff = datetime.now() - timedelta(days=days_back)
    cutoff_str = cutoff.strftime('%Y-%m-%dT%H:00:00')
    # Boundary between raw snapshots (recent) and hourly rollups (older)
    raw_cutoff = datetime.now() - timedelta(days=35)
    raw_cutoff_str = raw_cutoff.strftime('%Y-%m-%dT%H:00:00')

    try:
        conn = sqlite3.connect(f'file:{DB_PATH}?immutable=1', uri=True)
        cur = conn.cursor()

        # --- Raw snapshots (recent) — use only the latest snapshot per hour ---
        cur.execute("""
            SELECT
                strftime('%Y-%m-%dT%H:00:00', s.timestamp) as hour,
                s.pod,
                COUNT(*) as miners_online,
                SUM(CASE WHEN s.hs_rt > 0 THEN 1 ELSE 0 END) as miners_hashing,
                SUM(CASE WHEN s.mining_state = 'sleeping' THEN 1 ELSE 0 END) as miners_sleeping,
                SUM(CASE WHEN s.hs_rt = 0 AND (s.mining_state IS NULL OR s.mining_state != 'sleeping') THEN 1 ELSE 0 END) as miners_zero_hashrate,
                SUM(CASE WHEN s.error_codes != '' AND s.error_codes IS NOT NULL THEN 1 ELSE 0 END) as miners_with_errors
            FROM miner_snapshots s
            INNER JOIN (
                SELECT strftime('%Y-%m-%dT%H:00:00', timestamp) as hour,
                       MAX(timestamp) as max_ts
                FROM miner_snapshots
                WHERE timestamp >= ?
                GROUP BY hour
            ) latest ON s.timestamp = latest.max_ts
            GROUP BY hour, s.pod
        """, (cutoff_str,))
        raw_rows = cur.fetchall()

        # --- Hourly rollups (older data, 7-90 days) ---
        hourly_rows = []
        if days_back > 7:
            hourly_cutoff_str = cutoff_str
            cur.execute("""
                SELECT
                    hour, pod,
                    COUNT(*) as miners_online,
                    SUM(CASE WHEN avg_hs_rt > 0 THEN 1 ELSE 0 END) as miners_hashing,
                    SUM(CASE WHEN dominant_state = 'sleeping' THEN 1 ELSE 0 END) as miners_sleeping,
                    SUM(CASE WHEN avg_hs_rt = 0 AND (dominant_state IS NULL OR dominant_state != 'sleeping') THEN 1 ELSE 0 END) as miners_zero_hashrate,
                    SUM(has_errors) as miners_with_errors
                FROM miner_snapshots_hourly
                WHERE hour >= ? AND hour < ?
                GROUP BY hour, pod
            """, (hourly_cutoff_str, raw_cutoff_str))
            hourly_rows = cur.fetchall()

        conn.close()

        if not raw_rows and not hourly_rows:
            return [], "No historical data available in database"

        # Combine into hour -> pod -> data structure
        hours = defaultdict(dict)

        for row in hourly_rows:
            hour, pod, online, hashing, sleeping, zero_hash, with_errors = row
            # online from hourly includes sleeping miners in the count
            non_sleeping_online = online - sleeping
            installed = pod_config.get(pod, {}).get('miner_count', non_sleeping_online)
            miner_type = pod_config.get(pod, {}).get('miner_type', 'Unknown')
            offline = max(0, installed - non_sleeping_online - sleeping)
            pod_status = 'online' if non_sleeping_online > 0 else 'offline'

            hours[hour][pod] = {
                'pod_status': pod_status,
                'miner_type': miner_type,
                'miners_installed': installed,
                'miners_online': non_sleeping_online,
                'miners_hashing': hashing,
                'miners_low_hashrate': 0,
                'miners_zero_hashrate': zero_hash,
                'miners_offline': offline,
                'miners_sleeping': sleeping,
                'miners_with_errors': with_errors or 0,
                'total_error_instances': with_errors or 0,
                'error_summary': {
                    'miners_with_fan_errors': 0,
                    'miners_with_power_errors': 0,
                    'miners_with_temp_sensor_errors': 0,
                    'miners_with_overtemp_protection': 0,
                    'miners_with_hashboard_errors': 0,
                    'miners_with_pool_errors': 0,
                    'miners_with_system_errors': 0,
                }
            }

        for row in raw_rows:
            hour, pod, online, hashing, sleeping, zero_hash, with_errors = row
            non_sleeping_online = online - sleeping
            installed = pod_config.get(pod, {}).get('miner_count', non_sleeping_online)
            miner_type = pod_config.get(pod, {}).get('miner_type', 'Unknown')
            offline = max(0, installed - non_sleeping_online - sleeping)
            pod_status = 'online' if non_sleeping_online > 0 else 'offline'

            hours[hour][pod] = {
                'pod_status': pod_status,
                'miner_type': miner_type,
                'miners_installed': installed,
                'miners_online': non_sleeping_online,
                'miners_hashing': hashing,
                'miners_low_hashrate': 0,
                'miners_zero_hashrate': zero_hash,
                'miners_offline': offline,
                'miners_sleeping': sleeping,
                'miners_with_errors': with_errors or 0,
                'total_error_instances': with_errors or 0,
                'error_summary': {
                    'miners_with_fan_errors': 0,
                    'miners_with_power_errors': 0,
                    'miners_with_temp_sensor_errors': 0,
                    'miners_with_overtemp_protection': 0,
                    'miners_with_hashboard_errors': 0,
                    'miners_with_pool_errors': 0,
                    'miners_with_system_errors': 0,
                }
            }

        # Ensure all configured pods appear in every hour with correct installed count
        offline_pod_template = {
            'pod_status': 'offline',
            'miners_online': 0,
            'miners_hashing': 0,
            'miners_low_hashrate': 0,
            'miners_zero_hashrate': 0,
            'miners_sleeping': 0,
            'miners_with_errors': 0,
            'total_error_instances': 0,
            'error_summary': {
                'miners_with_fan_errors': 0,
                'miners_with_power_errors': 0,
                'miners_with_temp_sensor_errors': 0,
                'miners_with_overtemp_protection': 0,
                'miners_with_hashboard_errors': 0,
                'miners_with_pool_errors': 0,
                'miners_with_system_errors': 0,
            }
        }
        for hour_str, hour_pods in hours.items():
            for pod_name, pc in pod_config.items():
                if pod_name not in hour_pods:
                    hour_pods[pod_name] = {
                        **offline_pod_template,
                        'miner_type': pc['miner_type'],
                        'miners_installed': pc['miner_count'],
                        'miners_offline': pc['miner_count'],
                    }

        # Convert to list of report dicts sorted by timestamp
        historical_data = []
        for hour_str in sorted(hours.keys()):
            try:
                ts = datetime.fromisoformat(hour_str)
            except ValueError:
                continue
            historical_data.append({
                'file_timestamp': ts,
                'pods': hours[hour_str]
            })

        return historical_data, None

    except Exception as e:
        return [], f"Error loading historical data: {str(e)}"

def aggregate_pod_data(historical_data):
    """Aggregate data by pod across all time periods."""
    pod_timeline = defaultdict(list)
    pod_stats = defaultdict(lambda: {
        'hashing_rates': [],
        'offline_counts': [],
        'error_counts': [],
        'installed_counts': [],
        'latest_data': None
    })
    
    for report in historical_data:
        timestamp = report['file_timestamp']
        pods_data = report.get('pods', {})
        
        for pod_name, pod_data in pods_data.items():
            # Timeline data for charts
            pod_timeline[pod_name].append({
                'timestamp': timestamp,
                'miners_hashing': pod_data.get('miners_hashing', 0),
                'miners_offline': pod_data.get('miners_offline', 0),
                'miners_sleeping': pod_data.get('miners_sleeping', 0),
                'miners_zero_hashrate': pod_data.get('miners_zero_hashrate', 0),
                'miners_installed': pod_data.get('miners_installed', 0),
                'total_error_instances': pod_data.get('total_error_instances', 0),
                'pod_status': pod_data.get('pod_status', 'unknown')
            })
            
            # Statistical data
            installed = pod_data.get('miners_installed', 0)
            hashing = pod_data.get('miners_hashing', 0)
            hashing_rate = (hashing / installed * 100) if installed > 0 else 0
            
            pod_stats[pod_name]['hashing_rates'].append(hashing_rate)
            pod_stats[pod_name]['offline_counts'].append(pod_data.get('miners_offline', 0))
            pod_stats[pod_name]['error_counts'].append(pod_data.get('total_error_instances', 0))
            pod_stats[pod_name]['installed_counts'].append(installed)
            pod_stats[pod_name]['latest_data'] = pod_data
    
    return dict(pod_timeline), dict(pod_stats)

def calculate_pod_metrics(pod_stats, pod_timeline):
    """Calculate statistical metrics for each pod."""
    metrics = {}
    
    for pod_name, stats in pod_stats.items():
        if not stats['hashing_rates']:
            continue
            
        hashing_rates = stats['hashing_rates']
        offline_counts = stats['offline_counts']
        error_counts = stats['error_counts']
        
        # Calculate averages and trends
        current_rate = hashing_rates[-1] if hashing_rates else 0
        avg_24h = statistics.mean(hashing_rates[-24:]) if len(hashing_rates) >= 24 else statistics.mean(hashing_rates)
        avg_7d = statistics.mean(hashing_rates[-168:]) if len(hashing_rates) >= 168 else statistics.mean(hashing_rates)
        
        # Trend calculation (last 24h vs previous 24h)
        if len(hashing_rates) >= 48:
            recent_avg = statistics.mean(hashing_rates[-24:])
            prev_avg = statistics.mean(hashing_rates[-48:-24])
            trend_direction = "improving" if recent_avg > prev_avg else "declining" if recent_avg < prev_avg else "stable"
            trend_change = recent_avg - prev_avg
        else:
            trend_direction = "insufficient_data"
            trend_change = 0
        
        # Calculate machine health metrics
        latest = stats['latest_data']
        current_hashing = latest.get('miners_hashing', 0)
        current_sleeping = latest.get('miners_sleeping', 0)
        current_installed = latest.get('miners_installed', 0)
        
        # Get timeline data and filter to operational periods (miners actively hashing)
        timeline_data = pod_timeline.get(pod_name, [])
        # Use a higher threshold - need significant hashing activity to be considered "operational"
        hashing_points = [point for point in timeline_data if point['miners_hashing'] >= 50]
        
        # Find peak performance period and problems at that specific time
        if hashing_points:
            # Find the point with maximum hashing (peak performance)
            peak_point = max(hashing_points, key=lambda x: x['miners_hashing'])
            peak_hashing = peak_point['miners_hashing']
            
            # Get the problems at that exact peak moment
            peak_zero_hash = peak_point.get('miners_zero_hashrate', 0)
            peak_offline = peak_point.get('miners_offline', 0)
            
            hashing_data_points = len(hashing_points)
        else:
            # No significant hashing history - use current values if currently hashing
            peak_hashing = current_hashing
            peak_zero_hash = latest.get('miners_zero_hashrate', 0)
            peak_offline = latest.get('miners_offline', 0)
            hashing_data_points = 1 if current_hashing >= 50 else 0
        
        # Calculate averages only from hashing periods
        if timeline_data:
            hashing_periods = [point for point in timeline_data if point['miners_hashing'] > 0]
            if hashing_periods:
                avg_offline = statistics.mean([point.get('miners_offline', 0) for point in hashing_periods])
                avg_zero_hash = statistics.mean([point.get('miners_zero_hashrate', 0) for point in hashing_periods])
            else:
                avg_offline = latest.get('miners_offline', 0)
                avg_zero_hash = latest.get('miners_zero_hashrate', 0)
        else:
            avg_offline = latest.get('miners_offline', 0)
            avg_zero_hash = latest.get('miners_zero_hashrate', 0)
        
        metrics[pod_name] = {
            'current_hashing_rate': current_rate,
            'avg_24h': avg_24h,
            'avg_7d': avg_7d,
            'trend_direction': trend_direction,
            'trend_change': trend_change,
            'latest_data': stats['latest_data'],
            'data_points': hashing_data_points,
            'min_rate': min(hashing_rates) if hashing_rates else 0,
            'max_rate': max(hashing_rates) if hashing_rates else 0,
            'peak_hashing': peak_hashing,
            'peak_offline': peak_offline,
            'peak_zero_hash': peak_zero_hash,
            'avg_offline': avg_offline,
            'avg_zero_hash': avg_zero_hash,
            'current_installed': current_installed
        }
    
    return metrics

def calculate_site_metrics(pod_metrics, pod_to_site):
    """Calculate site-level aggregated metrics from pod metrics."""
    site_metrics = defaultdict(lambda: {
        'pods': [],
        'total_installed': 0,
        'total_peak_hashing': 0,
        'total_peak_offline': 0,
        'total_peak_zero_hash': 0,
        'total_data_points': 0,
        'avg_hashing_rate': 0
    })
    
    # Group pods by site
    for pod_name, metrics in pod_metrics.items():
        site_name = pod_to_site.get(pod_name, 'Unknown Site')
        
        site_metrics[site_name]['pods'].append(pod_name)
        site_metrics[site_name]['total_installed'] += metrics['current_installed']
        site_metrics[site_name]['total_peak_hashing'] += metrics['peak_hashing']
        site_metrics[site_name]['total_peak_offline'] += metrics['peak_offline']
        site_metrics[site_name]['total_peak_zero_hash'] += metrics['peak_zero_hash']
        site_metrics[site_name]['total_data_points'] += metrics['data_points']
    
    # Calculate averages
    for site_name, site_data in site_metrics.items():
        pod_count = len(site_data['pods'])
        if pod_count > 0:
            # Calculate average hashing rate across pods in site
            hashing_rates = [pod_metrics[pod]['current_hashing_rate'] for pod in site_data['pods']]
            site_data['avg_hashing_rate'] = statistics.mean(hashing_rates)
            site_data['avg_data_points'] = site_data['total_data_points'] / pod_count
            site_data['pod_count'] = pod_count
    
    return dict(site_metrics)

def render_site_summary(site_metrics):
    """Render the site-level summary table."""
    if not site_metrics:
        return ""
    
    html = """
    <div class="section">
        <h2>Site Summary</h2>
        <table class="fleet-table">
            <thead>
                <tr>
                    <th>Site Name</th>
                    <th>Pods</th>
                    <th>Total Installed</th>
                    <th>Peak Hashing</th>
                    <th>Peak Offline</th>
                    <th>Peak Zero Hash</th>
                    <th>Avg Hashing Rate</th>
                </tr>
            </thead>
            <tbody>
    """
    
    # Sort sites alphabetically by name
    sorted_sites = sorted(site_metrics.items(), key=lambda x: x[0])
    
    for site_name, metrics in sorted_sites:
        avg_rate = metrics['avg_hashing_rate']
        
        # Status classification based on average hashing rate
        if avg_rate >= 90:
            status_class = "good"
        elif avg_rate >= 80:
            status_class = "warning"
        elif avg_rate >= 70:
            status_class = "warning"
        else:
            status_class = "critical"
        
        # Color code based on problems at peak
        offline_class = "critical" if metrics['total_peak_offline'] >= 50 else "warning" if metrics['total_peak_offline'] >= 25 else ""
        zero_class = "critical" if metrics['total_peak_zero_hash'] >= 50 else "warning" if metrics['total_peak_zero_hash'] >= 25 else ""
        
        html += f"""
            <tr class="pod-row {status_class}">
                <td class="pod-name">{site_name}</td>
                <td class="installed">{metrics['pod_count']}</td>
                <td class="installed">{metrics['total_installed']}</td>
                <td class="peak-hashing">{metrics['total_peak_hashing']}</td>
                <td class="peak-minus {offline_class}">{metrics['total_peak_offline']}</td>
                <td class="peak-minus {zero_class}">{metrics['total_peak_zero_hash']}</td>
                <td class="hash-rate">{avg_rate:.1f}%</td>
            </tr>
        """
    
    # Calculate totals
    total_pods = sum(metrics['pod_count'] for metrics in site_metrics.values())
    total_installed = sum(metrics['total_installed'] for metrics in site_metrics.values())
    total_peak_hashing = sum(metrics['total_peak_hashing'] for metrics in site_metrics.values())
    total_peak_offline = sum(metrics['total_peak_offline'] for metrics in site_metrics.values())
    total_peak_zero_hash = sum(metrics['total_peak_zero_hash'] for metrics in site_metrics.values())
    
    # Calculate overall average hashing rate (weighted by number of sites)
    total_avg_rate = statistics.mean([metrics['avg_hashing_rate'] for metrics in site_metrics.values()]) if site_metrics else 0
    
    # Color code totals based on overall averages
    total_offline_class = "critical" if total_peak_offline >= 100 else "warning" if total_peak_offline >= 50 else ""
    total_zero_class = "critical" if total_peak_zero_hash >= 100 else "warning" if total_peak_zero_hash >= 50 else ""
    
    html += f"""
                <tr class="total-row" style="border-top: 2px solid #00ff00; background-color: rgba(0, 255, 0, 0.08); font-weight: bold;">
                    <td class="pod-name">TOTAL</td>
                    <td class="installed">{total_pods}</td>
                    <td class="installed">{total_installed}</td>
                    <td class="peak-hashing">{total_peak_hashing}</td>
                    <td class="peak-minus {total_offline_class}">{total_peak_offline}</td>
                    <td class="peak-minus {total_zero_class}">{total_peak_zero_hash}</td>
                    <td class="hash-rate">{total_avg_rate:.1f}%</td>
                </tr>
            </tbody>
        </table>
    </div>
    """
    
    return html

def render_fleet_overview(pod_metrics):
    """Render the fleet overview table."""
    html = """
    <div class="section">
        <h2>Fleet Overview</h2>
        <table class="fleet-table">
            <thead>
                <tr>
                    <th>Pod Name</th>
                    <th>Installed</th>
                    <th>Peak Hashing</th>
                    <th>Peak - Offline</th>
                    <th>Peak - Zero Hash</th>
                    <th>Data Points</th>
                </tr>
            </thead>
            <tbody>
    """
    
    # Sort pods alphabetically by name
    sorted_pods = sorted(pod_metrics.items(), key=lambda x: x[0])
    
    for pod_name, metrics in sorted_pods:
        trend_class = "trend-" + metrics['trend_direction'].replace("_", "-")
        
        # Improved status classification considering both current rate and trend
        current_rate = metrics['current_hashing_rate']
        trend_dir = metrics['trend_direction']
        
        if current_rate >= 90:
            status_class = "good"
        elif current_rate >= 80:
            # If trending up from decent rate, make it good
            status_class = "good" if trend_dir == "improving" else "warning"
        elif current_rate >= 70:
            status_class = "warning"
        elif current_rate >= 50:
            # If trending up from low rate, make it warning instead of critical
            status_class = "warning" if trend_dir == "improving" else "critical"
        else:
            status_class = "critical"
        
        # Show the problematic counts at peak time
        peak_offline_count = metrics['peak_offline']
        peak_zero_count = metrics['peak_zero_hash']
        
        # Color code based on how many machines were problematic at peak
        offline_class = "critical" if peak_offline_count >= 20 else "warning" if peak_offline_count >= 10 else ""
        zero_class = "critical" if peak_zero_count >= 20 else "warning" if peak_zero_count >= 10 else ""
        
        html += f"""
            <tr class="pod-row {status_class}" onclick="selectPod('{pod_name}')">
                <td class="pod-name">{pod_name}</td>
                <td class="installed">{metrics['current_installed']}</td>
                <td class="peak-hashing">{metrics['peak_hashing']}</td>
                <td class="peak-minus {offline_class}">{peak_offline_count}</td>
                <td class="peak-minus {zero_class}">{peak_zero_count}</td>
                <td>{metrics['data_points']}</td>
            </tr>
        """
    
    html += """
            </tbody>
        </table>
    </div>
    """
    
    return html

def render_timeline_chart(pod_timeline):
    """Render the interactive timeline chart."""
    # Prepare data for Chart.js
    chart_data = {}
    
    for pod_name, timeline in pod_timeline.items():
        chart_data[pod_name] = {
            'timestamps': [point['timestamp'].strftime('%Y-%m-%d %H:00') for point in timeline],
            'hashing': [point['miners_hashing'] for point in timeline],
            'offline': [point['miners_offline'] for point in timeline],
            'sleeping': [point['miners_sleeping'] for point in timeline],
            'zero_hash': [point['miners_zero_hashrate'] for point in timeline],
            'installed': [point['miners_installed'] for point in timeline]
        }
    
    html = f"""
    <div class="section chart-section">
        <h2>Pod Timeline Analysis</h2>
        <div class="chart-controls">
            <label for="podSelect">Select Pod:</label>
            <select id="podSelect" onchange="updateChart()">
                <option value="">Choose a pod...</option>
                {"".join(f'<option value="{pod}">{pod}</option>' for pod in sorted(chart_data.keys()))}
            </select>
            <label class="checkbox-label" style="margin-left: 20px; display: inline-flex; align-items: center; cursor: pointer;">
                <input type="checkbox" id="onlineOnly" onchange="updateChart()" style="margin-right: 6px;">
                <span>Only show when online</span>
            </label>
            <div class="chart-legend">
                <span class="legend-item hashing">■ Hashing</span>
                <span class="legend-item offline">■ Offline</span>
                <span class="legend-item sleeping">■ Sleeping</span>
                <span class="legend-item zero-hash">■ Zero Hash</span>
                <span class="legend-item installed">— Installed</span>
            </div>
        </div>
        <div class="chart-container">
            <canvas id="timelineChart"></canvas>
        </div>
    </div>
    
    <script>
        const chartData = {json.dumps(chart_data)};
        let chart = null;
        
        function selectPod(podName) {{
            document.getElementById('podSelect').value = podName;
            updateChart();
        }}
        
        function updateChart() {{
            const selectedPod = document.getElementById('podSelect').value;
            if (!selectedPod || !chartData[selectedPod]) return;

            const rawData = chartData[selectedPod];
            const onlineOnly = document.getElementById('onlineOnly').checked;

            // Filter data if "only online" is checked
            let filteredIndices = [];
            if (onlineOnly) {{
                for (let i = 0; i < rawData.hashing.length; i++) {{
                    if (rawData.hashing[i] > 0) {{
                        filteredIndices.push(i);
                    }}
                }}
            }} else {{
                filteredIndices = rawData.hashing.map((_, i) => i);
            }}

            const data = {{
                timestamps: filteredIndices.map(i => rawData.timestamps[i]),
                hashing: filteredIndices.map(i => rawData.hashing[i]),
                offline: filteredIndices.map(i => rawData.offline[i]),
                sleeping: filteredIndices.map(i => rawData.sleeping[i]),
                zero_hash: filteredIndices.map(i => rawData.zero_hash[i]),
                installed: filteredIndices.map(i => rawData.installed[i])
            }};

            if (chart) {{
                chart.destroy();
            }}

            const ctx = document.getElementById('timelineChart').getContext('2d');
            chart = new Chart(ctx, {{
                type: 'line',
                data: {{
                    labels: data.timestamps,
                    datasets: [
                        {{
                            label: 'Miners Hashing',
                            data: data.hashing,
                            borderColor: '#28a745',
                            backgroundColor: 'rgba(40, 167, 69, 0.1)',
                            fill: false,
                            tension: 0.1
                        }},
                        {{
                            label: 'Miners Offline',
                            data: data.offline,
                            borderColor: '#dc3545',
                            backgroundColor: 'rgba(220, 53, 69, 0.1)',
                            fill: false,
                            tension: 0.1
                        }},
                        {{
                            label: 'Miners Sleeping',
                            data: data.sleeping,
                            borderColor: '#6f42c1',
                            backgroundColor: 'rgba(111, 66, 193, 0.1)',
                            fill: false,
                            tension: 0.1
                        }},
                        {{
                            label: 'Zero Hash',
                            data: data.zero_hash,
                            borderColor: '#fd7e14',
                            backgroundColor: 'rgba(253, 126, 20, 0.1)',
                            fill: false,
                            tension: 0.1
                        }},
                        {{
                            label: 'Installed',
                            data: data.installed,
                            borderColor: '#6c757d',
                            borderDash: [5, 5],
                            fill: false,
                            tension: 0.1
                        }}
                    ]
                }},
                options: {{
                    responsive: true,
                    maintainAspectRatio: false,
                    interaction: {{
                        intersect: false,
                        mode: 'index'
                    }},
                    scales: {{
                        y: {{
                            beginAtZero: true,
                            title: {{
                                display: true,
                                text: 'Miner Count'
                            }}
                        }},
                        x: {{
                            title: {{
                                display: true,
                                text: 'Time'
                            }},
                            ticks: {{
                                maxTicksLimit: 20,
                                autoSkip: true
                            }}
                        }}
                    }},
                    elements: {{
                        point: {{
                            radius: 2,
                            hoverRadius: 4
                        }},
                        line: {{
                            borderWidth: 2
                        }}
                    }},
                    plugins: {{
                        title: {{
                            display: true,
                            text: selectedPod + ' - Miner Status Timeline'
                        }},
                        tooltip: {{
                            mode: 'index',
                            intersect: false
                        }},
                        legend: {{
                            display: true,
                            position: 'top'
                        }}
                    }}
                }}
            }});
        }}
    </script>
    """
    
    return html

def main():
    print("Content-Type: text/html\n")
    
    form = cgi.FieldStorage()
    days_back = int(form.getvalue('days', '7'))
    export_format = form.getvalue('export', '')
    
    # Load and process data
    historical_data, error = load_historical_from_db(days_back)
    
    if error:
        print(f"<html><body><h1>Error: {error}</h1></body></html>")
        return
    
    if not historical_data:
        print("<html><body><h1>No historical data available</h1></body></html>")
        return
    
    # Process data
    pod_timeline, pod_stats = aggregate_pod_data(historical_data)
    pod_metrics = calculate_pod_metrics(pod_stats, pod_timeline)
    
    # Load pod-to-site mapping and calculate site metrics
    pod_to_site = load_pod_to_site_mapping()
    site_metrics = calculate_site_metrics(pod_metrics, pod_to_site)
    
    # Handle CSV export
    if export_format == 'csv':
        print("""
<!DOCTYPE html>
<html>
<head>
    <title>Miner Trends CSV Export</title>
    <style>
        body { font-family: monospace; padding: 20px; }
        .csv-data { 
            background: #f5f5f5; 
            padding: 15px; 
            border: 1px solid #ddd; 
            white-space: pre;
            font-size: 14px;
        }
        .instructions {
            margin-bottom: 20px;
            padding: 10px;
            background: #e7f3ff;
            border: 1px solid #b3d9ff;
        }
    </style>
</head>
<body>
    <h1>Miner Trends CSV Data</h1>
    
    <div class="instructions">
        <strong>Instructions:</strong> Select all the text in the box below, copy it (Ctrl+C), then paste it into Google Sheets.
    </div>
    
    <div class="csv-data">Pod,Site,Installed,Peak_Hashing,Peak_Offline,Peak_Zero_Hash,Data_Points""")
        
        for pod_name, metrics in sorted(pod_metrics.items()):
            site_name = pod_to_site.get(pod_name, 'Unknown')
            print(f"{pod_name},{site_name},{metrics['current_installed']},{metrics['peak_hashing']},{metrics['peak_offline']},{metrics['peak_zero_hash']},{metrics['data_points']}")
        
        # Add site summary section
        print("\n\nSite Summary:")
        print("Site,Pods,Total_Installed,Peak_Hashing,Peak_Offline,Peak_Zero_Hash,Avg_Hashing_Rate")
        for site_name, metrics in sorted(site_metrics.items()):
            print(f"{site_name},{metrics['pod_count']},{metrics['total_installed']},{metrics['total_peak_hashing']},{metrics['total_peak_offline']},{metrics['total_peak_zero_hash']},{metrics['avg_hashing_rate']:.1f}")
        
        # Add totals row
        total_pods = sum(metrics['pod_count'] for metrics in site_metrics.values())
        total_installed = sum(metrics['total_installed'] for metrics in site_metrics.values())
        total_peak_hashing = sum(metrics['total_peak_hashing'] for metrics in site_metrics.values())
        total_peak_offline = sum(metrics['total_peak_offline'] for metrics in site_metrics.values())
        total_peak_zero_hash = sum(metrics['total_peak_zero_hash'] for metrics in site_metrics.values())
        total_avg_rate = statistics.mean([metrics['avg_hashing_rate'] for metrics in site_metrics.values()]) if site_metrics else 0
        print(f"TOTAL,{total_pods},{total_installed},{total_peak_hashing},{total_peak_offline},{total_peak_zero_hash},{total_avg_rate:.1f}")
        
        print("""</div>
</body>
</html>""")
        return
    
    # Render HTML
    print(f"""
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Miner Trends - NGON Mining</title>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css">
    <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
    <style>
        {generate_dropdown_css()}

        body {{
            font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
            margin: 0;
            padding: 0;
            background-color: #1a1a1a;
            color: #e0e0e0;
            line-height: 1.4;
        }}

        /* Floating-box header (matches status/gen_manager) */
        .header {{
            background-color: rgba(255,255,255,0.05) !important;
            border: 1px solid rgba(255,255,255,0.1) !important;
            border-radius: 8px !important;
            padding: 30px !important;
            margin: 20px !important;
            display: flex !important;
            justify-content: space-between !important;
            align-items: flex-start !important;
            border-bottom: none !important;
        }}
        .header h1.dropdown-title {{
            font-size: 2.2em !important;
            font-weight: 600 !important;
            margin: 3px 0 0 0 !important;
            line-height: 1.2 !important;
            color: #00ff00 !important;
        }}
        .header .subtitle {{
            margin: 6px 0 0 0;
            color: #888;
            font-size: 14px;
        }}

        .controls {{
            background-color: rgba(255,255,255,0.05);
            border: 1px solid rgba(255,255,255,0.1);
            border-radius: 8px;
            padding: 15px;
            margin: 0 20px 20px 20px;
            display: flex;
            gap: 15px;
            align-items: center;
            flex-wrap: wrap;
            color: #e0e0e0;
        }}
        .controls label {{ color: #888; font-size: 12px; }}
        .controls select, .controls input[type="text"] {{
            padding: 8px 12px;
            border: 1px solid #3a3a3a;
            border-radius: 4px;
            background: #2a2a2a;
            color: #e0e0e0;
            font-size: 13px;
        }}
        .controls button {{
            padding: 8px 14px;
            background: #00ff00;
            color: #000;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            font-weight: 600;
            font-size: 13px;
        }}
        .controls button:hover {{ background: #00cc00; }}
        .controls span {{ color: #888; font-size: 12px; }}

        .section {{
            background-color: rgba(255,255,255,0.05);
            border: 1px solid rgba(255,255,255,0.1);
            border-radius: 8px;
            padding: 20px;
            margin: 0 20px 20px 20px;
            color: #e0e0e0;
        }}
        .section.chart-section {{
            margin-left: 20px;
            margin-right: 20px;
            padding: 20px;
            max-width: none;
        }}
        .section h2 {{
            margin-top: 0;
            color: #00ff00;
            border-bottom: 1px solid rgba(255,255,255,0.15);
            padding-bottom: 10px;
        }}

        .fleet-table {{
            width: 100%;
            border-collapse: collapse;
            margin-top: 15px;
            color: #e0e0e0;
        }}
        .fleet-table th {{
            background: rgba(0, 255, 0, 0.1);
            color: #00ff00;
            padding: 12px 8px;
            text-align: center;
            font-weight: 600;
            font-size: 12px;
            text-transform: uppercase;
            vertical-align: middle;
            border-bottom: 1px solid rgba(255,255,255,0.1);
        }}
        .fleet-table th:first-child {{ text-align: left; }}
        .fleet-table td {{
            padding: 10px 8px;
            border-bottom: 1px solid rgba(255,255,255,0.05);
            text-align: center;
            vertical-align: middle;
            color: #e0e0e0;
        }}
        .fleet-table td:first-child {{ text-align: left; }}

        .pod-row {{
            cursor: pointer;
            transition: background-color 0.2s;
        }}
        .pod-row:hover    {{ background-color: rgba(255,255,255,0.05); }}
        .pod-row.critical {{ background-color: rgba(220, 53, 69, 0.18); }}
        .pod-row.warning  {{ background-color: rgba(255, 193, 7, 0.15); }}
        .pod-row.good     {{ background-color: rgba(40, 167, 69, 0.15); }}

        .pod-name {{ font-weight: 600; color: #e0e0e0; }}
        .hash-rate, .peak-hashing, .installed {{ font-weight: 600; text-align: center; }}

        .trend-improving {{ color: #00ff00; font-weight: 600; }}
        .trend-declining {{ color: #ff4444; font-weight: 600; }}
        .trend-stable    {{ color: #888; }}

        .peak-minus {{ font-weight: 600; text-align: center; }}
        .peak-minus.warning  {{ color: #ffaa00; }}
        .peak-minus.critical {{ color: #ff4444; }}

        .chart-controls {{
            margin-bottom: 20px;
            display: flex;
            gap: 20px;
            align-items: center;
            flex-wrap: wrap;
            color: #e0e0e0;
        }}
        .chart-legend {{ display: flex; gap: 15px; }}
        .legend-item {{ font-size: 12px; }}
        .legend-item.hashing   {{ color: #00ff00; }}
        .legend-item.offline   {{ color: #ff4444; }}
        .legend-item.sleeping  {{ color: #4a9eff; }}
        .legend-item.zero-hash {{ color: #ff6600; }}
        .legend-item.installed {{ color: #888; }}

        .chart-container {{
            height: 500px;
            width: 100%;
            position: relative;
        }}

        .summary-stats {{
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
            gap: 15px;
            margin-bottom: 20px;
        }}
        .stat-card {{
            background-color: rgba(255,255,255,0.08);
            border: 1px solid rgba(255,255,255,0.1);
            border-radius: 6px;
            padding: 15px;
            text-align: center;
        }}
        .stat-card h3 {{
            margin: 0 0 5px 0;
            font-size: 12px;
            color: #888;
            text-transform: uppercase;
            font-weight: 600;
        }}
        .stat-card .value {{
            font-size: 24px;
            font-weight: bold;
            color: #00ff00;
        }}

        .timestamp {{
            text-align: center;
            color: #666 !important;
            margin: 20px;
            font-size: 12px;
        }}

        @media (max-width: 768px) {{
            .fleet-table {{ font-size: 12px; }}
            .fleet-table th,
            .fleet-table td {{ padding: 6px 4px; }}
            .controls {{ flex-direction: column; align-items: stretch; }}
        }}
    </style>
</head>
<body>
    <div class="header">
        <div>
            <div class="dropdown">
                <h1 class="dropdown-title">NGON Mining - Miner Trends</h1>
                <div class="dropdown-content">{generate_dropdown_html(_user_access)}</div>
            </div>
            <div class="subtitle">Historical analysis and performance trends across all mining pods</div>
        </div>
    </div>

    <div class="controls">
        <form method="get" style="display: flex; gap: 10px; align-items: center;">
            <label for="days">Time Period:</label>
            <select name="days" id="days">
                <option value="1" {"selected" if days_back == 1 else ""}>Last 24 Hours</option>
                <option value="3" {"selected" if days_back == 3 else ""}>Last 3 Days</option>
                <option value="7" {"selected" if days_back == 7 else ""}>Last 7 Days</option>
                <option value="14" {"selected" if days_back == 14 else ""}>Last 14 Days</option>
                <option value="30" {"selected" if days_back == 30 else ""}>Last 30 Days</option>
            </select>
            <button type="submit">Update</button>
        </form>
        
        <form method="get" style="display: flex; gap: 10px;" target="_blank">
            <input type="hidden" name="days" value="{days_back}">
            <input type="hidden" name="export" value="csv">
            <button type="submit">Export CSV</button>
        </form>
        
        <span>Showing {len(historical_data)} data points over {days_back} days</span>
    </div>
    """)
    
    # Summary statistics
    total_pods = len(pod_metrics)
    good_pods = sum(1 for m in pod_metrics.values() if m['current_hashing_rate'] >= 90)
    problem_pods = sum(1 for m in pod_metrics.values() if m['current_hashing_rate'] < 80)
    avg_fleet_rate = statistics.mean([m['current_hashing_rate'] for m in pod_metrics.values()]) if pod_metrics else 0
    
    print(f"""
    <div class="summary-stats">
        <div class="stat-card">
            <h3>Total Pods</h3>
            <div class="value">{total_pods}</div>
        </div>
        <div class="stat-card">
            <h3>Performing Well</h3>
            <div class="value">{good_pods}</div>
        </div>
        <div class="stat-card">
            <h3>With Problems</h3>
            <div class="value">{problem_pods}</div>
        </div>
        <div class="stat-card">
            <h3>Fleet Average</h3>
            <div class="value">{avg_fleet_rate:.1f}%</div>
        </div>
    </div>
    """)
    
    # Render main sections
    print(render_site_summary(site_metrics))
    print(render_fleet_overview(pod_metrics))
    print(render_timeline_chart(pod_timeline))
    
    print(f"""
    <div class="timestamp">
        Analysis generated: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')} |
        Data range: {historical_data[0]['file_timestamp'].strftime('%Y-%m-%d %H:00')} to {historical_data[-1]['file_timestamp'].strftime('%Y-%m-%d %H:00')}
    </div>
    <script>{generate_dropdown_js()}</script>
</body>
</html>
    """)

if __name__ == "__main__":
    main()