import { Component, DestroyRef, inject, OnInit, OnDestroy } from '@angular/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { FormsModule, ReactiveFormsModule, UntypedFormBuilder, UntypedFormGroup, Validators } 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 { MatSelectModule } from '@angular/material/select';

import { Observable, Subscription } from 'rxjs';

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

@Component({
    selector: 'app-settings-page',
    imports: [
        RouterLink,
        FormsModule,
        ReactiveFormsModule,
        MatButtonModule,
        MatIconModule,
        MatDividerModule,
        MatFormFieldModule,
        MatInputModule,
        MatSelectModule,
        ListErrorsComponent,
    ],
    styleUrl: './settings.component.scss',
    templateUrl: './settings.component.html',
})
export class SettingsComponent 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 = 'Vos paramètres';
    bannerTitle = '';
    btnUpdateTitle = 'Mettre à jour';
    btnLogoutTitle = 'Se déconnecter';
    btnPasswordTitle = 'Changer le mot de passe';
    user: Partial<User> = {} as Partial<User>;
    settingsForm: UntypedFormGroup;
    errors: Errors = { errors: {} };
    isSubmitting = false;
    destroyRef = inject(DestroyRef);
    imgPath = '/assets/images/avatars/';
    imgExt = '.jpg';
    avatars = [
        `${this.imgPath}animal_001${this.imgExt}`,
        `${this.imgPath}animal_002${this.imgExt}`,
        `${this.imgPath}animal_003${this.imgExt}`,
        `${this.imgPath}animal_004${this.imgExt}`,
        `${this.imgPath}animal_005${this.imgExt}`,
        `${this.imgPath}animal_006${this.imgExt}`,
        `${this.imgPath}animal_007${this.imgExt}`,
        `${this.imgPath}animal_008${this.imgExt}`,
        `${this.imgPath}animal_009${this.imgExt}`,
        `${this.imgPath}animal_010${this.imgExt}`,
        `${this.imgPath}animal_011${this.imgExt}`,
        `${this.imgPath}animal_012${this.imgExt}`,
        `${this.imgPath}animal_013${this.imgExt}`,
        `${this.imgPath}animal_014${this.imgExt}`,
        `${this.imgPath}animal_015${this.imgExt}`,
        `${this.imgPath}animal_016${this.imgExt}`,
    ];

    constructor() {
        // create form group using the form builder
        this.settingsForm = this.fb.group({
            username: ['', Validators.required],
            email: ['', [Validators.required, Validators.email]],
            firstname: ['', Validators.required],
            lastname: ['', Validators.required],
            phone: ['', Validators.required],
            image: '',
        });
        // Optional: subscribe to changes on the form :
        // this.settingsForm.valueChanges.pipe(this._scavenger.collect()).subscribe(values => this.updateUser(values));
    }

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

    ngOnInit() {
        this.titleService.setTitle(`Ad Astra - ${this.title}`);
        // Make a fresh copy of the current user's object to place in editable form fields
        Object.assign(this.user, this.userService.getCurrentUser());
        // Fill the form
        this.settingsForm.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();
    }

    logout() {
        this.userService.purgeAuth();
        this.router.navigateByUrl('/login');
    }

    updatePass() {
        this.router.navigateByUrl('/settings/credentials');
    }

    submitForm() {
        this.isSubmitting = true;

        /* Update the model */
        if (this.avatars.indexOf(this.settingsForm.value.image) === -1) {
            this.settingsForm.value.image = `${this.imgPath}animal_001${this.imgExt}`;
        }
        this.updateUser(this.settingsForm.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);
    }
}
