import { Component, OnInit, Input, OnChanges, SimpleChanges } from '@angular/core';
import { UsergrpmaintainceService } from 'src/app/services/admin/usergrpmaintaince.service';
import { Dashboard3Service } from 'src/app/services/builder/dashboard3.service';

@Component({
  selector: 'app-grid-view',
  templateUrl: './grid-view.component.html',
  styleUrls: ['./grid-view.component.scss']
})
export class GridViewComponent implements OnInit, OnChanges {
  @Input() xAxis: string;
  @Input() yAxis: string | string[];
  @Input() table: string;
  @Input() datastore: string;
  @Input() charttitle: string;
  @Input() chartlegend: boolean = true;
  @Input() showlabel: boolean = true;
  @Input() chartcolor: boolean;
  @Input() slices: boolean;
  @Input() donut: boolean;
  @Input() charturl: string;
  @Input() chartparameter: string;
  @Input() datasource: string;
  @Input() fieldName: string;
  @Input() connection: number; // Add connection input

  loading = false;
  givendata: any[] = [];
  orders;
  error: string;
  modalAdd = false;
  modaledit = false;
  modaldelete = false;
  rowSelected: any = {};
  mcreate;
  medit;
  showdata;
  submitted = false;
  dynamicHeaders: any[] = [];

  constructor(

    private mainservice: UsergrpmaintainceService,
    private dashboardService: Dashboard3Service,
  ) { }

  ngOnInit(): void {
    this.fetchGridData();
  }

  ngOnChanges(changes: SimpleChanges): void {
    console.log('GridViewComponent input changes:', changes);

    // Check if any of the key properties have changed
    const xAxisChanged = changes.xAxis && !changes.xAxis.firstChange;
    const yAxisChanged = changes.yAxis && !changes.yAxis.firstChange;
    const tableChanged = changes.table && !changes.table.firstChange;
    const connectionChanged = changes.connection && !changes.connection.firstChange; // Add connection change detection

    // Respond to input changes
    if (xAxisChanged || yAxisChanged || tableChanged || connectionChanged) {
      console.log('X or Y axis or table or connection changed, fetching new data');
      // Only fetch data if xAxis, yAxis, table, or connection has changed (and it's not the first change)
      this.fetchGridData();
    }
  }

  // Dynamic headers for the grid
  
  fetchGridData(): void {
    // If we have the necessary data, fetch grid data from the service
    if (this.table && this.xAxis) {
      console.log('Fetching grid data for:', { table: this.table, xAxis: this.xAxis, yAxis: this.yAxis, connection: this.connection });

      // Convert yAxis to string if it's an array
      const yAxisString = Array.isArray(this.yAxis) ? this.yAxis.join(',') : this.yAxis;

      // Fetch data from the dashboard service, similar to other chart components
      this.dashboardService.getChartData(this.table, 'grid', this.xAxis, yAxisString, this.connection).subscribe(
        (data: any) => {
          console.log('Received grid data:', data);
          if (data === null) {
            console.warn('Grid API returned null data. Check if the API endpoint is working correctly.');
            this.error = "No data Available";
            return;
          }
          
          // Handle the actual data structure returned by the API
          if (data && data.chartData) {
            this.givendata = data.chartData;
            this.extractDynamicHeaders(data.chartData);
            this.error = this.givendata.length === 0 ? "No data Available" : undefined;
            console.log('Updated grid with data:', this.givendata);
          } else if (data && data.data) {
            // Handle the original expected format as fallback
            this.givendata = data.data;
            this.extractDynamicHeaders(data.data);
            this.error = this.givendata.length === 0 ? "No data Available" : undefined;
            console.log('Updated grid with legacy data format:', this.givendata);
          } else if (Array.isArray(data)) {
            // Handle case where data is directly an array
            this.givendata = data;
            this.extractDynamicHeaders(data);
            this.error = this.givendata.length === 0 ? "No data Available" : undefined;
            console.log('Updated grid with array data:', this.givendata);
          } else {
            console.warn('Grid received data does not have expected structure', data);
            this.error = "No valid data received";
            this.givendata = [];
          }
        }, (error) => {
          console.log('Error fetching grid data:', error);
          this.error = "Server Error";
        });
    } else if (this.table) {
      console.log('Missing xAxis, falling back to default data fetching');
      // Fallback to default data fetching when only table is provided
       // Convert yAxis to string if it's an array
      const yAxisString = Array.isArray(this.yAxis) ? this.yAxis.join(',') : this.yAxis;

      // Fetch data from the dashboard service, similar to other chart components
      this.dashboardService.getChartData(this.table, 'grid', this.xAxis, yAxisString, this.connection).subscribe(
        (data: any) => {
      // this.mainservice.getAll().subscribe((data: any) => {
        console.log('recv data ', data);
        this.givendata = Array.isArray(data) ? data : [];
        this.extractDynamicHeaders(data);
        this.error = this.givendata && this.givendata.length === 0 ? "No data Available" : undefined;
      }, (error) => {
        console.log(error);
        this.error = "Server Error";
      });
    } else {
      console.log('Missing required data for grid:', { table: this.table });
      this.error = "Table name is required";
    }
  }
  
  /**
   * Extract dynamic headers from the data
   * @param data Array of data objects
   */
  private extractDynamicHeaders(data: any): void {
    // Ensure data is an array
    const dataArray = Array.isArray(data) ? data : [];
    
    if (dataArray && dataArray.length > 0) {
      // Get all unique keys from the data objects
      const allKeys = new Set<string>();
      dataArray.forEach(item => {
        if (item && typeof item === 'object') {
          Object.keys(item).forEach(key => allKeys.add(key));
        }
      });
      
      // Convert to array of header objects with key and display name
      this.dynamicHeaders = Array.from(allKeys).map(key => ({
        key: key,
        displayName: this.formatHeader(key)
      }));
      
      console.log('Dynamic headers extracted:', this.dynamicHeaders);
    } else {
      this.dynamicHeaders = [];
    }
  }
  
  /**
   * Format header name for better display
   * @param key The key to format
   */
  private formatHeader(key: string): string {
    // Convert camelCase to Title Case
    return key
      .replace(/([A-Z])/g, ' $1')
      .replace(/^./, str => str.toUpperCase());
  }
}