import { HttpClient } from '@angular/common/http';
import { Component } from '@angular/core';
import {
  AbstractControl,
  FormArray,
  FormControl,
  FormGroup,
  ReactiveFormsModule,
  Validators,
} from '@angular/forms';
import { Router, RouterLink } from '@angular/router';
import { Hotel } from '../HotelItem/hotel';
import { NgFor, NgIf } from '@angular/common';
import { CrossValidator } from '../crossValidator.service';

@Component({
  selector: 'app-new-hotel',
  standalone: true,
  imports: [ReactiveFormsModule, NgIf, NgFor, RouterLink],
  templateUrl: './new-hotel.component.html',
  styleUrl: './new-hotel.component.css',
})
export class NewHotelComponent {
  public hotelForm!: FormGroup;
  public hotel!: Hotel;
  errorMessages: Record<string, string> = {};

  private validationErrorMessages: Record<string, string> = {
    required: 'This field is required',
    minlength: 'The value is too short',
    maxlength: 'The value is too long',
    pattern: 'The value format is incorrect',
  };

  private fullFormValidationErrorMessages: Record<string, string> = {
    mismatch: 'The name and description have to be the same',
    mismatchEmail: 'The Emails must be the same.',
    mismatchPhone: 'The Phone numbers must be the same.',
  };

  updateErrorMessages(): void {
    this.errorMessages = {};

    Object.keys(this.hotelForm.controls).forEach((field) => {
      const control = this.hotelForm.get(field);

      if (control && control.errors && control.touched) {
        this.errorMessages[field] = Object.keys(control.errors)
          .map(
            (errorKey) =>
              this.validationErrorMessages[errorKey] ||
              `Unknown error: ${errorKey}`,
          )
          .join(' ');
      }
    });

    if (this.hotelForm.errors) {
      Object.keys(this.hotelForm.errors).forEach((errorKey) => {
        const errorMessage =
          this.fullFormValidationErrorMessages[errorKey] ||
          `Unknown error: ${errorKey}`;
        this.errorMessages['form'] = errorMessage;
      });
    }

    console.log(this.errorMessages);
  }

  ngOnInit(): void {
    const tags = [];

    for (const tag of this.hotel?.tags ?? []) {
      tags.push(new FormControl(tag, [Validators.required]));
    }

    this.hotelForm = new FormGroup(
      {
        name: new FormControl('', Validators.required),
        description: new FormControl('', Validators.required),
        price: new FormControl(0, Validators.required),
        imageUrl: new FormControl('', Validators.required),
        rating: new FormControl(0, Validators.required),
        contactType: new FormControl('None'),
        email: new FormControl(''),
        emailConfirmation: new FormControl(''),
        phone: new FormControl(''),
        phoneConfirmation: new FormControl(''),
        tags: new FormArray(tags),
      },
      { validators: new CrossValidator().crossValidate() },
    );

    this.hotelForm.valueChanges.subscribe(() => this.updateErrorMessages());
    this.hotelForm.valueChanges.subscribe(() => this.formUpdated());
  }

  formUpdated() {
    console.log(this.hotelForm.get('contactType')?.value);
  }

  getTags() {
    return this.hotelForm.controls['tags'] as FormArray;
  }

  deleteTag(tagElement: AbstractControl) {
    this.getTags().removeAt(this.getTags().controls.indexOf(tagElement));
  }

  addTag() {
    this.getTags().push(new FormControl('', [Validators.required]));
  }

  constructor(
    public http: HttpClient,
    public router: Router,
  ) {}

  submit(): void {
    console.log(this.hotelForm.value);
    const hotel: Hotel = {
      id: 0,
      hotelName: this.hotelForm.get('name')?.value,
      description: this.hotelForm.get('description')?.value,
      price: this.hotelForm.get('price')?.value,
      imageUrl: this.hotelForm.get('imageUrl')?.value,
      rating: this.hotelForm.get('rating')?.value,
      tags: this.hotelForm.get('tags')?.value,
    };

    if (this.hotelForm.get('contactType')?.value == 'Email') {
      hotel.email = this.hotelForm.get('email')?.value;
    } else {
      hotel.phone = this.hotelForm.get('phone')?.value;
    }
    this.http.post('/api/hotels/', hotel).subscribe();
    this.router.navigate(['/']);
  }
}
