import {
  DeesElement,
  customElement,
  property,
  state,
  type TemplateResult,
} from '@design.estate/dees-element';
import * as domtools from '@design.estate/dees-domtools';
import { demoFunc } from './demo.js';
import { chartAreaStyles } from './styles.js';
import { renderChartArea } from './template.js';
import ApexCharts from 'apexcharts';
declare global {
  interface HTMLElementTagNameMap {
    'dees-chart-area': DeesChartArea;
  }
}
@customElement('dees-chart-area')
export class DeesChartArea extends DeesElement {
  public static demo = demoFunc;
  // instance
  @state()
  public chart: ApexCharts;
  @property()
  public label: string = 'Untitled Chart';
  @property({ type: Array })
  public series: ApexAxisChartSeries = [];
  
  // Override getter to return internal chart data
  get chartSeries(): ApexAxisChartSeries {
    return this.internalChartData.length > 0 ? this.internalChartData : this.series;
  }
  @property({ attribute: false })
  public yAxisFormatter: (value: number) => string = (val) => `${val} Mbps`;
  
  @property({ type: Number })
  public rollingWindow: number = 0; // 0 means no rolling window
  
  @property({ type: Boolean })
  public realtimeMode: boolean = false;
  
  @property({ type: String })
  public yAxisScaling: 'fixed' | 'dynamic' | 'percentage' = 'dynamic';
  
  @property({ type: Number })
  public yAxisMax: number = 100; // Used when yAxisScaling is 'fixed' or 'percentage'
  
  @property({ type: Number })
  public autoScrollInterval: number = 1000; // Auto-scroll interval in milliseconds (0 to disable)
  private resizeObserver: ResizeObserver;
  private resizeTimeout: number;
  private internalChartData: ApexAxisChartSeries = [];
  private autoScrollTimer: number | null = null;
  private readonly DEBUG_RESIZE = false; // Set to true to enable resize debugging
  
  // Chart color schemes
  private readonly CHART_COLORS = {
    dark: [
      'hsl(217.2 91.2% 59.8%)', // Blue
      'hsl(173.4 80.4% 40%)',   // Teal
      'hsl(280.3 87.4% 66.7%)', // Purple
      'hsl(24.6 95% 53.1%)',    // Orange
    ],
    light: [
      'hsl(222.2 47.4% 51.2%)', // Blue (shadcn primary)
      'hsl(142.1 76.2% 36.3%)', // Green (shadcn success)
      'hsl(280.3 47.7% 50.2%)', // Purple (muted)
      'hsl(20.5 90.2% 48.2%)',  // Orange (shadcn destructive variant)
    ]
  };
  constructor() {
    super();
    domtools.elementBasic.setup();
    this.resizeObserver = new ResizeObserver((entries) => {
      // Debounce resize calls to prevent excessive updates
      if (this.resizeTimeout) {
        clearTimeout(this.resizeTimeout);
      }
      
      this.resizeTimeout = window.setTimeout(() => {
        // Simply resize if we have a chart, since we're only observing the mainbox
        if (this.chart) {
          // Log resize event for debugging
          if (this.DEBUG_RESIZE && entries.length > 0) {
            const entry = entries[0];
            console.log('DeesChartArea - Resize detected:', {
              width: entry.contentRect.width,
              height: entry.contentRect.height
            });
          }
          this.resizeChart();
        }
      }, 100); // 100ms debounce
    });
    
    // Note: ResizeObserver is now set up after chart initialization in firstUpdated()
    // to ensure proper timing and avoid race conditions
    
    this.registerGarbageFunction(async () => {
      if (this.resizeTimeout) {
        clearTimeout(this.resizeTimeout);
      }
      if (this.resizeObserver) {
        this.resizeObserver.disconnect();
      }
      this.stopAutoScroll();
      
      // Critical: Destroy chart instance to prevent memory leak
      if (this.chart) {
        try {
          this.chart.destroy();
          this.chart = null;
        } catch (error) {
          console.error('Error destroying chart:', error);
        }
      }
    });
  }
  
