import {Component, CUSTOM_ELEMENTS_SCHEMA, EventEmitter, Inject, inject, OnInit, Output, signal} from '@angular/core';
import {
  AbstractControl,
  FormBuilder,
  FormControl,
  FormGroup,
  FormGroupDirective,
  FormsModule,
  NgForm,
  ReactiveFormsModule, ValidationErrors, ValidatorFn,
  Validators
} from '@angular/forms';
import {MatButtonModule} from '@angular/material/button';
import {
  MAT_DIALOG_DATA,
  MatDialogActions,
  MatDialogClose,
  MatDialogContent,
  MatDialogRef,
  MatDialogTitle
} from '@angular/material/dialog';
import {MatFormField, MatInput, MatLabel, MatSuffix} from '@angular/material/input';
import {MatIcon} from '@angular/material/icon';
import {MatSnackBar} from '@angular/material/snack-bar';
import {DialogSignupData} from '../../main-module/main.component/main.component';
import {ErrorStateMatcher} from '@angular/material/core';

@Component({
  selector: 'app-dialog-signup.component',
  imports: [
    FormsModule,
    MatButtonModule,
    MatDialogActions,
    MatDialogClose,
    MatDialogContent,
    MatDialogTitle,
    MatFormField,
    MatIcon,
    MatInput,
    MatLabel,
    MatSuffix,
    MatFormField,
    ReactiveFormsModule,

  ],
  templateUrl: './dialog-signup.component.html',
  styleUrl: './dialog-signup.component.scss',
  schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
export class DialogSignupComponent  implements OnInit {
  readonly dialogRef = inject(MatDialogRef<DialogSignupComponent>);
  hide = signal(true);

  @Output() signupClicked = new EventEmitter<any>();
  @Output() loginClicked = new EventEmitter<any>();

  private _snackBar = inject(MatSnackBar);

  durationInSeconds = 5;

  emailFormControl = new FormControl('', [Validators.required, Validators.email]);

  matcher = new MyErrorStateMatcher();

  errorMessage = signal('');

  signUpForm = new FormGroup({
    username: new FormControl('', [Validators.required]),
    email: new FormControl('', [Validators.required, Validators.email]),
    password: new FormControl('', [Validators.required]),
    confirmPassword: new FormControl('', [Validators.required, this.validateSamePassword]),
  });
  minPw = 8;

  constructor(
    @Inject(MAT_DIALOG_DATA) public data:DialogSignupData,
    private formBuilder: FormBuilder) {

  }

  ngOnInit(): void {

    }

  updateErrorMessage() {
    if (this.emailFormControl.hasError('required')) {
      this.errorMessage.set('You must enter a value');
    } else if (this.emailFormControl.hasError('email')) {
      this.errorMessage.set('Not a valid email');
    } else {
      this.errorMessage.set('');
    }
  }

  clickEvent(event: MouseEvent) {
    this.hide.set(!this.hide());
    event.stopPropagation();
  }

  onNoClick() {
    this.dialogRef.close();
  }

  openSignupFailedSnackBar(errorMessage : string = "Sign up failed.") {
    this._snackBar.open(errorMessage , "", {
      duration: this.durationInSeconds * 1000,
    });
  }

  openSignupSuccessSnackBar(message : string = "User registered successfully!") {
    this._snackBar.open(message, "", {
      duration: this.durationInSeconds * 1000,
    });
  }

  signup() {
    if (!this.signUpForm.invalid) {
      this.signupClicked.emit(this.data);
    }
  }

  login() {
    this.loginClicked.emit();
  }

  private validateSamePassword(control: AbstractControl): ValidationErrors | null {
    const password = control.parent?.get('password');
    const confirmPassword = control.parent?.get('confirmPassword');
    return password?.value == confirmPassword?.value ? null : { 'notSame': true };
  }
}



/** Error when invalid control is dirty, touched, or submitted. */
export class MyErrorStateMatcher implements ErrorStateMatcher {
  isErrorState(control: FormControl | null, form: FormGroupDirective | NgForm | null): boolean {
    const isSubmitted = form && form.submitted;
    return !!(control && control.invalid && (control.dirty || control.touched || isSubmitted));
  }
}
