import { Component, OnInit } from '@angular/core';
import { ClrLoadingState } from '@clr/angular';
import { ChartTypeService } from '../chart-type-manager/chart-type.service';
import { UiComponentService } from './ui-component.service';
import { ComponentPropertyService } from './component-property.service';
import { ChartTemplateService } from './chart-template.service';
import { DynamicFieldService } from './dynamic-field.service';

export interface ChartType {
  id: number;
  name: string;
  displayName: string;
  description: string;
  isActive: boolean;
  createdAt: string;
  updatedAt: string;
}

export interface UiComponent {
  id: number;
  chartType: ChartType;
  componentName: string;
  componentType: string;
  displayLabel: string;
  placeholder: string;
  isRequired: boolean;
  sortOrder: number;
  createdAt: string;
  updatedAt: string;
}

export interface ComponentProperty {
  id: number;
  component: UiComponent;
  propertyName: string;
  propertyValue: string;
  propertyType: string;
  createdAt: string;
  updatedAt: string;
}

export interface ChartTemplate {
  id: number;
  chartType: ChartType;
  templateName: string;
  templateHtml: string;
  templateCss: string;
  isDefault: boolean;
  createdAt: string;
  updatedAt: string;
}

export interface DynamicField {
  id: number;
  chartType: ChartType;
  fieldName: string;
  fieldLabel: string;
  fieldType: string;
  fieldOptions: string;
  isRequired: boolean;
  showInUi: boolean;
  sortOrder: number;
  createdAt: string;
  updatedAt: string;
}

@Component({
  selector: 'app-chart-config-manager',
  templateUrl: './chart-config-manager.component.html',
  styleUrls: ['./chart-config-manager.component.scss']
})
export class ChartConfigManagerComponent implements OnInit {
  // Chart Types
  chartTypes: ChartType[] = [];
  selectedChartType: ChartType | null = null;
  newChartType: Partial<ChartType> = {};
  showAddChartTypeForm = false;
  chartTypeLoadingState: ClrLoadingState = ClrLoadingState.DEFAULT;

  // UI Components
  uiComponents: UiComponent[] = [];
  selectedUiComponent: UiComponent | null = null;
  newUiComponent: Partial<UiComponent> = {};
  showAddUiComponentForm = false;
  uiComponentLoadingState: ClrLoadingState = ClrLoadingState.DEFAULT;

  // Component Properties
  componentProperties: ComponentProperty[] = [];
  selectedComponentProperty: ComponentProperty | null = null;
  newComponentProperty: Partial<ComponentProperty> = {};
  showAddComponentPropertyForm = false;
  componentPropertyLoadingState: ClrLoadingState = ClrLoadingState.DEFAULT;

  // Chart Templates
  chartTemplates: ChartTemplate[] = [];
  selectedChartTemplate: ChartTemplate | null = null;
  newChartTemplate: Partial<ChartTemplate> = {};
  showAddChartTemplateForm = false;
  chartTemplateLoadingState: ClrLoadingState = ClrLoadingState.DEFAULT;

  // Dynamic Fields
  dynamicFields: DynamicField[] = [];
  selectedDynamicField: DynamicField | null = null;
  newDynamicField: Partial<DynamicField> = {};
  showAddDynamicFieldForm = false;
  dynamicFieldLoadingState: ClrLoadingState = ClrLoadingState.DEFAULT;

  // Make ClrLoadingState available to template
  readonly ClrLoadingState = ClrLoadingState;

  // Error handling
  errorMessage: string | null = null;
  successMessage: string | null = null;

  constructor(
    private chartTypeService: ChartTypeService,
    private uiComponentService: UiComponentService,
    private componentPropertyService: ComponentPropertyService,
    private chartTemplateService: ChartTemplateService,
    private dynamicFieldService: DynamicFieldService
  ) { }

  ngOnInit(): void {
    console.log('ChartConfigManagerComponent initialized');
    this.loadChartTypes();
  }

  // Show error message
  private showError(message: string): void {
    this.errorMessage = message;
    setTimeout(() => {
      this.errorMessage = null;
    }, 5000);
  }

