import { Injectable } from '@angular/core';
import { environment } from '@env/environment';
import PocketBase from 'pocketbase';
import { AuthRepository, AuthResponse } from '@app/domain/authentification/auth.repository';
import { from, map, Observable } from 'rxjs';
import { User } from '@app/domain/users/user.model';
import { LoginDto } from '@app/domain/authentification/dto/login-dto';
import { RegisterDto } from '@app/domain/authentification/dto/register-dto';

@Injectable({ providedIn: 'root' })
export class PbAuthRepository implements AuthRepository {
  private pb = new PocketBase(environment.baseUrl);

  get(): User | undefined {
    return this.pb.authStore.model as User | undefined;
  }

  isAuthenticated(): boolean {
    return this.pb.authStore.isValid;
  }

  isEmailVerified(): boolean {
    return this.pb.authStore.model ? this.pb.authStore.model['verified'] : false;
  }

  login(loginDto: LoginDto): Observable<AuthResponse> {
    return from(
      this.pb.collection('users').authWithPassword(loginDto.email, loginDto.password)
    ).pipe(
      map((response) => {
        const isValid = response.record['verified'];
        return {
          isValid,
          record: this.pb.authStore.model as User,
          token: this.pb.authStore.token,
        } as AuthResponse;
      })
    );
  }

  logout(): void {
    this.pb.authStore.clear();
  }

  register(registerDto: RegisterDto): Observable<User> {
    return from(this.pb.collection('users').create<User>(registerDto));
  }

  confirmPasswordReset(
    resetToken: string,
    newPassword: string,
    confirmPassword: string
  ): Observable<boolean> {
    return from(
      this.pb.collection('users').confirmPasswordReset(resetToken, newPassword, confirmPassword)
    );
  }

  sendRequestPasswordReset(email: string): Observable<boolean> {
    return from(this.pb.collection('users').requestPasswordReset(email));
  }

  sendVerificationEmail(email: string): Observable<boolean> {
    return from(this.pb.collection('users').requestVerification(email)).pipe(map((value) => true));
  }
}
