import { ChangeDetectorRef, Component, Input, Signal, effect, inject } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormControl, FormGroup, FormsModule, ReactiveFormsModule } from '@angular/forms';
import { Site, UiCollaborater, UiVisitor, VisitType } from 'src/app/core/interfaces/interfaces.ui';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInputModule } from '@angular/material/input';
import { MatSelectModule } from '@angular/material/select';
import { MatCheckboxModule } from '@angular/material/checkbox';
import { NgxMatSelectSearchModule } from 'ngx-mat-select-search';
import { SelectComponent, UiLabelValue } from '../../shared/reactive-select/select.component';
import { sites } from 'src/data_test';
import { VisitorService } from '../../visitor/visitor.service';
import { CollaboratorSignalsStateService } from '../../shared/services/signal-state/collaborator-signals-state.service';
import {
  EditModeState,
  StepLabels,
  VisitSignalsStateService,
} from '../../shared/services/signal-state/visit-signals-state.service';
import { ReactiveButtonComponent } from '../../shared/reactive-button/reactive-button.component';
import { DialogService } from '../../shared/services/dialog.service';
import { DialogAddVisitorComponent } from './dialog-add-visitor.component';
import { MatExpansionModule } from '@angular/material/expansion';
import { ListVisitorDetailsComponent } from '../detail/list-visitor-details.component';
import { UiTableAction } from 'src/app/core/interfaces/datatable.interface';
import { DialogUpdateVisitorComponent } from './dialog-update-visitor.component';
import { DialogRemoveVisitorComponent } from './dialog-remove-visitor.component';