  // Show success message
  private showSuccess(message: string): void {
    this.successMessage = message;
    setTimeout(() => {
      this.successMessage = null;
    }, 3000);
  }

  // Chart Type Methods
  loadChartTypes(): void {
    this.chartTypeLoadingState = ClrLoadingState.LOADING;
    console.log('Loading chart types...');
    this.chartTypeService.getAllChartTypes().subscribe({
      next: (data) => {
        console.log('Chart types loaded:', data);
        this.chartTypes = data;
        this.chartTypeLoadingState = ClrLoadingState.SUCCESS;
      },
      error: (error) => {
        console.error('Error loading chart types:', error);
        this.showError('Error loading chart types: ' + (error.error?.message || error.message || 'Unknown error'));
        this.chartTypeLoadingState = ClrLoadingState.ERROR;
      }
    });
  }

  createChartType(): void {
    if (!this.newChartType.name) {
      this.showError('Chart type name is required');
      return;
    }

    this.chartTypeLoadingState = ClrLoadingState.LOADING;
    this.chartTypeService.createChartType(this.newChartType).subscribe({
      next: (data) => {
        this.chartTypes.push(data);
        this.newChartType = {};
        this.showAddChartTypeForm = false;
        this.showSuccess('Chart type created successfully');
        this.chartTypeLoadingState = ClrLoadingState.SUCCESS;
      },
      error: (error) => {
        console.error('Error creating chart type:', error);
        this.showError('Error creating chart type: ' + (error.error?.message || error.message || 'Unknown error'));
        this.chartTypeLoadingState = ClrLoadingState.ERROR;
      }
    });
  }

  updateChartType(): void {
    if (!this.selectedChartType || !this.selectedChartType.name) {
      this.showError('Chart type name is required');
      return;
    }

    this.chartTypeLoadingState = ClrLoadingState.LOADING;
    this.chartTypeService.updateChartType(this.selectedChartType.id, this.selectedChartType).subscribe({
      next: (data) => {
        const index = this.chartTypes.findIndex(ct => ct.id === data.id);
        if (index !== -1) {
          this.chartTypes[index] = data;
        }
        this.selectedChartType = null;
        this.showSuccess('Chart type updated successfully');
        this.chartTypeLoadingState = ClrLoadingState.SUCCESS;
      },
      error: (error) => {
        console.error('Error updating chart type:', error);
        this.showError('Error updating chart type: ' + (error.error?.message || error.message || 'Unknown error'));
        this.chartTypeLoadingState = ClrLoadingState.ERROR;
      }
    });
  }

  deleteChartType(id: number): void {
    if (!confirm('Are you sure you want to delete this chart type? This will also delete all related UI components, templates, and fields.')) {
      return;
    }

    this.chartTypeLoadingState = ClrLoadingState.LOADING;
    this.chartTypeService.deleteChartType(id).subscribe({
      next: () => {
        this.chartTypes = this.chartTypes.filter(ct => ct.id !== id);
        // Clear related data if the deleted chart type was selected
        if (this.selectedChartType && this.selectedChartType.id === id) {
          this.selectedChartType = null;
          this.uiComponents = [];
          this.chartTemplates = [];
          this.dynamicFields = [];
        }
        this.showSuccess('Chart type deleted successfully');
        this.chartTypeLoadingState = ClrLoadingState.SUCCESS;
      },
      error: (error) => {
        console.error('Error deleting chart type:', error);
        this.showError('Error deleting chart type: ' + (error.error?.message || error.message || 'Unknown error'));
        this.chartTypeLoadingState = ClrLoadingState.ERROR;
      }
    });
  }

  selectChartTypeForEdit(chartType: ChartType): void {
    this.selectedChartType = { ...chartType };
  }

