import { html, css, cssManager } from '@design.estate/dees-element';
import type { DeesChartArea } from './component.js';
import '@design.estate/dees-wcctools/demotools';
import './component.js';

export const demoFunc = () => {
  // Initial dataset values
  const initialDatasets = {
    system: {
      label: 'System Usage (%)',
      series: [
        {
          name: 'CPU',
          data: [
            { x: new Date(Date.now() - 300000).toISOString(), y: 25 },
            { x: new Date(Date.now() - 240000).toISOString(), y: 30 },
            { x: new Date(Date.now() - 180000).toISOString(), y: 28 },
            { x: new Date(Date.now() - 120000).toISOString(), y: 35 },
            { x: new Date(Date.now() - 60000).toISOString(), y: 32 },
            { x: new Date().toISOString(), y: 38 },
          ],
        },
        {
          name: 'Memory',
          data: [
            { x: new Date(Date.now() - 300000).toISOString(), y: 45 },
            { x: new Date(Date.now() - 240000).toISOString(), y: 48 },
            { x: new Date(Date.now() - 180000).toISOString(), y: 46 },
            { x: new Date(Date.now() - 120000).toISOString(), y: 52 },
            { x: new Date(Date.now() - 60000).toISOString(), y: 50 },
            { x: new Date().toISOString(), y: 55 },
          ],
        },
      ],
    },
  };
  
  const initialFormatters = {
    system: (val: number) => `${val}%`,
  };
  
  return html`
    <dees-demowrapper .runAfterRender=${async (elementArg: HTMLElement) => {
      // Get the chart elements
      const chartElement = elementArg.querySelector('#main-chart') as DeesChartArea;
      const connectionsChartElement = elementArg.querySelector('#connections-chart') as DeesChartArea;
      let intervalId: number;
      let connectionsIntervalId: number;
      let currentDataset = 'system';

      // Y-axis formatters for different datasets
      const formatters = {
        system: (val: number) => `${val}%`,
        network: (val: number) => `${val} Mbps`,
        sales: (val: number) => `$${val.toLocaleString()}`,
      };
      
      // Time window configuration (in milliseconds)
      const TIME_WINDOW = 2 * 60 * 1000; // 2 minutes
      const UPDATE_INTERVAL = 1000; // 1 second
      const DATA_POINT_INTERVAL = 5000; // Show data points every 5 seconds
      
      // Store previous values for smooth transitions
      let previousValues = {
        cpu: 30,
        memory: 50,
        download: 150,
        upload: 30,
        connections: 150
      };

      // Generate initial data points for time window
      const generateInitialData = (baseValue: number, variance: number, interval: number = DATA_POINT_INTERVAL) => {
        const data = [];
        const now = Date.now();
        const pointCount = Math.floor(TIME_WINDOW / interval);
        
        for (let i = pointCount; i >= 0; i--) {
          const timestamp = new Date(now - (i * interval)).toISOString();
          const value = baseValue + (Math.random() - 0.5) * variance;
          data.push({ x: timestamp, y: Math.round(value) });
        }
        return data;
      };
      
      // Different datasets to showcase
      const datasets = {
        system: {
          label: 'System Usage (%)',
          series: [
            {
              name: 'CPU',
              data: generateInitialData(previousValues.cpu, 10),
            },
            {
              name: 'Memory',
              data: generateInitialData(previousValues.memory, 8),
            },
          ],
        },
        network: {
          label: 'Network Traffic (Mbps)',
          series: [
            {
              name: 'Download',
              data: generateInitialData(previousValues.download, 30),
            },
            {
              name: 'Upload',
              data: generateInitialData(previousValues.upload, 10),
            },
          ],
        },
        sales: {
          label: 'Sales Analytics',
          series: [
            {
              name: 'Revenue',
              data: [
                { x: '2025-01-01', y: 45000 },
                { x: '2025-01-02', y: 52000 },
                { x: '2025-01-03', y: 48000 },
                { x: '2025-01-04', y: 61000 },
                { x: '2025-01-05', y: 58000 },
                { x: '2025-01-06', y: 65000 },
              ],
            },
            {
              name: 'Profit',
              data: [
                { x: '2025-01-01', y: 12000 },
                { x: '2025-01-02', y: 14000 },
                { x: '2025-01-03', y: 11000 },
                { x: '2025-01-04', y: 18000 },
                { x: '2025-01-05', y: 16000 },
                { x: '2025-01-06', y: 20000 },
              ],
            },
          ],
        },
      };

      // Generate smooth value transitions
      const getNextValue = (current: number, min: number, max: number, maxChange: number = 5) => {
        // Add some randomness but keep it close to current value
        const change = (Math.random() - 0.5) * maxChange * 2;
        let newValue = current + change;
        
        // Apply some "pressure" to move towards center of range
        const center = (min + max) / 2;
        const pressure = (center - newValue) * 0.1;
        newValue += pressure;
        
        // Ensure within bounds
        newValue = Math.max(min, Math.min(max, newValue));
        return Math.round(newValue);
      };

      // Track time of last data point
      let lastDataPointTime = Date.now();
      let connectionsLastUpdate = Date.now();
      
      // Add real-time data
      const addRealtimeData = () => {
        if (!chartElement) return;
        
        const now = Date.now();
        
        // Only add new data point every DATA_POINT_INTERVAL
        const shouldAddPoint = (now - lastDataPointTime) >= DATA_POINT_INTERVAL;
        
        if (shouldAddPoint) {
          lastDataPointTime = now;
          const newTimestamp = new Date(now).toISOString();
          
          // Generate smooth transitions for new values
          if (currentDataset === 'system') {
            // Generate new values
            previousValues.cpu = getNextValue(previousValues.cpu, 20, 50, 3);
            previousValues.memory = getNextValue(previousValues.memory, 40, 70, 2);
            
            // Get current data and add new points
            const currentSeries = chartElement.chartSeries.map((series, index) => ({
              name: series.name,
              data: [
                ...(series.data as Array<{x: any; y: any}>),
                index === 0 
                  ? { x: newTimestamp, y: previousValues.cpu }
                  : { x: newTimestamp, y: previousValues.memory }
              ]
            }));
            
            chartElement.updateSeries(currentSeries, false);
            
          } else if (currentDataset === 'network') {
            // Generate new values
            previousValues.download = getNextValue(previousValues.download, 100, 200, 10);
            previousValues.upload = getNextValue(previousValues.upload, 20, 50, 5);
            
            // Get current data and add new points
            const currentSeries = chartElement.chartSeries.map((series, index) => ({
              name: series.name,
              data: [
                ...(series.data as Array<{x: any; y: any}>),
                index === 0 
                  ? { x: newTimestamp, y: previousValues.download }
                  : { x: newTimestamp, y: previousValues.upload }
              ]
            }));
            
            chartElement.updateSeries(currentSeries, false);
          }
        }
      };

      // Update connections chart data
      const updateConnections = () => {
        if (!connectionsChartElement) return;
        
        const now = Date.now();
        const newTimestamp = new Date(now).toISOString();
        
        // Generate new connections value with discrete changes
        const change = Math.floor(Math.random() * 21) - 10; // -10 to +10 connections
        previousValues.connections = Math.max(50, Math.min(300, previousValues.connections + change));
        
        // Get current data and add new point
        const currentSeries = connectionsChartElement.chartSeries;
        const newData = [{
          name: currentSeries[0]?.name || 'Connections',
          data: [
            ...(currentSeries[0]?.data as Array<{x: any; y: any}> || []),
            { x: newTimestamp, y: previousValues.connections }
          ]
        }];
        
        connectionsChartElement.updateSeries(newData, false);
      };

      // Switch dataset
      const switchDataset = (name: string) => {
        currentDataset = name;
        const dataset = datasets[name];
        chartElement.label = dataset.label;
        chartElement.series = dataset.series;
        chartElement.yAxisFormatter = formatters[name];
        
        // Set appropriate y-axis scaling
        if (name === 'system') {
          chartElement.yAxisScaling = 'percentage';
          chartElement.yAxisMax = 100;
        } else if (name === 'network') {
          chartElement.yAxisScaling = 'dynamic';
        } else {
          chartElement.yAxisScaling = 'dynamic';
        }
        
        // Reset last data point time to get fresh data immediately
        lastDataPointTime = Date.now() - DATA_POINT_INTERVAL;
      };

      // Start/stop real-time updates
      const startRealtime = () => {
        if (!intervalId && (currentDataset === 'system' || currentDataset === 'network')) {
          chartElement.realtimeMode = true;
          // Only add data every 5 seconds, chart auto-scrolls independently
          intervalId = window.setInterval(() => addRealtimeData(), DATA_POINT_INTERVAL);
        }
        
        // Start connections updates
        if (!connectionsIntervalId) {
          connectionsChartElement.realtimeMode = true;
          // Update connections every second
          connectionsIntervalId = window.setInterval(() => updateConnections(), UPDATE_INTERVAL);
        }
      };

      const stopRealtime = () => {
        if (intervalId) {
          window.clearInterval(intervalId);
          intervalId = null;
          chartElement.realtimeMode = false;
        }
        
        // Stop connections updates
        if (connectionsIntervalId) {
          window.clearInterval(connectionsIntervalId);
          connectionsIntervalId = null;
          connectionsChartElement.realtimeMode = false;
        }
      };

      // Randomize current data (spike/drop simulation)
      const randomizeData = () => {
        if (currentDataset === 'system') {
          // Simulate CPU/Memory spike
          previousValues.cpu = Math.random() > 0.5 ? 85 : 25;
          previousValues.memory = Math.random() > 0.5 ? 80 : 45;
        } else if (currentDataset === 'network') {
          // Simulate network traffic spike
          previousValues.download = Math.random() > 0.5 ? 250 : 100;
          previousValues.upload = Math.random() > 0.5 ? 80 : 20;
        }
        
        // Also spike connections
        previousValues.connections = Math.random() > 0.5 ? 280 : 80;
        
        // Force immediate update by resetting timers
        lastDataPointTime = 0;
        connectionsLastUpdate = 0;
      };

      // Wire up button click handlers
      const buttons = elementArg.querySelectorAll('dees-button');
      buttons.forEach(button => {
        const text = button.textContent?.trim();
        if (text === 'System Usage') {
          button.addEventListener('click', () => switchDataset('system'));
        } else if (text === 'Network Traffic') {
          button.addEventListener('click', () => switchDataset('network'));
        } else if (text === 'Sales Data') {
          button.addEventListener('click', () => switchDataset('sales'));
        } else if (text === 'Start Live') {
          button.addEventListener('click', () => startRealtime());
        } else if (text === 'Stop Live') {
          button.addEventListener('click', () => stopRealtime());
        } else if (text === 'Spike Values') {
          button.addEventListener('click', () => randomizeData());
        }
      });
      
      // Update button states based on current dataset
      const updateButtonStates = () => {
        const buttons = elementArg.querySelectorAll('dees-button');
        buttons.forEach(button => {
          const text = button.textContent?.trim();
          if (text === 'System Usage') {
            button.type = currentDataset === 'system' ? 'highlighted' : 'normal';
          } else if (text === 'Network Traffic') {
            button.type = currentDataset === 'network' ? 'highlighted' : 'normal';
          } else if (text === 'Sales Data') {
            button.type = currentDataset === 'sales' ? 'highlighted' : 'normal';
          }
        });
      };
      
      // Configure main chart with rolling window
      chartElement.rollingWindow = TIME_WINDOW;
      chartElement.realtimeMode = false; // Will be enabled when starting live updates
      chartElement.yAxisScaling = 'percentage'; // Initial system dataset uses percentage
      chartElement.yAxisMax = 100;
      chartElement.autoScrollInterval = 1000; // Auto-scroll every second
      
      // Set initial time window
      setTimeout(() => {
        chartElement.updateTimeWindow();
      }, 100);
      
      // Update button states when dataset changes
      const originalSwitchDataset = switchDataset;
      const switchDatasetWithButtonUpdate = (name: string) => {
        originalSwitchDataset(name);
        updateButtonStates();
      };
      
      // Replace switchDataset with the one that updates buttons
      buttons.forEach(button => {
        const text = button.textContent?.trim();
        if (text === 'System Usage') {
          button.removeEventListener('click', () => switchDataset('system'));
          button.addEventListener('click', () => switchDatasetWithButtonUpdate('system'));
        } else if (text === 'Network Traffic') {
          button.removeEventListener('click', () => switchDataset('network'));
          button.addEventListener('click', () => switchDatasetWithButtonUpdate('network'));
        } else if (text === 'Sales Data') {
          button.removeEventListener('click', () => switchDataset('sales'));
          button.addEventListener('click', () => switchDatasetWithButtonUpdate('sales'));
        }
      });
      
      // Initialize connections chart with data
      if (connectionsChartElement) {
        const initialConnectionsData = generateInitialData(previousValues.connections, 30, UPDATE_INTERVAL);
        connectionsChartElement.series = [{
          name: 'Connections',
          data: initialConnectionsData
        }];
        
        // Configure connections chart
        connectionsChartElement.rollingWindow = TIME_WINDOW;
        connectionsChartElement.realtimeMode = false; // Will be enabled when starting live updates
        connectionsChartElement.yAxisScaling = 'fixed';
        connectionsChartElement.yAxisMax = 350;
        connectionsChartElement.autoScrollInterval = 1000; // Auto-scroll every second
        
        // Set initial time window
        setTimeout(() => {
          connectionsChartElement.updateTimeWindow();
        }, 100);
      }
    }}>
      <style>
        ${css`
        .demoBox {
          position: relative;
          background: ${cssManager.bdTheme('hsl(0 0% 95%)', 'hsl(0 0% 9%)')};
          height: 100%;
          width: 100%;
          padding: 40px;
          box-sizing: border-box;
          display: flex;
          flex-direction: column;
          gap: 24px;
        }
        
        .controls {
          display: flex;
          flex-wrap: wrap;
          gap: 12px;
          margin-bottom: 8px;
        }
        
        .chart-container {
          flex: 1;
          min-height: 400px;
        }
        
        .info {
          color: ${cssManager.bdTheme('hsl(215.4 16.3% 56.9%)', 'hsl(215 20.2% 55.1%)')};
          font-size: 12px;
          font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Geist Sans', sans-serif;
          text-align: center;
          margin-top: 8px;
        }
      `}
    </style>
    <div class="demoBox">
      <div class="controls">
        <dees-button-group label="Dataset:">
          <dees-button type="highlighted">System Usage</dees-button>
          <dees-button>Network Traffic</dees-button>
          <dees-button>Sales Data</dees-button>
        </dees-button-group>
        
        <dees-button-group label="Real-time:">
          <dees-button>Start Live</dees-button>
          <dees-button>Stop Live</dees-button>
        </dees-button-group>
        
        <dees-button-group label="Actions:">
          <dees-button>Spike Values</dees-button>
        </dees-button-group>
      </div>
      
      <div class="chart-container">
        <dees-chart-area
          id="main-chart"
          .label=${initialDatasets.system.label}
          .series=${initialDatasets.system.series}
          .yAxisFormatter=${initialFormatters.system}
        ></dees-chart-area>
      </div>
      
      <div class="chart-container" style="margin-top: 20px;">
        <dees-chart-area
          id="connections-chart"
          .label=${'Active Connections'}
          .series=${[{
            name: 'Connections',
            data: [] as Array<{x: any; y: any}>
          }]}
          .yAxisFormatter=${(val: number) => `${val}`}
        ></dees-chart-area>
      </div>
      
      <div class="info">
        Real-time monitoring with 2-minute rolling window • 
        Updates every second with smooth value transitions • 
        Click 'Spike Values' to simulate load spikes
      </div>
    </div>
    </dees-demowrapper>
  `;
};