/**
 * Client-Side Analytics Tracker
 *
 * Browser-safe event tracking wrapper that works in React components.
 * Automatically handles session tracking and user context.
 */

"use client";

import { EventCategory, EventName, EventProperties } from "./events";

// Extend Window interface for analytics libraries
declare global {
  interface Window {
    posthog?: {
      capture: (event: string, properties?: Record<string, unknown>) => void;
    };
    gtag?: (...args: unknown[]) => void;
  }
}

// Session management
let sessionId: string | null = null;

/**
 * Get or create session ID (persists for browser session)
 */
function getSessionId(): string {
  if (sessionId) return sessionId;

  if (typeof window !== "undefined" && window.sessionStorage) {
    let id = window.sessionStorage.getItem("analytics_session_id");
    if (!id) {
      id = `sess_${Date.now()}_${Math.random().toString(36).substring(2, 11)}`;
      window.sessionStorage.setItem("analytics_session_id", id);
    }
    sessionId = id;
    return id;
  }

  return `sess_${Date.now()}_${Math.random().toString(36).substring(2, 11)}`;
}

/**
 * Get user ID from session/cookies if available
 */
function getUserId(): string | undefined {
  if (typeof window !== "undefined" && window.localStorage) {
    return window.localStorage.getItem("user_id") || undefined;
  }
  return undefined;
}

/**
 * Get current page path
 */
function getCurrentPage(): string {
  if (typeof window !== "undefined") {
    return window.location.pathname;
  }
  return "";
}

/**
 * Get current language from URL
 */
function getCurrentLanguage(): "en" | "ar" {
  if (typeof window !== "undefined") {
    const path = window.location.pathname;
    return path.startsWith("/ar") ? "ar" : "en";
  }
  return "en";
}

/**
 * Track event via API endpoint
 */
async function sendEvent(
  eventName: EventName,
  category: EventCategory,
  properties: EventProperties = {},
): Promise<void> {
  try {
    // Add session and context
    const enrichedProperties: EventProperties = {
      sessionId: getSessionId(),
      userId: getUserId(),
      page: getCurrentPage(),
      language: getCurrentLanguage(),
      ...properties,
    };

    // Send to backend API
    await fetch("/api/analytics/events", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        eventName,
        category,
        properties: enrichedProperties,
      }),
      // Don't wait for response
      keepalive: true,
    });

    // Also send to PostHog if available
    if (window.posthog) {
      window.posthog.capture(eventName, {
        category,
        ...enrichedProperties,
      });
    }

    // Send to Google Analytics if available
    if (window.gtag) {
      window.gtag("event", eventName, {
        event_category: category,
        ...enrichedProperties,
      });
    }
  } catch (error) {
    // Silent fail - don't break user experience
    console.error("Failed to track event:", error);
  }
}

// ==================== CTA TRACKING ====================

export const trackDemoBookingStarted = (properties: EventProperties = {}) => {
  return sendEvent(EventName.CTA_DEMO_BOOKING_STARTED, EventCategory.CTA, {
    ctaType: "demo_booking",
    ...properties,
  });
};

export const trackDemoBookingCompleted = (properties: EventProperties = {}) => {
  return sendEvent(EventName.CTA_DEMO_BOOKING_COMPLETED, EventCategory.CTA, {
    ctaType: "demo_booking",
    ...properties,
  });
};

export const trackContactFormOpened = (properties: EventProperties = {}) => {
  return sendEvent(EventName.CTA_CONTACT_FORM_OPENED, EventCategory.CTA, {
    ctaType: "contact_form",
    ...properties,
  });
};

export const trackContactFormSubmitted = (properties: EventProperties = {}) => {
  return sendEvent(EventName.CTA_CONTACT_FORM_SUBMITTED, EventCategory.CTA, {
    ctaType: "contact_form",
    ...properties,
  });
};

export const trackPricingViewed = (properties: EventProperties = {}) => {
  return sendEvent(EventName.CTA_PRICING_VIEWED, EventCategory.CTA, {
    ctaType: "pricing",
    ...properties,
  });
};

export const trackPricingPlanSelected = (
  planName: string,
  planPrice: number,
  properties: EventProperties = {},
) => {
  return sendEvent(EventName.CTA_PRICING_PLAN_SELECTED, EventCategory.CTA, {
    ctaType: "pricing_plan",
    planName,
    planPrice,
    ...properties,
  });
};