  // UI Component Methods
  loadUiComponents(chartTypeId: number): void {
    if (!chartTypeId) {
      this.uiComponents = [];
      return;
    }
    
    this.uiComponentLoadingState = ClrLoadingState.LOADING;
    this.uiComponentService.getUiComponentsByChartType(chartTypeId).subscribe({
      next: (data) => {
        this.uiComponents = data;
        this.uiComponentLoadingState = ClrLoadingState.SUCCESS;
      },
      error: (error) => {
        console.error('Error loading UI components:', error);
        this.showError('Error loading UI components: ' + (error.error?.message || error.message || 'Unknown error'));
        this.uiComponentLoadingState = ClrLoadingState.ERROR;
      }
    });
  }

  createUiComponent(): void {
    if (!this.selectedChartType) {
      this.showError('Please select a chart type first');
      return;
    }

    if (!this.newUiComponent.componentName) {
      this.showError('Component name is required');
      return;
    }

    this.uiComponentLoadingState = ClrLoadingState.LOADING;
    
    // Create a complete chartType object with only the ID
    const chartTypeWithId = { 
      id: this.selectedChartType.id,
      name: '',
      displayName: '',
      description: '',
      isActive: true,
      createdAt: '',
      updatedAt: ''
    };

    const uiComponentData = {
      ...this.newUiComponent,
      chartType: chartTypeWithId
    };

    this.uiComponentService.createUiComponent(uiComponentData).subscribe({
      next: (data) => {
        this.uiComponents.push(data);
        this.newUiComponent = {};
        this.showAddUiComponentForm = false;
        this.showSuccess('UI component created successfully');
        this.uiComponentLoadingState = ClrLoadingState.SUCCESS;
      },
      error: (error) => {
        console.error('Error creating UI component:', error);
        this.showError('Error creating UI component: ' + (error.error?.message || error.message || 'Unknown error'));
        this.uiComponentLoadingState = ClrLoadingState.ERROR;
      }
    });
  }

  updateUiComponent(): void {
    if (!this.selectedUiComponent || !this.selectedUiComponent.componentName) {
      this.showError('Component name is required');
      return;
    }

    this.uiComponentLoadingState = ClrLoadingState.LOADING;
    this.uiComponentService.updateUiComponent(this.selectedUiComponent.id, this.selectedUiComponent).subscribe({
      next: (data) => {
        const index = this.uiComponents.findIndex(uc => uc.id === data.id);
        if (index !== -1) {
          this.uiComponents[index] = data;
        }
        this.selectedUiComponent = null;
        this.showSuccess('UI component updated successfully');
        this.uiComponentLoadingState = ClrLoadingState.SUCCESS;
      },
      error: (error) => {
        console.error('Error updating UI component:', error);
        this.showError('Error updating UI component: ' + (error.error?.message || error.message || 'Unknown error'));
        this.uiComponentLoadingState = ClrLoadingState.ERROR;
      }
    });
  }

  deleteUiComponent(id: number): void {
    if (!confirm('Are you sure you want to delete this UI component?')) {
      return;
    }

    this.uiComponentLoadingState = ClrLoadingState.LOADING;
    this.uiComponentService.deleteUiComponent(id).subscribe({
      next: () => {
        this.uiComponents = this.uiComponents.filter(uc => uc.id !== id);
        this.showSuccess('UI component deleted successfully');
        this.uiComponentLoadingState = ClrLoadingState.SUCCESS;
      },
      error: (error) => {
        console.error('Error deleting UI component:', error);
        this.showError('Error deleting UI component: ' + (error.error?.message || error.message || 'Unknown error'));
        this.uiComponentLoadingState = ClrLoadingState.ERROR;
      }
    });
  }

  selectUiComponentForEdit(uiComponent: UiComponent): void {
    this.selectedUiComponent = { ...uiComponent };
  }

  // Component Property Methods
  loadComponentProperties(componentId: number): void {
    if (!componentId) {
      this.componentProperties = [];
      return;
    }
    
    this.componentPropertyLoadingState = ClrLoadingState.LOADING;
    this.componentPropertyService.getComponentPropertiesByComponent(componentId).subscribe({
      next: (data) => {
        this.componentProperties = data;
        this.componentPropertyLoadingState = ClrLoadingState.SUCCESS;
      },
      error: (error) => {
        console.error('Error loading component properties:', error);
        this.showError('Error loading component properties: ' + (error.error?.message || error.message || 'Unknown error'));
        this.componentPropertyLoadingState = ClrLoadingState.ERROR;
      }
    });
  }

