import { Component, DestroyRef, inject, OnInit, OnDestroy } from '@angular/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import {
    AbstractControl,
    FormsModule,
    ReactiveFormsModule,
    UntypedFormBuilder,
    UntypedFormGroup,
    Validators,
    ValidatorFn,
    ValidationErrors,
} from '@angular/forms';
import { Router, RouterLink } from '@angular/router';
import { Title } from '@angular/platform-browser';
import { MatButtonModule } from '@angular/material/button';
import { MatDividerModule } from '@angular/material/divider';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatIconModule } from '@angular/material/icon';
import { MatInputModule } from '@angular/material/input';

import { Observable, Subscription } from 'rxjs';

import { Errors, User } from '@models';
import { UserService } from '@services';
import { ListErrorsComponent } from '@components/shared';

@Component({
    selector: 'app-credentials',
    imports: [
        RouterLink,
        FormsModule,
        ReactiveFormsModule,
        MatButtonModule,
        MatIconModule,
        MatFormFieldModule,
        MatInputModule,
        MatDividerModule,
        ListErrorsComponent,
    ],
    templateUrl: './credentials.component.html',
    styleUrl: './credentials.component.scss',
})
export class CredentialsComponent implements OnInit, OnDestroy {
    private router = inject(Router);
    private titleService = inject(Title);
    private userService = inject(UserService);
    private fb = inject(UntypedFormBuilder);

    private _user: Subscription = new Subscription();
    title = 'Modifier le mot de passe';
    bannerTitle = '';
    btnUpdateTitle = 'Mettre à jour';
    btnLogoutTitle = 'Se déconnecter';
    user: Partial<User> = {} as Partial<User>;
    credentialsForm: UntypedFormGroup;
    errors: Errors = { errors: {} };
    isSubmitting = false;
    destroyRef = inject(DestroyRef);

    constructor() {
        this.credentialsForm = this.fb.group(
            {
                password: ['', Validators.required],
                confirmPassword: ['', Validators.required],
            },
            { validators: this.checkPasswords },
        );
    }

    get f() {
        return this.credentialsForm.controls;
    }

    ngOnInit() {
        this.titleService.setTitle(`Ad Astra - ${this.title}`);
        Object.assign(this.user, this.userService.getCurrentUser());
        this.credentialsForm.patchValue(this.user);
        if (this.user.username) {
            this.bannerTitle = `@${this.user.username}`;
        } else {
            this.bannerTitle = `${this.user.firstname} ${this.user.lastname}`;
        }
    }

    ngOnDestroy() {
        this._user.unsubscribe();
    }

    submitForm() {
        this.isSubmitting = true;
        this.updateUser(this.credentialsForm.value);
        const user$: Observable<{ user: User }> = this.userService
            .update(this.user)
            .pipe(takeUntilDestroyed(this.destroyRef));
        this._user = user$.subscribe({
            next: ({ user }) => void this.router.navigateByUrl('/profile/' + user.username),
            error: (err) => {
                this.errors = err;
                this.isSubmitting = false;
            },
        });
    }

    updateUser(values: NonNullable<unknown>) {
        Object.assign(this.user, values);
    }

    checkPasswords: ValidatorFn = (group: AbstractControl): ValidationErrors | null => {
        const pass = group.get('password')!.value;
        const confirmPass = group.get('confirmPassword')!.value;
        return pass === confirmPass ? null : { notSame: true };
    };
}