@Component({
  selector: 'app-visitor-form',
  standalone: true,
  imports: [
    CommonModule,
    ReactiveFormsModule,
    FormsModule,
    MatFormFieldModule,
    MatInputModule,
    MatSelectModule,
    MatCheckboxModule,
    NgxMatSelectSearchModule,
    SelectComponent,
    ReactiveButtonComponent,
    MatExpansionModule,
    ListVisitorDetailsComponent,
  ],
  template: `
    <form class="form-container mb-5 flex flex-col gap-8" [formGroup]="visitorFormGroup">
      <div class="form-block__pre">
        <div class="flex-1 basis-[6%]">
          <h1>{{ dataStateMode.updateTitleStep[0] }}</h1>
          <h3 class="text-center">1 - Objet & Visiteur(s)</h3>
          <p class="leading-normal text-gray-500">
            {{ labels().STEP_VISITOR }}
          </p>
        </div>

        <div class="mt-6 flex flex-wrap items-start gap-5">
          <div class="flex-1 rounded-2xl  border-gray-200 bg-opacity-60 pb-0">
            <div class="flex flex-col">
              <label class="mb-2 inline-block font-semibold">Objet de la visite *</label>
              <mat-form-field appearance="outline">
                <input formControlName="title" matInput />
                <mat-error class="text-sm">Le titre est obligatoire</mat-error>
              </mat-form-field>

              <label for="input-description" class="mb-2 inline-block font-semibold"
                >Description de la visite</label
              >
              <mat-form-field class="textarea" appearance="outline">
                <textarea
                  id="input-description"
                  placeholder="Entrez la description"
                  matInput
                  rows="3"
                  formControlName="description"></textarea>
              </mat-form-field>
            </div>
          </div>
        </div>
      </div>
      <div class="form-block__info">
        <div class="grid auto-cols-max grid-cols-4 grid-rows-none gap-x-4 gap-y-2">
          <div class="col-span-2">
            <p class="mb-3 font-semibold">Lieu de la visite *</p>
            <mat-form-field class="col-span-2 self-end" appearance="outline">
              <mat-select formControlName="site">
                <mat-option *ngFor="let site of physicalSites" [value]="site">{{
                  site.libelle
                }}</mat-option>
              </mat-select>
            </mat-form-field>
          </div>
          <div class="col-span-2">
            <p class="mb-3 font-semibold">Visite organisée pour un collègue</p>
            <app-select
              [reactiveFormGroup]="visitorFormGroup"
              controlName="initiator"
              [formField]="{
                label: 'Sélectionner le collaborateur',
                placeholder: 'Rechercher un collaborateur'
              }"
              [selectList]="collaboratorsList">
            </app-select>
          </div>
          <h2 class="col-span-4 row-start-2 mb-2">Visiteur(s) et besoins</h2>

          <div class="col-span-2 row-start-4 rounded-2xl border border-gray-300 p-6">
            <div class="mb-4 ml-2">
              <h3 class="text-center">Visiteur(s)</h3>
            </div>
            <p>Cliquez sur l'un des deux boutons pour ajouter un visiteur.</p>
            <div class="mb-5 mt-2 flex justify-center gap-4">
              <reactive-button
                standalone
                icon="person_add"
                [action]="openAddVisitorDialog"
                [hint]="{
                  position: 'left',
                  label: 'Créer un tout nouveau visiteur'
                }"
                variant="primary" />
              <reactive-button
                icon="person_search"
                standalone
                [action]="openVisitorSearchDialog"
                [hint]="{
                  position: 'right',
                  label:
                    'Rechercher parmi les visiteurs ayant déja effectué une visite sur les sites '
                }"
                variant="primary" />
            </div>

            <p class="mb-2 mt-4">
              Liste des visiteurs invités * ({{ visitors.value?.length || 0 }})
            </p>

            <app-list-visitor-details
              *ngIf="visitors.value !== null"
              [actions]="listVisitorActions"
              [labels]="{ name: 'Nom', surname: 'Prénom' }"
              [visitors]="visitors.value" />

            <div
              *ngIf="visitors.value === null || visitors.value.length === 0"
              class="card-search-item">
              Aucun visiteurs
            </div>
          </div>

          <div
            class="col-span-2 col-start-3 row-start-4 h-fit rounded-2xl border border-gray-200 bg-gray-50 p-6">
            <div class="mb-4">
              <h3 class="text-center">Besoins</h3>
              <p>Identifiez les besoins et informations concernant cette visite.</p>
            </div>

            <div class="needs flex flex-col">
              <mat-checkbox formControlName="needBadge">Badge</mat-checkbox>
              <mat-checkbox formControlName="overtime">Dépassement horaire</mat-checkbox>
            </div>
          </div>

          <h2 class="col-span-4 row-start-6">Personne à contacter en cas de problème</h2>
          <mat-form-field class="col-span-2 row-start-7" appearance="outline">
            <mat-label>Prénom et Nom</mat-label>
            <input formControlName="contactName" matInput />
          </mat-form-field>

          <mat-form-field class="col-span-2 col-start-3 row-start-7" appearance="outline">
            <mat-label>Téléphone</mat-label>
            <input formControlName="contactPhone" matInput />
          </mat-form-field>
        </div>
      </div>
    </form>
  `,
  styles: [],
})
export class VisitorFormComponent {
  @Input({ required: true }) visitorFormGroup!: VisitorForm;
  @Input({ required: true }) dataStateMode!: EditModeState;
  visitType: Signal<VisitType>;
  physicalSites = sites;
  collaborators!: Signal<UiCollaborater[] | null>;
  collaboratorsList!: UiLabelValue<Partial<UiCollaborater>>[];
  listVisitorActions: UiTableAction<Partial<UiVisitor>>[] = [];
  labels: Signal<StepLabels>;
  private visitorService = inject(VisitorService);
  private collaboratorState = inject(CollaboratorSignalsStateService);
  private visitState = inject(VisitSignalsStateService);
  private dialog = inject(DialogService);
  constructor() {
    this.listVisitorActions = [
      {
        action: (visitor): void => {
          console.log(visitor);
          this.openUpdateVisitorDialog(visitor);
        },
        label: '',
        icon: 'update',
        variant: 'secondary',
        hint: {
          label: 'Modifier le visiteur',
        },
      },
      {
        action: (visitor): void => {
          console.log(visitor);
          this.openVisitorRemoveDialog(visitor);
        },
        label: '',
        icon: 'close',
        variant: 'secondary',
        hint: {
          label: 'Supprimer le visiteur',
        },
      },
    ];

    effect(() => {
      this.collaborators = this.collaboratorState.select('collaboratorList');
      console.log(this.collaborators());

      if (this.collaborators() != undefined || this.collaborators() != null) {
        this.collaboratorsList = this.collaborators()!.map(collaborator => {
          return { label: collaborator.username, value: collaborator };
        });
      }
    });

    this.visitType = this.visitState.select('type');
    this.labels = this.visitState.select('stepLabels');
  }