export const trackFreeTrialClicked = (properties: EventProperties = {}) => {
  return sendEvent(EventName.CTA_FREE_TRIAL_CLICKED, EventCategory.CTA, {
    ctaType: "free_trial",
    ...properties,
  });
};

// ==================== FEATURE USAGE TRACKING ====================

export const trackDashboardViewed = (properties: EventProperties = {}) => {
  return sendEvent(
    EventName.FEATURE_DASHBOARD_VIEWED,
    EventCategory.FEATURE_USAGE,
    { featureName: "dashboard", ...properties },
  );
};

export const trackAppointmentCreated = (properties: EventProperties = {}) => {
  return sendEvent(
    EventName.FEATURE_APPOINTMENT_CREATED,
    EventCategory.FEATURE_USAGE,
    { featureName: "appointments", actionType: "create", ...properties },
  );
};

export const trackAppointmentCancelled = (properties: EventProperties = {}) => {
  return sendEvent(
    EventName.FEATURE_APPOINTMENT_CANCELLED,
    EventCategory.FEATURE_USAGE,
    { featureName: "appointments", actionType: "cancel", ...properties },
  );
};

export const trackBillingViewed = (properties: EventProperties = {}) => {
  return sendEvent(
    EventName.FEATURE_BILLING_VIEWED,
    EventCategory.FEATURE_USAGE,
    { featureName: "billing", ...properties },
  );
};

export const trackSubscriptionUpgraded = (properties: EventProperties = {}) => {
  return sendEvent(
    EventName.FEATURE_SUBSCRIPTION_UPGRADED,
    EventCategory.FEATURE_USAGE,
    { featureName: "subscription", actionType: "upgrade", ...properties },
  );
};

export const trackSubscriptionCancelled = (
  properties: EventProperties = {},
) => {
  return sendEvent(
    EventName.FEATURE_SUBSCRIPTION_CANCELLED,
    EventCategory.FEATURE_USAGE,
    { featureName: "subscription", actionType: "cancel", ...properties },
  );
};

export const trackSettingsUpdated = (properties: EventProperties = {}) => {
  return sendEvent(
    EventName.FEATURE_SETTINGS_UPDATED,
    EventCategory.FEATURE_USAGE,
    { featureName: "settings", actionType: "update", ...properties },
  );
};

export const trackTeamMemberInvited = (properties: EventProperties = {}) => {
  return sendEvent(
    EventName.FEATURE_TEAM_MEMBER_INVITED,
    EventCategory.FEATURE_USAGE,
    { featureName: "team", actionType: "invite", ...properties },
  );
};

// ==================== USER JOURNEY TRACKING ====================

export const trackSignupStarted = (properties: EventProperties = {}) => {
  return sendEvent(
    EventName.USER_SIGNUP_STARTED,
    EventCategory.USER_JOURNEY,
    properties,
  );
};

export const trackSignupCompleted = (
  userId: string,
  properties: EventProperties = {},
) => {
  return sendEvent(
    EventName.USER_SIGNUP_COMPLETED,
    EventCategory.USER_JOURNEY,
    { userId, ...properties },
  );
};

export const trackLoginSuccess = (
  userId: string,
  properties: EventProperties = {},
) => {
  return sendEvent(EventName.USER_LOGIN_SUCCESS, EventCategory.USER_JOURNEY, {
    userId,
    ...properties,
  });
};

export const trackLoginFailed = (properties: EventProperties = {}) => {
  return sendEvent(
    EventName.USER_LOGIN_FAILED,
    EventCategory.USER_JOURNEY,
    properties,
  );
};

export const trackLogout = (
  userId: string,
  properties: EventProperties = {},
) => {
  return sendEvent(EventName.USER_LOGOUT, EventCategory.USER_JOURNEY, {
    userId,
    ...properties,
  });
};

export const trackOnboardingCompleted = (
  userId: string,
  properties: EventProperties = {},
) => {
  return sendEvent(
    EventName.USER_ONBOARDING_COMPLETED,
    EventCategory.USER_JOURNEY,
    { userId, ...properties },
  );
};

// ==================== ERROR TRACKING ====================

export const trackFormValidationError = (
  formName: string,
  errorMessage: string,
  properties: EventProperties = {},
) => {
  return sendEvent(EventName.ERROR_FORM_VALIDATION, EventCategory.ERROR, {
    formName,
    errorMessage,
    ...properties,
  });
};