  public async connectedCallback() {
    super.connectedCallback();
    
    // Trigger resize when element is connected to DOM
    // This helps with dynamically added charts
    if (this.chart) {
      // Wait a frame for layout to settle
      await new Promise(resolve => requestAnimationFrame(resolve));
      await this.resizeChart();
    }
  }
  public static styles = chartAreaStyles;
  public render(): TemplateResult {
    return renderChartArea(this);
  }
  public async firstUpdated() {
    await this.domtoolsPromise;
    
    // Wait for next animation frame to ensure layout is complete
    await new Promise(resolve => requestAnimationFrame(resolve));
    
    // Get actual dimensions of the container
    const mainbox: HTMLDivElement = this.shadowRoot.querySelector('.mainbox');
    const chartContainer: HTMLDivElement = this.shadowRoot.querySelector('.chartContainer');
    
    if (!mainbox || !chartContainer) {
      console.error('Chart containers not found');
      return;
    }
    
    // Calculate initial dimensions
    const styleChartContainer = window.getComputedStyle(chartContainer);
    const paddingTop = parseInt(styleChartContainer.paddingTop, 10);
    const paddingBottom = parseInt(styleChartContainer.paddingBottom, 10);
    const paddingLeft = parseInt(styleChartContainer.paddingLeft, 10);
    const paddingRight = parseInt(styleChartContainer.paddingRight, 10);
    
    const initialWidth = mainbox.clientWidth - paddingLeft - paddingRight;
    const initialHeight = mainbox.offsetHeight - paddingTop - paddingBottom;
    
    // Use provided series data or default demo data
    const chartSeries = this.series.length > 0 ? this.series : [
      {
        name: 'cpu',
        data: [
          { x: '2025-01-15T03:00:00', y: 25 },
          { x: '2025-01-15T07:00:00', y: 30 },
          { x: '2025-01-15T11:00:00', y: 20 },
          { x: '2025-01-15T15:00:00', y: 35 },
          { x: '2025-01-15T19:00:00', y: 25 },
        ],
      },
      {
        name: 'memory',
        data: [
          { x: '2025-01-15T03:00:00', y: 10 },
          { x: '2025-01-15T07:00:00', y: 12 },
          { x: '2025-01-15T11:00:00', y: 10 },
          { x: '2025-01-15T15:00:00', y: 30 },
          { x: '2025-01-15T19:00:00', y: 40 },
        ],
      },
    ];
    
    // Store internal data
    this.internalChartData = chartSeries;
    
    // Get current theme
    const isDark = !this.goBright;
    const theme = isDark ? 'dark' : 'light';
    
    var options: ApexCharts.ApexOptions = {
      series: chartSeries,
      chart: {
        width: initialWidth || 100, // Use actual width or fallback
        height: initialHeight || 100, // Use actual height or fallback
        type: 'area',
        background: 'transparent', // Transparent background to inherit from container
        toolbar: {
          show: false, // This line disables the toolbar
        },
        animations: {
          enabled: !this.realtimeMode, // Disable animations in realtime mode
          speed: 400,
          animateGradually: {
            enabled: false, // Disable gradual animation for cleaner updates
            delay: 0
          },
          dynamicAnimation: {
            enabled: !this.realtimeMode,
            speed: 350
          }
        },
        zoom: {
          enabled: false, // Disable zoom for cleaner interaction
        },
        selection: {
          enabled: false, // Disable selection
        },
      },
      dataLabels: {
        enabled: false,
      },
      stroke: {
        width: 2,
        curve: 'smooth',
      },
      xaxis: {
        type: 'datetime', // Time-series data
        labels: {
          format: 'HH:mm:ss', // Time formatting with seconds
          datetimeUTC: false,
          style: {
            colors: [isDark ? 'hsl(0 0% 63.9%)' : 'hsl(0 0% 20%)'], // Label color
            fontSize: '12px',
            fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif',
            fontWeight: '400',
          },
        },
        axisBorder: {
          show: false, // Hide x-axis border
        },
        axisTicks: {
          show: false, // Hide x-axis ticks
        },
      },
      yaxis: {
        min: 0,
        max: this.yAxisScaling === 'dynamic' ? undefined : this.yAxisMax,
        labels: {
          formatter: this.yAxisFormatter,
          style: {
            colors: [isDark ? 'hsl(0 0% 63.9%)' : 'hsl(0 0% 20%)'], // Label color
            fontSize: '12px',
            fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif',
            fontWeight: '400',
          },
        },
        axisBorder: {
          show: false, // Hide y-axis border
        },
        axisTicks: {
          show: false, // Hide y-axis ticks
        },
      },
      tooltip: {
        shared: true, // Enables the tooltip to display across series
        intersect: false, // Allows hovering anywhere on the chart
        followCursor: true, // Makes tooltip follow mouse even between points
        x: {
          format: 'dd/MM/yy HH:mm',
        },
        custom: ({ series, dataPointIndex, w }: any) => {
          // Iterate through each series and get its value
          // Note: We can't access component instance here, so we'll use w.config.theme.mode
          const currentTheme = w.config.theme.mode;
          const isDarkMode = currentTheme === 'dark';
          const bgColor = isDarkMode ? 'hsl(0 0% 9%)' : 'hsl(0 0% 100%)';
          const textColor = isDarkMode ? 'hsl(0 0% 95%)' : 'hsl(0 0% 9%)';
          const borderColor = isDarkMode ? 'hsl(0 0% 14.9%)' : 'hsl(0 0% 89.8%)';
          
          // Get formatter from chart config
          const formatter = w.config.yaxis[0]?.labels?.formatter || ((val: number) => val.toString());
          
          let tooltipContent = `
`;
          series.forEach((s: number[], index: number) => {
            const label = w.globals.seriesNames[index]; // Get series label
            const value = s[dataPointIndex]; // Get value at data point
            const color = w.globals.colors[index];
            const formattedValue = formatter(value);
            tooltipContent += `
              
              ${label}:
              ${formattedValue}
            
`;
          });
          tooltipContent += `