import { Injectable, OnDestroy, inject } from '@angular/core';
import { Router, NavigationEnd } from '@angular/router';
import { isPlatformBrowser } from '@angular/common';
import { PLATFORM_ID } from '@angular/core';
import { filter, Subscription, skip } from 'rxjs';
import { OpenPanel } from '@openpanel/web';
import type { IdentifyPayload } from '@openpanel/web';
import { OpenPanelConfig, OPENPANEL_CONFIG } from '@core/models/openpanel.model';

export type TrackProperties = Record<string, string | number | boolean | null | undefined>;

@Injectable({
  providedIn: 'root',
})
export class OpenPanelService implements OnDestroy {
  private readonly config = inject(OPENPANEL_CONFIG);
  private readonly platformId = inject(PLATFORM_ID)
  private readonly router = inject(Router);

  private op?: OpenPanel;
  private routerSubscription?: Subscription;

  constructor() {
    if(isPlatformBrowser(this.platformId)) {
      this.initialize();
    }
  }

  // ─── Initialization ────────────────────────────────────────────────────────

  private initialize(): void {
    this.op = new OpenPanel({
      clientId: this.config.clientId,
      apiUrl: this.config.apiUrl,
      trackScreenViews: false, // We handle this manually via Router
      trackOutgoingLinks: this.config.trackOutgoingLinks ?? false,
      trackAttributes: this.config.trackAttributes ?? false,
      disabled: this.config.disabled ?? false,
    });

    if (this.config.globalProperties) {
      this.op.setGlobalProperties(this.config.globalProperties);
    }

    if (this.config.trackScreenViews !== false) {
      this.setupRouteTracking();
    }
  }

  private setupRouteTracking(): void {
    // Nur einmalig subscriben, vorherige Sub zerstören
    this.routerSubscription?.unsubscribe();

    this.routerSubscription = this.router.events
      .pipe(
        filter((event) => event instanceof NavigationEnd),
        // Ersten initialNavigation-Event überspringen – SSR hat ihn schon getriggert
        skip(1),
      )
      .subscribe((event) => {
        const navEvent = event as NavigationEnd;
        this.trackScreenView(navEvent.urlAfterRedirects);
      });
  }

  // ─── Public API ────────────────────────────────────────────────────────────

  /**
   * Tracks a custom event with optional properties.
   * @example opService.track('button_clicked', { button_name: 'signup' });
   */
  track(eventName: string, properties?: TrackProperties): void {
    if (!this.op) return; 
    if (this.config.debug) {
      console.debug('[OpenPanel] track:', eventName, properties);
    }
    this.op.track(eventName, properties);
  }

  /**
   * Identifies the current user. Call this after login.
   * @example opService.identify({ profileId: 'user-123', email: 'user@example.com' });
   */
  identify(payload: IdentifyPayload): void {
    if (!this.op) return; 
    if (this.config.debug) {
      console.debug('[OpenPanel] identify:', payload.profileId);
    }
    this.op.identify(payload);
  }

  /**
   * Clears the current user identity. Call this on logout.
   */
  clearUser(): void {
    if (!this.op) return; 
    if (this.config.debug) {
      console.debug('[OpenPanel] clearUser');
    }
    this.op.clear();
  }

  /**
   * Sets properties that will be sent with every subsequent event.
   */
  setGlobalProperties(properties: TrackProperties): void {
    if (!this.op) return; 
    this.op.setGlobalProperties(properties);
  }

  /**
   * Increments a numeric property on the user profile.
   * @example opService.increment('login_count');
   */
  increment(property: string): void {
    if (!this.op) return; 
    this.op.increment(property);
  }



  /**
   * Decrements a numeric property on the user profile.
   * @example opService.decrement('credits', 5);
   */
  decrement(property: string): void {
    if (!this.op) return; 
    this.op.decrement(property);
  }

  /**
   * Manually tracks a screen/page view.
   */
  trackScreenView(path?: string): void {
    if (!this.op) return; 
    const currentPath = path ?? this.router.url;
    if (this.config.debug) {
      console.debug('[OpenPanel] screenView:', currentPath);
    }
    this.op.track('screen_view', { path: currentPath });
  }

  // ─── Cleanup ───────────────────────────────────────────────────────────────

  ngOnDestroy(): void {
    this.routerSubscription?.unsubscribe();
  }
}