import { Component, OnInit, forwardRef, OnDestroy } from '@angular/core';
import { CommonModule } from '@angular/common';
import { ReactiveFormsModule } from '@angular/forms';
import { MatCheckboxModule } from '@angular/material/checkbox';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatOptionModule } from '@angular/material/core';
import { FieldBase } from '@pega/angular-sdk-components';
import { ComponentMapperComponent } from '@pega/angular-sdk-components';
import { PConnFieldProps } from '@pega/angular-sdk-components';
import { deleteInstruction, insertInstruction, updateNewInstructions } from '@pega/angular-sdk-components';
import { handleEvent } from '@pega/angular-sdk-components';

interface {{COMPONENT_CLASS_NAME}}Props extends Omit<PConnFieldProps, 'value'> {
  // If any, enter additional props that only exist on Checkbox here
  // Everything from PConnFieldProps except value and change type of value to boolean
  value: boolean;
  caption?: string;
  trueLabel?: string;
  falseLabel?: string;
  selectionMode?: string;
  datasource?: any;
  selectionKey?: string;
  selectionList?: any;
  primaryField: string;
  readonlyContextList: any;
  referenceList: string;
  variant?: string;
  renderMode: string;
}

@Component({
  selector: 'app-{{COMPONENT_CLASS_NAME_KEBAB}}',
  templateUrl: './{{COMPONENT_CLASS_NAME_KEBAB}}.component.html',
  styleUrls: ['./{{COMPONENT_CLASS_NAME_KEBAB}}.component.scss'],
  imports: [CommonModule, ReactiveFormsModule, MatCheckboxModule, MatFormFieldModule, MatOptionModule, forwardRef(() => ComponentMapperComponent)]
})
export class {{COMPONENT_CLASS_NAME}}Component extends FieldBase implements OnInit, OnDestroy {
  configProps$: {{COMPONENT_CLASS_NAME}}Props;

  caption$?: string = '';
  showLabel$ = false;
  isChecked$ = false;
  trueLabel$?: string;
  falseLabel$?: string;

  selectionMode?: string;
  datasource?: any;
  selectionKey?: string;
  selectionList?: any;
  primaryField: string;
  selectedvalues: any;
  referenceList: string;
  listOfCheckboxes: any[] = [];
  variant?: string;

  // Override ngOnInit method
  override ngOnInit(): void {
    super.ngOnInit();

    if (this.selectionMode === 'multi' && this.referenceList?.length > 0 && !this.bReadonly$) {
      this.pConn$.setReferenceList(this.selectionList);
      updateNewInstructions(this.pConn$, this.selectionList);
    }
  }

  /**
   * Updates the component when there are changes in the state.
   */
  override updateSelf(): void {
    // moved this from ngOnInit() and call this from there instead...
    this.configProps$ = this.pConn$.resolveConfigProps(this.pConn$.getConfigProps()) as {{COMPONENT_CLASS_NAME}}Props;

    // Update component common properties
    this.updateComponentCommonProperties(this.configProps$);

    if (this.label$ != '') {
      this.showLabel$ = true;
    }
    this.variant = this.configProps$.variant;
    if (this.bReadonly$) {
      this.fieldControl?.disable();
    }

    // multi case
    this.selectionMode = this.configProps$.selectionMode;
    if (this.selectionMode === 'multi') {
      this.referenceList = this.configProps$.referenceList;
      this.selectionList = this.configProps$.selectionList;
      this.selectedvalues = this.configProps$.readonlyContextList;
      this.primaryField = this.configProps$.primaryField;
      this.bReadonly$ = this.configProps$.renderMode === 'ReadOnly' || this.displayMode$ === 'DISPLAY_ONLY' || this.configProps$.readOnly;

      this.datasource = this.configProps$.datasource;
      this.selectionKey = this.configProps$.selectionKey;
      const listSourceItems = this.datasource?.source ?? [];
      const dataField = this.selectionKey?.split?.('.')[1] ?? '';
      const listToDisplay: any[] = [];
      listSourceItems.forEach(element => {
        element.selected = this.selectedvalues?.some?.(data => data[dataField] === element.key);
        listToDisplay.push(element);
      });
      this.listOfCheckboxes = listToDisplay;
    } else {
      if (this.configProps$.value != undefined) {
        this.value$ = this.configProps$.value;
      }

      this.caption$ = this.configProps$.caption;
      this.trueLabel$ = this.configProps$.trueLabel || 'Yes';
      this.falseLabel$ = this.configProps$.falseLabel || 'No';

      this.isChecked$ = this.value$ === 'true' || this.value$ == true;
    }
  }

  fieldOnChange(event: any) {
    event.value = event.checked;
    handleEvent(this.actionsApi, 'changeNblur', this.propName, event.checked);
    this.pConn$.clearErrorMessages({
      property: this.propName
    });
  }

  fieldOnBlur(event: any) {
    if (this.selectionMode === 'multi') {
      this.pConn$.getValidationApi().validate(this.selectedvalues, this.selectionList);
    } else {
      this.pConn$.getValidationApi().validate(event.target.checked);
    }
  }

  handleChangeMultiMode(event, element) {
    if (!element.selected) {
      insertInstruction(this.pConn$, this.selectionList, this.selectionKey, this.primaryField, {
        id: element.key,
        primary: element.text ?? element.value
      });
    } else {
      deleteInstruction(this.pConn$, this.selectionList, this.selectionKey, {
        id: element.key,
        primary: element.text ?? element.value
      });
    }
    this.pConn$.clearErrorMessages({
      property: this.selectionList,
      category: '',
      context: ''
    });
  }
}
