import { MatCardModule } from '@angular/material/card';
import { MatListModule } from '@angular/material/list';
import { MatInputModule } from '@angular/material/input';
import { MatFormFieldModule } from '@angular/material/form-field';
import { Component, signal } from '@angular/core';
import { FormControl, FormGroup, FormsModule, ReactiveFormsModule, Validators } from '@angular/forms';
import { MatButtonModule } from '@angular/material/button';
import { WidgetService } from 'src/app/widget-configuration.service';
import { forkJoin, map } from 'rxjs';
import { HttpClient } from '@angular/common/http';
import { MatSelectModule } from '@angular/material/select';
import { CommonModule } from '@angular/common';
import { error } from 'console';

@Component({
  selector: 'app-video',
  imports: [
    CommonModule,
    FormsModule,
    ReactiveFormsModule,
    MatCardModule,
    MatListModule,
    MatFormFieldModule,
    MatInputModule,
    MatSelectModule,
    MatButtonModule,
  ],
  templateUrl: './video.component.html',
  styleUrl: './video.component.scss',
  standalone: true,
})
export class VideoComponent {
  client: any;
  widgetConf: any;
  serverUrl!: string;
  formId!: string;
  sessionId!: string;

  fields = signal<any[]>([]);
  videoEngagement = signal<boolean>(true);
  videoServices = signal<any[]>([]);
  sessionState = signal<string>('');

  dynamicForm: FormGroup = new FormGroup({});
  selectedService = new FormControl();
  bodyMessage = new FormControl();

  constructor(private widgetService: WidgetService, private http: HttpClient) {
    this.client = this.widgetService.getClient();
    this.serverUrl = this.widgetService.getServerUrl();
    this.widgetConf = this.client.getConfiguration();

    this.loadCallServices();
    this.loadFormConfigurations();
  }

  // recupero i servizi disponibili per il canale VIDEO
  private loadCallServices() {
    const services = this.widgetConf.servicesConfiguration
      .filter((conf: any) => conf.type === 'VIDEO')
      .flatMap((conf: any) => conf.services);

    console.log('Servizi VIDEO:', services);
    this.videoServices.set(services);
  }

  // recupero il form associato ai vari servizi (in modo da sapere quali campi vanno compilati e inviati all'apertura di una nuova sessione)
  private loadFormConfigurations() {
    const formRequests: any[] = [];
    const seenFormIds = new Set<string>();

    this.widgetConf.servicesConfiguration?.forEach((conf: any) => {
      conf.services?.forEach((service: any) => {
        if (service.formId && !seenFormIds.has(service.formId)) {
          seenFormIds.add(service.formId);
          this.formId = service.formId;

          const request$ = this.http
            .get(
              `${this.serverUrl}/apps/widget/conf/forms/form_${service.formId}.json`
            )
            .pipe(
              map((config: any) => ({
                formId: service.formId,
                config,
              }))
            );

          formRequests.push(request$);
        }
      });
    });

    if (formRequests.length) {
      forkJoin(formRequests).subscribe((formConfigs: any[]) => {
        console.log('Form configs ricevuti:', formConfigs);

        const allFields = formConfigs.flatMap((fc) => fc.config.fields || []);
        const sortedFields = allFields.sort((a, b) => +a.order - +b.order);

        this.fields.set(sortedFields);
        this.buildForm(sortedFields);
      });
    }
  }

  // costruisco il form con i campi che mi sono arrivati dal json del form configurato
  private buildForm(fields: any[]) {
    const formGroup: { [key: string]: FormControl } = {};

    fields.forEach((field) => {
      const validators = [];

      if (field.required === 'TRUE') {
        validators.push(Validators.required);
      }

      if (field.validationPattern) {
        validators.push(Validators.pattern(field.validationPattern));
      }

      formGroup[field.key] = new FormControl(
        field.defaultValue || '',
        validators
      );
    });

    this.dynamicForm = new FormGroup(formGroup);
    console.log('Form created:', this.dynamicForm);
  }

  newVideoChannelSession() {
    this.sessionSubscription();
    if (this.dynamicForm.invalid) return;

    const formValues = this.dynamicForm.value;

    const formattedFields = this.fields().map((field: any) => ({
      id: field.key,
      label: field.label,
      value: formValues[field.key],
    }));

    // metodo per creare nuova sessione VIDEO
    this.client
      .videoChannelSessionNew(
        this.selectedService.value?.code, // id servizio selezionato
        null, // nome cliente
        null, // email client
        formattedFields, // form fields
        this.formId, // id della form associata al servizio scelto
        this.widgetService.widgetId // id widget
      )
      .then((res: any) => {
        console.log('videoChannelSessionNew SUCCESS');
        console.log('SessionId:', res);
        this.sessionId = res;
        this.videoEngagement.set(false);
      })
      .catch((err: any) => {
        console.error('videoChannelSessionNew ERROR', err);
      });
  }

  sessionSubscription(){
    // mi sottoscrivo per monitorare il canale VIDEO
    this.client.videoChannelSessionMonitor().subscribe({
      next: (session : any) => {
        console.log('videoChannelSessionMonitor session', session);
        if (session.sessionState == 'ACTIVE'){
          this.sessionState.set('CONNECTED');
        } else if (session.sessionState == 'CLOSED') {
          // videochiamata terminata
          this.sessionState.set('CLOSED');
        }
      },
      error: (err : any) => {
        console.error('videoChannelSessionMonitor ERROR', err)
      }
    })
  }

   /** CHIUSURA VIDEOCHIAMATA */

   closeVideoSession(){
    this.client.videoChannelSessionClose(this.sessionId).then((res: boolean) => {
        console.log('videoChannelSessionClose SUCCESS');
        this.sessionState.set('CLOSED');
      })
      .catch((err: any) => {
        console.error('videoChannelSessionClose ERROR', err);
      });
   }
}
