import {
  HttpErrorResponse,
  HttpEvent,
  HttpHandler,
  HttpInterceptor,
  HttpRequest,
} from '@angular/common/http';
import { inject, Injectable, NgZone } from '@angular/core';
import { Router } from '@angular/router';

import { Store } from '@ngxs/store';
import { catchError, Observable, throwError } from 'rxjs';

import { AuthClearAction } from '../../shared/action/auth.action';
import { IValues } from '../../shared/interface/setting.interface';
import { SettingState } from '../../shared/state/setting.state';

@Injectable()
export class AuthInterceptor implements HttpInterceptor {
  private store = inject(Store);
  private router = inject(Router);
  private ngZone = inject(NgZone);

  setting$: Observable<IValues> = inject(Store).select(SettingState.setting) as Observable<IValues>;

  public isMaintenanceModeOn: boolean = false;

  constructor() {
    this.setting$.subscribe(setting => {
      this.isMaintenanceModeOn = setting?.maintenance?.maintenance_mode!;
    });
  }

  intercept<T>(req: HttpRequest<T>, next: HttpHandler): Observable<HttpEvent<T>> {
    // If Maintenance Mode On
    if (this.isMaintenanceModeOn) {
      this.ngZone.run(() => {
        void this.router.navigate(['/maintenance']);
      });
    }

    const token = this.store.selectSnapshot(state => state.auth.access_token);
    const lang = this.store.selectSnapshot(state => state?.language?.defaultLanguage?.locale);

    req = req.clone({
      setHeaders: {
        ...(token ? { Authorization: `Bearer ${token}` } : {}),
        'Accept-Lang': lang || 'en', // Default language fallback
      },
    });

    return next.handle(req).pipe(
      catchError((error: HttpErrorResponse) => {
        if (error.status === 401) {
          // this.notificationService.notification = false;
          this.store.dispatch(new AuthClearAction());
        }
        return throwError(() => error);
      }),
    );
  }
}
