import { inject, Injectable, signal } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { catchError, tap } from 'rxjs/operators';
import { of, Observable, BehaviorSubject } from 'rxjs';
import { Router } from '@angular/router';

interface CookieStatusResponse {
  message: string;
  userName: string | null;
  isAuthenticated: boolean;
}

@Injectable({
  providedIn: 'root'
})
export class AuthService {
  private readonly authReturnRouteKey = 'AuthReturnRoute';
  private readonly http = inject(HttpClient);
  private readonly router = inject(Router);

  isLoggedIn = signal(false);
  userName = signal('');

  //BehaviorSubject that emits true once the initial auth check has completed.
  //Guards should wait for this before making redirect decisions.
  authCheckComplete$ = new BehaviorSubject<boolean>(false);

  constructor() {
  }

  public checkLoginStatusOnInit(): Observable<unknown> {
    return this.http.get<CookieStatusResponse>(`${window.location.origin}/api/Auth/CheckCookieStatus`).pipe(
      tap(response => {
        this.isLoggedIn.set(response.isAuthenticated);
        this.userName.set(response.userName || '');
        this.authCheckComplete$.next(true);
      }),
      catchError(error => {
        console.error('AuthService: Error checking cookie status on init:', error);
        this.isLoggedIn.set(false);
        this.userName.set('');
        // Signal that auth check is complete (even on error)
        this.authCheckComplete$.next(true);
        // Crucially, if we get a 401 *here*, the app initializer should continue,
        // and the router guard will then take over to redirect.
        // We return EMPTY or of(null) to complete the observable without throwing,
        // so the app initialization can proceed to route resolution.
        return of(null);
      })
    );
  }

  public login(): void {
    console.info('AuthService: Initiating login via BFF endpoint.');

    this.saveRoute();

    const rootReturnUrl = encodeURIComponent(window.location.href);
    window.location.href = `${window.location.origin}/api/Auth/Login?returnUrl=${rootReturnUrl}`;
  }

  public logout(): void {
    console.info('AuthService: Initiating logout via BFF endpoint.');

    this.isLoggedIn.set(false);
    this.userName.set('');

    const redirectUri = encodeURIComponent(window.location.href);
    window.location.href = `${window.location.origin}/api/Auth/Logout?redirectUri=${redirectUri}`;
  }

  private saveRoute(): void {
    // Save the route (e.g. #/ExamplePath) to session storage
    // If we are on the root, route might be empty, so default to #/
    const currentRoute = window.location.hash || '#/';
    console.log(`Saving route: ${currentRoute}`);
    sessionStorage.setItem(this.authReturnRouteKey, currentRoute);
  }

  public restoreSavedRoute(): void {
    if (!this.isLoggedIn())
      return;

    const savedRoute = sessionStorage.getItem(this.authReturnRouteKey);
    if (savedRoute) {
      console.log(`Restoring saved route: ${savedRoute}`);

      sessionStorage.removeItem(this.authReturnRouteKey);

      // Turn "#/ExamplePath" into "/ExamplePath"
      const routePath = savedRoute.replace(/^#/, '');

      this.router.navigateByUrl(routePath);
    }
  }

}
