import type {
  AnalyticsEventProperties,
  AnalyticsService,
} from "./analytics-service";
import { config } from "../../config";

/**
 * Configuration options for UmamiAnalyticsService.
 *
 * @property enabled - Whether analytics are enabled
 */
export type UmamiAnalyticsServiceOptions = {
  enabled: boolean;
};

/**
 * Umami Analytics Service Implementation (Script-less/Proxy edition).
 *
 * This version implements the Umami tracking protocol directly via fetch,
 * eliminating the need to load an external script.js file.
 *
 * In the browser, it gathers standard metadata (screen, language, referrer)
 * and sends it to the proxied '/stats/api/send' endpoint.
 */
export class UmamiAnalyticsService implements AnalyticsService {
  private websiteId?: string;
  private endpoint: string;
  private serverContext?: {
    userAgent?: string;
    language?: string;
    referrer?: string;
    ip?: string;
  };

  constructor(private readonly options: UmamiAnalyticsServiceOptions) {
    this.websiteId = config.analytics.umami.websiteId;

    // On server, use the full internal URL; on client, use the proxied path
    this.endpoint =
      typeof window === "undefined"
        ? config.analytics.umami.apiEndpoint
        : "/stats";
  }

  /**
   * Set the server-side context for the current request.
   * This allows the service to use real request headers for tracking.
   */
  setServerContext(context: {
    userAgent?: string;
    language?: string;
    referrer?: string;
    ip?: string;
  }) {
    this.serverContext = context;
  }

  /**
   * Internal method to send the payload to Umami API.
   */
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  private async sendPayload(type: "event", data: Record<string, unknown>) {
    if (!this.options.enabled || !this.websiteId) return;

    try {
      const payload = {
        website: this.websiteId,
        hostname:
          typeof window !== "undefined"
            ? window.location.hostname
            : this.serverContext?.referrer
              ? new URL(this.serverContext.referrer).hostname
              : "server",
        screen:
          typeof window !== "undefined"
            ? `${window.screen.width}x${window.screen.height}`
            : undefined,
        language:
          typeof window !== "undefined"
            ? navigator.language
            : this.serverContext?.language,
        referrer:
          typeof window !== "undefined"
            ? document.referrer
            : this.serverContext?.referrer,
        ...data,
      };

      const headers: Record<string, string> = {
        "Content-Type": "application/json",
      };

      // Set User-Agent
      if (typeof window !== "undefined") {
        headers["User-Agent"] = navigator.userAgent;
      } else if (this.serverContext?.userAgent) {
        headers["User-Agent"] = this.serverContext.userAgent;
      } else {
        headers["User-Agent"] = "Mintel-Server-Proxy";
      }

      // Forward client IP if available (Umami must be configured to trust this)
      if (this.serverContext?.ip) {
        headers["X-Forwarded-For"] = this.serverContext.ip;
      }

      const response = await fetch(`${this.endpoint}/api/send`, {
        method: "POST",
        headers,
        body: JSON.stringify({ type, payload }),
        keepalive: true,
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
      } as any);

      if (!response.ok && process.env.NODE_ENV === "development") {
        const errorText = await response.text();
        console.warn(
          `[Umami] API responded with ${response.status}: ${errorText}`,
        );
      }
    } catch (error) {
      if (process.env.NODE_ENV === "development") {
        console.error("[Umami] Failed to send analytics:", error);
      }
    }
  }

  /**
   * Track a custom event.
   */
  track(eventName: string, props?: AnalyticsEventProperties) {
    this.sendPayload("event", {
      name: eventName,
      data: props,
      url:
        typeof window !== "undefined"
          ? window.location.pathname + window.location.search
          : this.serverContext?.referrer
            ? new URL(this.serverContext.referrer).pathname
            : "/",
    });
  }

  /**
   * Track a pageview.
   */
  trackPageview(url?: string) {
    this.sendPayload("event", {
      url:
        url ||
        (typeof window !== "undefined"
          ? window.location.pathname + window.location.search
          : this.serverContext?.referrer
            ? new URL(this.serverContext.referrer).pathname
            : "/"),
    });
  }
}
