import { Component, OnInit, Input, forwardRef, OnDestroy, OnChanges } from '@angular/core';
import { FormGroup } from '@angular/forms';
import { AngularPConnectData, AngularPConnectService } from '@pega/angular-sdk-components';
import { ReferenceComponent } from '@pega/angular-sdk-components';
import { ComponentMapperComponent } from '@pega/angular-sdk-components';

interface CaseSummaryProps {
  // If any, enter additional props that only exist on this component
  status?: string;
  showStatus?: boolean;
  template?: string;
  readOnly?: boolean;
}

@Component({
  selector: 'app-case-summary',
  templateUrl: './case-summary.component.html',
  styleUrls: ['./case-summary.component.scss'],
  standalone: true,
  imports: [forwardRef(() => ComponentMapperComponent)]
})
export class CaseSummaryComponent implements OnInit, OnDestroy, OnChanges {
  @Input() pConn$: typeof PConnect;
  @Input() formGroup$: FormGroup;

  angularPConnectData: AngularPConnectData = {};
  configProps$: CaseSummaryProps;

  arChildren$: any[];

  status$?: string;
  bShowStatus$?: boolean;
  primaryFields$: any[] = [];
  secondaryFields$: any[] = [];

  constructor(private angularPConnect: AngularPConnectService) {}

  ngOnInit(): void {
    // First thing in initialization is registering and subscribing to the AngularPConnect service
    this.angularPConnectData = this.angularPConnect.registerAndSubscribeComponent(this, this.onStateChange);

    this.initComponent();
  }

  ngOnDestroy(): void {
    if (this.angularPConnectData.unsubscribeFn) {
      this.angularPConnectData.unsubscribeFn();
    }
  }

  initComponent() {
    // dereference the View in case the incoming pConn$ is a 'reference'
    this.pConn$ = ReferenceComponent.normalizePConn(this.pConn$);

    // Then, continue on with other initialization

    this.configProps$ = this.pConn$.resolveConfigProps(this.pConn$.getConfigProps()) as CaseSummaryProps;
    this.arChildren$ = this.pConn$.getChildren();

    this.generatePrimaryAndSecondaryFields();

    this.status$ = this.configProps$.status;
    this.bShowStatus$ = this.configProps$.showStatus;
  }

  // Callback passed when subscribing to store change
  onStateChange() {
    // Should always check the bridge to see if the component should
    // update itself (re-render)
    const bUpdateSelf = this.angularPConnect.shouldComponentUpdate(this);

    // ONLY call updateSelf when the component should update
    if (bUpdateSelf) {
      this.updateSelf();
    }
  }

  updateSelf() {
    this.generatePrimaryAndSecondaryFields();
  }

  ngOnChanges() {
    this.initComponent();
  }

  generatePrimaryAndSecondaryFields() {
    this.primaryFields$ = [];
    this.secondaryFields$ = [];

    for (const oField of this.arChildren$[0].getPConnect().getChildren()) {
      const kid = oField.getPConnect();
      this.primaryFields$.push(kid.resolveConfigProps(kid.getRawMetadata()));
    }

    const secondarySummaryFields = this.prepareCaseSummaryData(this.arChildren$[1].getPConnect());
    const secondaryChildren = this.arChildren$[1].getPConnect().getChildren();
    secondaryChildren.forEach((oField, index) => {
      const kid = oField.getPConnect();
      const displayLabel = secondarySummaryFields[index].value.getPConnect().getConfigProps().label;
      this.secondaryFields$.push({ ...kid.resolveConfigProps(kid.getRawMetadata()), kid, displayLabel });
    });
  }

  prepareComponentInCaseSummary(pConnectMeta, getPConnect) {
    const { config, children } = pConnectMeta;
    const pConnect = getPConnect();

    const caseSummaryComponentObject: any = {};

    const { type } = pConnectMeta;
    const createdComponent = pConnect.createComponent({
      type,
      children: children ? [...children] : [],
      config: {
        ...config
      }
    });

    caseSummaryComponentObject.value = createdComponent;
    return caseSummaryComponentObject;
  }

  prepareCaseSummaryData(summaryFieldChildren) {
    const convertChildrenToSummaryData = kid => {
      return kid?.map((childItem, index) => {
        const childMeta = childItem.getPConnect().meta;
        const caseSummaryComponentObject = this.prepareComponentInCaseSummary(childMeta, childItem.getPConnect);
        caseSummaryComponentObject.id = index + 1;
        return caseSummaryComponentObject;
      });
    };
    return summaryFieldChildren ? convertChildrenToSummaryData(summaryFieldChildren?.getChildren()) : undefined;
  }
}
