import { CommonModule } from '@angular/common';
import { Component, inject } from '@angular/core';
import {
  FormControl,
  FormGroup,
  FormsModule,
  ReactiveFormsModule,
  Validators,
} from '@angular/forms';
import { ActivatedRoute, Router, RouterModule } from '@angular/router';
import { AuthLoginErrorDto } from '@core/models';
import { AuthService } from '@core/services/auth.service';
import { RxState } from '@rx-angular/state';
import { ToastMessageOptions } from 'primeng/api';
import { ButtonModule } from 'primeng/button';
import { CheckboxModule } from 'primeng/checkbox';
import { InputTextModule } from 'primeng/inputtext';
import { MessagesModule } from 'primeng/messages';
import { PasswordModule } from 'primeng/password';
import { RippleModule } from 'primeng/ripple';
import { catchError, endWith, map, of, startWith, tap } from 'rxjs';

const loginFormGroupFunc = () => ({
  username: new FormControl<string | null>(null, {
    validators: [Validators.required, Validators.email],
  }),
  password: new FormControl<string | null>(null, {
    validators: [Validators.required],
  }),
});
export type LoginForm = FormGroup<ReturnType<typeof loginFormGroupFunc>>;
export type LoginFormValue = LoginForm['value'];

export interface loginState {
  submitted: boolean;
  isLoading: boolean;
}
type State = loginState;

@Component({
  templateUrl: './login.component.html',
  imports: [
    CommonModule,
    FormsModule,
    ReactiveFormsModule,
    ButtonModule,
    MessagesModule,
    InputTextModule,
    CheckboxModule,
    RippleModule,
    PasswordModule,
    RouterModule,
  ],
  providers: [RxState],
})
export class LoginComponent {
  private state = inject(RxState<State>);

  model$ = this.state.select();
  loginForm = new FormGroup(loginFormGroupFunc());
  messages: ToastMessageOptions[] = [];

  constructor(
    private authService: AuthService,
    private activatedRoute: ActivatedRoute,
    private router: Router,
  ) {
    this.authService.purgeAuth();
    this.state.set({
      submitted: false,
      isLoading: false,
    });
  }

  submit() {
    this.state.set({ submitted: true, isLoading: false });
    this.messages = [];

    if (this.loginForm.invalid) {
      return;
    }

    const form = this.loginForm.value;
    const params = {
      username: form.username!,
      password: form.password!,
    };

    const login$ = this.authService.attemptAuth(params).pipe(
      catchError((err) => {
        if (err.status === 0 || err.status === 500 || err.status === 502) {
          this.messages = [
            {
              severity: 'error',
              summary: 'Attenzione!',
              detail:
                'Impossibile effettuare il login in questo momento, riprova più tardi',
            },
          ];
        } else {
          const error: AuthLoginErrorDto = err.error;
          this.messages = [
            {
              severity: error.severity,
              summary: error?.title,
              detail: error.message,
            },
          ];
        }
        return of(null);
      }),
      tap((res) => {
        if (!res) return;
        this.activatedRoute.queryParams.subscribe((params) => {
          this.router.navigateByUrl(params['redirect']);
        });
      }),
      map(() => ({})),
      startWith({ isLoading: true }),
      endWith({ isLoading: false }),
    );
    this.state.connect(login$);
  }
}
