import { Component, OnInit, Input, forwardRef, OnChanges } from '@angular/core';
import { CommonModule } from '@angular/common';
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';
import { TemplateUtils } from '@pega/angular-sdk-components';
import { FormTemplateBase } from '@pega/angular-sdk-components';

function areViewsChanged(oldViews: any[], newViews: any[]): boolean {
  if (oldViews?.length !== newViews?.length) {
    return true;
  }

  return !oldViews?.every((oldView, index) => {
    const newView = newViews[index];
    return oldView.getPConnect().viewName === newView.getPConnect().viewName;
  });
}

interface {{COMPONENT_CLASS_NAME}}Props {
  // If any, enter additional props that only exist on this component
  NumCols: string;
  instructions: string;
}

@Component({
  selector: 'app-{{COMPONENT_CLASS_NAME_KEBAB}}',
  templateUrl: './{{COMPONENT_CLASS_NAME_KEBAB}}.component.html',
  styleUrls: ['./{{COMPONENT_CLASS_NAME_KEBAB}}.component.scss'],
  imports: [CommonModule, forwardRef(() => ComponentMapperComponent)]
})
export class {{COMPONENT_CLASS_NAME}}Component extends FormTemplateBase implements OnInit, OnChanges {
  @Input() override pConn$: typeof PConnect;
  @Input() formGroup$: FormGroup;

  // Used with AngularPConnect
  override angularPConnectData: AngularPConnectData = {};

  arChildren$: any[];
  divClass$: string;
  instructions: string;

  constructor(
    private angularPConnect: AngularPConnectService,
    private templateUtils: TemplateUtils
  ) {
    super();
  }

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

    this.updateSelf();
  }

  onStateChange() {
    this.updateSelf();
  }

  ngOnChanges(changes) {
    const { pConn$ } = changes;

    if (pConn$.previousValue && !PCore.isDeepEqual(pConn$.previousValue.getConfigProps(), pConn$.currentValue.getConfigProps())) {
      this.updateSelf();
    }
  }

  updateSelf() {
    const configProps = this.pConn$.getConfigProps() as {{COMPONENT_CLASS_NAME}}Props;
    const kids = this.pConn$.getChildren();
    this.instructions = this.templateUtils.getInstructions(this.pConn$, configProps?.instructions);

    const numCols = configProps.NumCols ? configProps.NumCols : '1';
    switch (numCols) {
      case '1':
        this.divClass$ = 'psdk-default-form-one-column';
        break;
      case '2':
        this.divClass$ = 'psdk-default-form-two-column';
        break;
      case '3':
        this.divClass$ = 'psdk-default-form-three-column';
        break;
      default:
        this.divClass$ = 'psdk-default-form-one-column';
        break;
    }

    // repoint children before getting templateArray
    // Children may contain 'reference' component, so we need to
    //  normalize them
    const children = ReferenceComponent.normalizePConnArray(kids[0].getPConnect().getChildren());

    if (areViewsChanged(this.arChildren$, children)) {
      this.arChildren$ = children;
    }
  }
}