  createComponentProperty(): void {
    if (!this.selectedUiComponent) {
      this.showError('Please select a UI component first');
      return;
    }

    if (!this.newComponentProperty.propertyName) {
      this.showError('Property name is required');
      return;
    }

    this.componentPropertyLoadingState = ClrLoadingState.LOADING;
    
    // Create a complete component object with only the ID
    const componentWithId = { 
      id: this.selectedUiComponent.id
    } as UiComponent;

    const componentPropertyData = {
      ...this.newComponentProperty,
      component: componentWithId
    };

    this.componentPropertyService.createComponentProperty(componentPropertyData).subscribe({
      next: (data) => {
        this.componentProperties.push(data);
        this.newComponentProperty = {};
        this.showAddComponentPropertyForm = false;
        this.showSuccess('Component property created successfully');
        this.componentPropertyLoadingState = ClrLoadingState.SUCCESS;
      },
      error: (error) => {
        console.error('Error creating component property:', error);
        this.showError('Error creating component property: ' + (error.error?.message || error.message || 'Unknown error'));
        this.componentPropertyLoadingState = ClrLoadingState.ERROR;
      }
    });
  }

  updateComponentProperty(): void {
    if (!this.selectedComponentProperty || !this.selectedComponentProperty.propertyName) {
      this.showError('Property name is required');
      return;
    }

    this.componentPropertyLoadingState = ClrLoadingState.LOADING;
    this.componentPropertyService.updateComponentProperty(this.selectedComponentProperty.id, this.selectedComponentProperty).subscribe({
      next: (data) => {
        const index = this.componentProperties.findIndex(cp => cp.id === data.id);
        if (index !== -1) {
          this.componentProperties[index] = data;
        }
        this.selectedComponentProperty = null;
        this.showSuccess('Component property updated successfully');
        this.componentPropertyLoadingState = ClrLoadingState.SUCCESS;
      },
      error: (error) => {
        console.error('Error updating component property:', error);
        this.showError('Error updating component property: ' + (error.error?.message || error.message || 'Unknown error'));
        this.componentPropertyLoadingState = ClrLoadingState.ERROR;
      }
    });
  }

  deleteComponentProperty(id: number): void {
    if (!confirm('Are you sure you want to delete this component property?')) {
      return;
    }

    this.componentPropertyLoadingState = ClrLoadingState.LOADING;
    this.componentPropertyService.deleteComponentProperty(id).subscribe({
      next: () => {
        this.componentProperties = this.componentProperties.filter(cp => cp.id !== id);
        this.showSuccess('Component property deleted successfully');
        this.componentPropertyLoadingState = ClrLoadingState.SUCCESS;
      },
      error: (error) => {
        console.error('Error deleting component property:', error);
        this.showError('Error deleting component property: ' + (error.error?.message || error.message || 'Unknown error'));
        this.componentPropertyLoadingState = ClrLoadingState.ERROR;
      }
    });
  }

  selectComponentPropertyForEdit(componentProperty: ComponentProperty): void {
    this.selectedComponentProperty = { ...componentProperty };
  }

  // Chart Template Methods
  loadChartTemplates(chartTypeId: number): void {
    if (!chartTypeId) {
      this.chartTemplates = [];
      return;
    }
    
    this.chartTemplateLoadingState = ClrLoadingState.LOADING;
    this.chartTemplateService.getChartTemplatesByChartType(chartTypeId).subscribe({
      next: (data) => {
        this.chartTemplates = data;
        this.chartTemplateLoadingState = ClrLoadingState.SUCCESS;
      },
      error: (error) => {
        console.error('Error loading chart templates:', error);
        this.showError('Error loading chart templates: ' + (error.error?.message || error.message || 'Unknown error'));
        this.chartTemplateLoadingState = ClrLoadingState.ERROR;
      }
    });
  }