  get visitors() {
    return this.visitorFormGroup.get('visitors') as FormControl<Partial<UiVisitor>[] | null>;
  }

  openVisitorRemoveDialog(visitor: Partial<UiVisitor>) {
    this.dialog
      .open(DialogRemoveVisitorComponent, { data: { partialVisitor: visitor }, width: '600px' })
      .afterClosed()
      .subscribe(visitor => {
        if (!visitor) return;
        this.removeVisitorFromGroup(visitor);
        if (this.dataStateMode.enable) {
          this.removeVisitor(visitor, this.dataStateMode.visitId as number);
        }
      });
  }
  
  removeVisitorFromGroup = (visitor: Partial<UiVisitor>) => {
    const visitors = this.visitors?.value;
    if (!visitors) return;

    this.visitors?.patchValue(visitors.filter(v => v.email !== visitor.email));
  };
  
  removeVisitor = (visitor: Partial<UiVisitor>, visitId: number) => {
    this.visitorService.DeleteVisitorFromVisit(visitId).subscribe(() => {
      console.log(visitor)
    })
  }

  openVisitorSearchDialog = () => {
    this.visitorService.openSearchVisitorFormDialog().subscribe(visitor => {
      if (!visitor) return;
      this.addVisitorToGroup(visitor);
    });
  };

  openAddVisitorDialog = () => {
    this.dialog
      .open(DialogAddVisitorComponent, {
        width: '600px',
      })
      .afterClosed()
      .subscribe(v => {
        if (!v) return;
        this.addVisitorToGroup(v);
        if (this.dataStateMode.enable) {
          this.addVisitor(v, this.dataStateMode.visitId as number);
        }
      });
  };

  addVisitor = (visitor: Partial<UiVisitor>, visitId: number) => {
    this.visitorService.addVisitor(visitor, visitId).subscribe(visitor => {
      console.log(visitor);
    });
  };

  openUpdateVisitorDialog(visitor: Partial<UiVisitor>) {
    console.log(this.visitors);

    console.log(visitor);

    this.dialog
      .open(DialogUpdateVisitorComponent, { data: { partialVisitor: visitor }, width: '600px' })
      .afterClosed()
      .subscribe(visitor => {
        console.log(visitor);

        if (!visitor) return;
        this.updateVisitorToGroup(visitor);
        if (this.dataStateMode.enable || visitor.id) {
          this.updateVisitor(visitor);
        }
      });
  }

  addVisitorToGroup = (visitor: Partial<UiVisitor>) => {
    const visitors = this.visitors?.value;

    if (visitors?.find(v => (v?.id && v?.id === visitor.id) || v?.email === visitor.email)) {
      return this.dialog.openSimpleReactiveDialogWithoutActions({
        message: `Attention, vous avez déja ajouté ${visitor.name} ${visitor.surname} à la visite`,
        title: 'Attention',
      });
    }

    const addedVisitors = visitors && visitors.length > 0 ? [...visitors, visitor] : [visitor];
    this.visitors?.patchValue(addedVisitors);

    this.dialog.openSimpleReactiveDialogWithoutActions({
      message: `Visiteur ajouté`,
      title: 'Information',
    });
  };

  private updateVisitor(visitor: Partial<UiVisitor>) {
    this.visitorService.updateVisitorFromVisit(visitor).subscribe(visitor => {
      console.log(visitor);
    });
  }

  updateVisitorToGroup(payloadVisitor: Partial<UiVisitor>) {
    const visitor = this.visitors.value?.find(v => v.email === payloadVisitor.email);

    if (!visitor) {
      return this.dialog.openSimpleReactiveDialogWithoutActions({
        message: "Le visiteur n'existe pas ou l'adresse mail est déja référencé",
        title: 'Attention',
      });
    }

    this.visitors.patchValue([
      ...(this.visitors.value?.filter(v => v.email !== visitor.email) || []),
      payloadVisitor,
    ]);
  }
}

export type VisitorForm = FormGroup<{
  initiator: FormControl<Partial<UiCollaborater> | null>;
  site: FormControl<Site | null>;
  visitors: FormControl<Partial<UiVisitor>[] | null>;
  needBadge: FormControl<boolean | null>;
  overtime: FormControl<boolean | null>;
  contactName: FormControl<string | null>;
  contactPhone: FormControl<string | null>;
  title: FormControl<string | null>;
  description: FormControl<string | null>;
}>;