
import { Component, OnInit, signal, ApplicationRef, inject, DestroyRef, ChangeDetectionStrategy } from '@angular/core';
import { Router, RouterOutlet, NavigationEnd } from '@angular/router';
import { Title } from '@angular/platform-browser';
import { HeaderComponent } from './components/header/header.component';
import { FooterComponent } from './components/footer/footer.component';
import { BackButtonComponent } from './components/back-button/back-button.component';
import { interval, concat } from 'rxjs';
import { filter, first } from 'rxjs/operators';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { SwUpdate } from '@angular/service-worker';
import { TranslatePipe } from './i18n/translate.pipe';
import { TranslateService } from './i18n/translate.service';
import { PlatformRuntimeService } from './core/runtime/platform-runtime.service';
import { UiRuntimeFacade } from './facades/runtime/ui-runtime.facade';
import { ApiHealthService } from './services/api-health.service';
import { SeoService } from './services/seo.service';
import { FloatingNotificationsComponent } from './features/website/user-experience/components/floating-notifications/floating-notifications.component';
import { AdminAuthService, AuthService } from '@marketplaces/auth';
import { TelegramLoginComponent } from './components/telegram-login/telegram-login.component';

@Component({
  selector: 'app-root',
  imports: [RouterOutlet, HeaderComponent, FooterComponent, BackButtonComponent, TranslatePipe, FloatingNotificationsComponent, TelegramLoginComponent],
  templateUrl: './app.html',
  styleUrl: './app.scss',
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class App implements OnInit {
  protected title = '';
  readonly isAdminHost = typeof window !== 'undefined'
    && window.location.hostname.toLowerCase().startsWith('admin.');
  isHomePage = signal(true);
  isAdminRoute = signal(false);
  checkingServer = signal(true);
  serverAvailable = signal(false);

  private destroyRef = inject(DestroyRef);
  private titleService = inject(Title);
  private swUpdate = inject(SwUpdate);
  private appRef = inject(ApplicationRef);
  private router = inject(Router);
  private i18n = inject(TranslateService);
  private platformRuntime = inject(PlatformRuntimeService);
  private uiRuntime = inject(UiRuntimeFacade);
  private apiHealth = inject(ApiHealthService);
  private seoService = inject(SeoService);
  private authService = inject(AuthService);
  private adminAuthService = inject(AdminAuthService);

  ngOnInit(): void {
    this.platformRuntime.initialize();
    this.title = this.uiRuntime.marketplaceName();
    this.titleService.setTitle(`${this.uiRuntime.marketplaceDisplayName()} - ${this.i18n.t('app.pageTitle')}`);
    this.checkServerHealth();
    this.setupAutoUpdates();
    this.openLoginDialogsFromTestModeQueryParams();
    
    // Track route changes to show/hide back button
    this.router.events
      .pipe(
        filter(event => event instanceof NavigationEnd),
        takeUntilDestroyed(this.destroyRef)
      )
      .subscribe((event) => {
        const navEnd = event as NavigationEnd;
        const url = navEnd.urlAfterRedirects || navEnd.url;
        // Home pages: /ru, /en, /hy (with or without trailing slash)
        this.isHomePage.set(/^\/[a-z]{2}\/?$/.test(url) || url === '/' || url === '');
        // Admin backoffice and the Marketplace Builder (/edit) own their own
        // shells (AdminLayoutComponent / ProjectEditorPageComponent's sidebar) -
        // the storefront header/back-button/footer never render on either.
        this.isAdminRoute.set(/^\/[a-z]{2}\/(backoffice|edit)(\/|$|\?)/.test(url));
      });
  }

  private checkServerHealth(): void {
    this.checkingServer.set(true);
    this.apiHealth.ping()
      .pipe(takeUntilDestroyed(this.destroyRef))
      .subscribe({
        next: () => {
          this.serverAvailable.set(true);
          this.checkingServer.set(false);
        },
        error: () => {
          this.serverAvailable.set(false);
          this.checkingServer.set(false);
        }
      });
  }

  retryConnection(): void {
    this.checkServerHealth();
  }

  /**
   * ?login=true / ?adminLogin=true open the respective login dialog for
   * manual testing. ?devBypassAdmin=true skips the QR flow entirely and
   * activates a fake local admin session - dev builds only, no effect (and
   * no-ops server-side too, see AdminAuthService.devBypassLogin) in
   * production. No effect when the params are absent.
   */
  private openLoginDialogsFromTestModeQueryParams(): void {
    if (typeof window === 'undefined') {
      return;
    }
    const params = new URLSearchParams(window.location.search);
    if (params.get('login') === 'true') {
      this.authService.requestLogin();
    }
    if (params.get('adminLogin') === 'true') {
      this.adminAuthService.requestLogin();
    }
    if (params.get('devBypassAdmin') === 'true') {
      this.adminAuthService.devBypassLogin();
    }
  }

  private setupAutoUpdates(): void {
    if (!this.swUpdate.isEnabled) {
      return;
    }

    const appIsStable$ = this.appRef.isStable.pipe(first(isStable => isStable === true));
    const every6Hours$ = interval(6 * 60 * 60 * 1000);
    const checkInterval$ = concat(appIsStable$, every6Hours$);

    checkInterval$
      .pipe(takeUntilDestroyed(this.destroyRef))
      .subscribe(async () => {
        try {
          await this.swUpdate.checkForUpdate();
        } catch (err) {
          console.error('Update check failed:', err);
        }
      });
  }
}