  createChartTemplate(): void {
    if (!this.selectedChartType) {
      this.showError('Please select a chart type first');
      return;
    }

    if (!this.newChartTemplate.templateName) {
      this.showError('Template name is required');
      return;
    }

    this.chartTemplateLoadingState = ClrLoadingState.LOADING;
    
    // Remove the chartType from the template data since we're passing it as a parameter
    const chartTemplateData = { ...this.newChartTemplate };
    // Remove chartType property if it exists
    delete (chartTemplateData as any).chartType;

    this.chartTemplateService.createChartTemplate(chartTemplateData, this.selectedChartType.id).subscribe({
      next: (data) => {
        this.chartTemplates.push(data);
        this.newChartTemplate = {};
        this.showAddChartTemplateForm = false;
        this.showSuccess('Chart template created successfully');
        this.chartTemplateLoadingState = ClrLoadingState.SUCCESS;
      },
      error: (error) => {
        console.error('Error creating chart template:', error);
        this.showError('Error creating chart template: ' + (error.error?.message || error.message || 'Unknown error'));
        this.chartTemplateLoadingState = ClrLoadingState.ERROR;
      }
    });
  }

  updateChartTemplate(): void {
    if (!this.selectedChartTemplate || !this.selectedChartTemplate.templateName) {
      this.showError('Template name is required');
      return;
    }

    this.chartTemplateLoadingState = ClrLoadingState.LOADING;
    this.chartTemplateService.updateChartTemplate(this.selectedChartTemplate.id, this.selectedChartTemplate).subscribe({
      next: (data) => {
        const index = this.chartTemplates.findIndex(ct => ct.id === data.id);
        if (index !== -1) {
          this.chartTemplates[index] = data;
        }
        this.selectedChartTemplate = null;
        this.showSuccess('Chart template updated successfully');
        this.chartTemplateLoadingState = ClrLoadingState.SUCCESS;
      },
      error: (error) => {
        console.error('Error updating chart template:', error);
        this.showError('Error updating chart template: ' + (error.error?.message || error.message || 'Unknown error'));
        this.chartTemplateLoadingState = ClrLoadingState.ERROR;
      }
    });
  }

  deleteChartTemplate(id: number): void {
    if (!confirm('Are you sure you want to delete this chart template?')) {
      return;
    }

    this.chartTemplateLoadingState = ClrLoadingState.LOADING;
    this.chartTemplateService.deleteChartTemplate(id).subscribe({
      next: () => {
        this.chartTemplates = this.chartTemplates.filter(ct => ct.id !== id);
        this.showSuccess('Chart template deleted successfully');
        this.chartTemplateLoadingState = ClrLoadingState.SUCCESS;
      },
      error: (error) => {
        console.error('Error deleting chart template:', error);
        this.showError('Error deleting chart template: ' + (error.error?.message || error.message || 'Unknown error'));
        this.chartTemplateLoadingState = ClrLoadingState.ERROR;
      }
    });
  }

  selectChartTemplateForEdit(chartTemplate: ChartTemplate): void {
    this.selectedChartTemplate = { ...chartTemplate };
  }

  // Dynamic Field Methods
  loadDynamicFields(chartTypeId: number): void {
    if (!chartTypeId) {
      this.dynamicFields = [];
      return;
    }
    
    this.dynamicFieldLoadingState = ClrLoadingState.LOADING;
    this.dynamicFieldService.getDynamicFieldsByChartType(chartTypeId).subscribe({
      next: (data) => {
        this.dynamicFields = data;
        this.dynamicFieldLoadingState = ClrLoadingState.SUCCESS;
      },
      error: (error) => {
        console.error('Error loading dynamic fields:', error);
        this.showError('Error loading dynamic fields: ' + (error.error?.message || error.message || 'Unknown error'));
        this.dynamicFieldLoadingState = ClrLoadingState.ERROR;
      }
    });
  }