export const trackApiError = (
  errorMessage: string,
  errorCode?: string,
  properties: EventProperties = {},
) => {
  return sendEvent(EventName.ERROR_API_REQUEST, EventCategory.ERROR, {
    errorMessage,
    errorCode,
    ...properties,
  });
};

export const trackPaymentError = (
  errorMessage: string,
  properties: EventProperties = {},
) => {
  return sendEvent(EventName.ERROR_PAYMENT_FAILED, EventCategory.ERROR, {
    errorMessage,
    ...properties,
  });
};

export const trackPageNotFound = (
  page: string,
  properties: EventProperties = {},
) => {
  return sendEvent(EventName.ERROR_PAGE_NOT_FOUND, EventCategory.ERROR, {
    page,
    ...properties,
  });
};

export const trackSessionExpired = (properties: EventProperties = {}) => {
  return sendEvent(
    EventName.ERROR_SESSION_EXPIRED,
    EventCategory.ERROR,
    properties,
  );
};

// ==================== ENGAGEMENT TRACKING ====================

export const trackVideoPlayed = (
  videoId: string,
  properties: EventProperties = {},
) => {
  return sendEvent(
    EventName.ENGAGEMENT_VIDEO_PLAYED,
    EventCategory.ENGAGEMENT,
    { videoId, resourceType: "video", ...properties },
  );
};

export const trackResourceDownloaded = (
  resourceId: string,
  resourceType: string,
  properties: EventProperties = {},
) => {
  return sendEvent(
    EventName.ENGAGEMENT_RESOURCE_DOWNLOADED,
    EventCategory.ENGAGEMENT,
    { resourceId, resourceType, ...properties },
  );
};

export const trackCaseStudyViewed = (
  caseStudyId: string,
  properties: EventProperties = {},
) => {
  return sendEvent(
    EventName.ENGAGEMENT_CASE_STUDY_VIEWED,
    EventCategory.ENGAGEMENT,
    { caseStudyId, resourceType: "case_study", ...properties },
  );
};

export const trackFaqExpanded = (
  faqId: string,
  properties: EventProperties = {},
) => {
  return sendEvent(
    EventName.ENGAGEMENT_FAQ_EXPANDED,
    EventCategory.ENGAGEMENT,
    { resourceId: faqId, resourceType: "faq", ...properties },
  );
};

export const trackChatbotOpened = (properties: EventProperties = {}) => {
  return sendEvent(
    EventName.ENGAGEMENT_CHATBOT_OPENED,
    EventCategory.ENGAGEMENT,
    { resourceType: "chatbot", ...properties },
  );
};

// ==================== CONVERSION TRACKING ====================

export const trackLeadCaptured = (properties: EventProperties = {}) => {
  return sendEvent(
    EventName.CONVERSION_LEAD_CAPTURED,
    EventCategory.CONVERSION,
    properties,
  );
};

export const trackTrialStarted = (
  userId: string,
  properties: EventProperties = {},
) => {
  return sendEvent(
    EventName.CONVERSION_TRIAL_STARTED,
    EventCategory.CONVERSION,
    { userId, ...properties },
  );
};

export const trackPaidCustomer = (
  userId: string,
  value: number,
  properties: EventProperties = {},
) => {
  return sendEvent(
    EventName.CONVERSION_PAID_CUSTOMER,
    EventCategory.CONVERSION,
    { userId, value, ...properties },
  );
};

// ==================== NAVIGATION TRACKING ====================

export const trackPageView = (
  page: string,
  properties: EventProperties = {},
) => {
  return sendEvent(EventName.NAVIGATION_PAGE_VIEW, EventCategory.NAVIGATION, {
    page,
    ...properties,
  });
};

export const trackExternalLinkClicked = (
  destination: string,
  properties: EventProperties = {},
) => {
  return sendEvent(
    EventName.NAVIGATION_EXTERNAL_LINK_CLICKED,
    EventCategory.NAVIGATION,
    { destination, ...properties },
  );
};

// ==================== REACT HOOKS ====================

/**
 * Hook to track page views on component mount
 */
export function usePageView(pageName?: string) {
  if (typeof window !== "undefined") {
    const page = pageName || getCurrentPage();
    trackPageView(page);
  }
}

/**
 * Hook to track component interaction
 */
export function useTrackInteraction(
  eventName: EventName,
  category: EventCategory,
  properties: EventProperties = {},
) {
  return () => sendEvent(eventName, category, properties);
}
