import {Component, Inject, inject, input, signal} from '@angular/core';
import {FormControl, FormGroup, FormsModule, ReactiveFormsModule, Validators} from '@angular/forms';
import {MatInput, MatLabel} from '@angular/material/input';
import {MatFormFieldModule} from '@angular/material/form-field';
import {MailService, SubmitEmail, VerifyCode} from '@api';
import {AuthService} from '@services/auth.service';
import {MatButtonModule} from '@angular/material/button';
import {
  MAT_DIALOG_DATA,
  MatDialogActions,
  MatDialogContent,
  MatDialogRef,
  MatDialogTitle
} from '@angular/material/dialog';
import {interval, Subscription} from 'rxjs';

@Component({
  selector: 'app-verify-mail-dialog',
  imports: [
    FormsModule,
    MatFormFieldModule,
    MatInput,
    MatLabel,
    ReactiveFormsModule,
    MatButtonModule,
    MatDialogTitle,
    MatDialogContent,
    MatDialogActions
  ],
  templateUrl: './verify-mail-dialog.component.html',
  styleUrl: './verify-mail-dialog.component.scss'
})
export class VerifyMailDialogComponent {
  protected form: FormGroup<VerifyMail>;

  protected readonly completionMessage = input<string>("Thank you for completing your form!");
  protected readonly verifyMail = input<VerifyMailData | null>(null);
  protected mailVerified = signal<boolean>(false);

  // For resend cooldown
  protected resendCooldown = signal<boolean>(false);
  protected cooldownSeconds = signal<number>(60);
  private cooldownSubscription: Subscription | null = null;

  private mailService = inject(MailService);
  private authService = inject(AuthService);
  protected readonly email: string;

  constructor(
    public dialogRef: MatDialogRef<VerifyMailDialogComponent>,
    @Inject(MAT_DIALOG_DATA) public data: InputMail
  ) {
    this.form = new FormGroup({
      code: new FormControl('', {
        nonNullable: true,
        validators: [Validators.required, Validators.minLength(6), Validators.maxLength(6)]
      })
    });
    this.email = data.email;
    this.mailService.submitEmailForVerification({email: this.email.toLowerCase()}).subscribe();
  }

  public onSubmit() {
    if (this.form === undefined) {
      console.error('Form is undefined');
      return;
    }
    if (this.form.valid) {
      this.sendForm();
    } else {
      Object.keys(this.form.controls).forEach(field => {
        const control = this.form!.get(field);
        control?.markAsTouched({onlySelf: true});
      });
    }
  }

  public onCancel() {
    this.dialogRef.close(false);
  }

  public onResend() {
    if (this.resendCooldown()) {
      return;
    }

    const submitEmail: SubmitEmail = {
      email: this.email
    };

    this.mailService.resendVerificationEmail(submitEmail).subscribe({
      next: (response) => {
        this.startResendCooldown();
      },
      error: (error) => {
        console.error('Error resending verification email', error);
      }
    });
  }

  private startResendCooldown() {
    this.resendCooldown.set(true);
    this.cooldownSeconds.set(60);

    if (this.cooldownSubscription) {
      this.cooldownSubscription.unsubscribe();
    }

    this.cooldownSubscription = interval(1000).subscribe(() => {
      const currentSeconds = this.cooldownSeconds();
      if (currentSeconds <= 1) {
        this.resendCooldown.set(false);
        this.cooldownSubscription?.unsubscribe();
        this.cooldownSubscription = null;
      } else {
        this.cooldownSeconds.set(currentSeconds - 1);
      }
    });
  }

  private sendForm() {
    const rawValue = this.form.getRawValue();
    if (this.authService.isAuthenticated$()) {
      const form: VerifyCode = {
        code: rawValue.code,
      };
      this.mailService.verifyEmailCode(form).subscribe({
        next: (mailResponse) => {
          this.mailVerified.set(mailResponse.verified);
          if (mailResponse.verified) {
            this.dialogRef.close(true);
          }
        },
        error: (error) => {
          console.error('Error verifying email code', error);
        }
      });
    } else {
      throw new Error('User not logged in');
    }
  }

  ngOnDestroy() {
    if (this.cooldownSubscription) {
      this.cooldownSubscription.unsubscribe();
    }
  }
}

interface VerifyMail {
  code: FormControl<string>;
}

interface VerifyMailData {
  verified: boolean;
  mail: string;
}

interface InputMail {
  email: string;
}