  createDynamicField(): void {
    if (!this.selectedChartType) {
      this.showError('Please select a chart type first');
      return;
    }

    if (!this.newDynamicField.fieldName) {
      this.showError('Field name is required');
      return;
    }

    this.dynamicFieldLoadingState = ClrLoadingState.LOADING;
    
    // Remove the chartType from the dynamic field data since we're passing it as a parameter
    const dynamicFieldData = { ...this.newDynamicField };
    // Remove chartType property if it exists
    delete (dynamicFieldData as any).chartType;

    this.dynamicFieldService.createDynamicField(dynamicFieldData, this.selectedChartType.id).subscribe({
      next: (data) => {
        this.dynamicFields.push(data);
        this.newDynamicField = {};
        this.showAddDynamicFieldForm = false;
        this.showSuccess('Dynamic field created successfully');
        this.dynamicFieldLoadingState = ClrLoadingState.SUCCESS;
      },
      error: (error) => {
        console.error('Error creating dynamic field:', error);
        this.showError('Error creating dynamic field: ' + (error.error?.message || error.message || 'Unknown error'));
        this.dynamicFieldLoadingState = ClrLoadingState.ERROR;
      }
    });
  }

  updateDynamicField(): void {
    if (!this.selectedDynamicField || !this.selectedDynamicField.fieldName) {
      this.showError('Field name is required');
      return;
    }

    this.dynamicFieldLoadingState = ClrLoadingState.LOADING;
    this.dynamicFieldService.updateDynamicField(this.selectedDynamicField.id, this.selectedDynamicField).subscribe({
      next: (data) => {
        const index = this.dynamicFields.findIndex(df => df.id === data.id);
        if (index !== -1) {
          this.dynamicFields[index] = data;
        }
        this.selectedDynamicField = null;
        this.showSuccess('Dynamic field updated successfully');
        this.dynamicFieldLoadingState = ClrLoadingState.SUCCESS;
      },
      error: (error) => {
        console.error('Error updating dynamic field:', error);
        this.showError('Error updating dynamic field: ' + (error.error?.message || error.message || 'Unknown error'));
        this.dynamicFieldLoadingState = ClrLoadingState.ERROR;
      }
    });
  }

  deleteDynamicField(id: number): void {
    if (!confirm('Are you sure you want to delete this dynamic field?')) {
      return;
    }

    this.dynamicFieldLoadingState = ClrLoadingState.LOADING;
    this.dynamicFieldService.deleteDynamicField(id).subscribe({
      next: () => {
        this.dynamicFields = this.dynamicFields.filter(df => df.id !== id);
        this.showSuccess('Dynamic field deleted successfully');
        this.dynamicFieldLoadingState = ClrLoadingState.SUCCESS;
      },
      error: (error) => {
        console.error('Error deleting dynamic field:', error);
        this.showError('Error deleting dynamic field: ' + (error.error?.message || error.message || 'Unknown error'));
        this.dynamicFieldLoadingState = ClrLoadingState.ERROR;
      }
    });
  }

  selectDynamicFieldForEdit(dynamicField: DynamicField): void {
    this.selectedDynamicField = { ...dynamicField };
  }

  // Helper methods
  onChartTypeSelect(chartType: ChartType): void {
    this.selectedChartType = chartType;
    this.loadUiComponents(chartType.id);
    this.loadChartTemplates(chartType.id);
    this.loadDynamicFields(chartType.id);
  }

  onUiComponentSelect(uiComponent: UiComponent): void {
    this.selectedUiComponent = uiComponent;
    this.loadComponentProperties(uiComponent.id);
    // Scroll to the Component Properties tab
    setTimeout(() => {
      const element = document.querySelector('clr-tab[ng-reflect-ng-if="true"] button[clr-tab-link]:nth-child(3)');
      if (element) {
        element.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
      }
    }, 100);
  }

  resetForms(): void {
    this.newChartType = {};
    this.newUiComponent = {};
    this.newComponentProperty = {};
    this.newChartTemplate = {};
    this.newDynamicField = {};
    this.showAddChartTypeForm = false;
    this.showAddUiComponentForm = false;
    this.showAddComponentPropertyForm = false;
    this.showAddChartTemplateForm = false;
    this.showAddDynamicFieldForm = false;
    this.selectedChartType = null;
    this.selectedUiComponent = null;
    this.selectedComponentProperty = null;
    this.selectedChartTemplate = null;
    this.selectedDynamicField = null;
  }
}