import { hasAnalyticsConsent, isAnalyticsEnvironment } from './analyticsConsent';
import type { Account } from '../data';

type QueuedCall =
  | { type: 'track'; eventName: string; data?: Record<string, unknown> }
  | { type: 'identify'; userInfo: Record<string, unknown> };

const queue: QueuedCall[] = [];

/**
 * Named product events for Tianji (consent-gated). Page views stay on tracker.js.
 *
 * | Event | When |
 * |-------|------|
 * | Login Success / Failed | Password or SSO sign-in |
 * | Sign Up Started / Success / Failed | Self-serve registration |
 * | Logout | Sign out |
 * | Checkout Started | Stripe Checkout session created |
 * | Payment Success / Canceled | Billing return URLs |
 * | Conversation Created | New chat id assigned over WS |
 * | Message Sent | User submits prompt (no content) |
 * | ToS Acknowledged | POST acknowledge_tos succeeds |
 * | Billing Portal Opened | Account manage / portal CTAs |
 * | Subscription Upgrade Started | Upgrade intent (#75) |
 * | Plan Change Started | Change-plan intent (#75) |
 * | Subscription Cancel Started | Cancel intent (#75) |
 * | Account Delete Started / Success / Failed | Self-delete (#34 companion) |
 * | Message Copied / Rated / Rating Reason / Exported | Message actions (#97) |
 * | Activity Stage Completed | Live activity status stage rolled over (#96) |
 */
export const AnalyticsEvents = {
  LOGIN_SUCCESS: 'Login Success',
  LOGIN_FAILED: 'Login Failed',
  SIGNUP_STARTED: 'Sign Up Started',
  SIGNUP_SUCCESS: 'Sign Up Success',
  SIGNUP_FAILED: 'Sign Up Failed',
  LOGOUT: 'Logout',
  CHECKOUT_STARTED: 'Checkout Started',
  PAYMENT_SUCCESS: 'Payment Success',
  PAYMENT_CANCELED: 'Payment Canceled',
  CONVERSATION_CREATED: 'Conversation Created',
  MESSAGE_SENT: 'Message Sent',
  TOS_ACKNOWLEDGED: 'ToS Acknowledged',
  BILLING_PORTAL_OPENED: 'Billing Portal Opened',
  SUBSCRIPTION_UPGRADE_STARTED: 'Subscription Upgrade Started',
  PLAN_CHANGE_STARTED: 'Plan Change Started',
  SUBSCRIPTION_CANCEL_STARTED: 'Subscription Cancel Started',
  ACCOUNT_DELETE_STARTED: 'Account Delete Started',
  ACCOUNT_DELETE_SUCCESS: 'Account Delete Success',
  ACCOUNT_DELETE_FAILED: 'Account Delete Failed',
  MESSAGE_COPIED: 'Message Copied',
  MESSAGE_RATED: 'Message Rated',
  MESSAGE_RATING_REASON: 'Message Rating Reason',
  MESSAGE_EXPORTED: 'Message Exported',
  ACTIVITY_STAGE_COMPLETED: 'Activity Stage Completed',
} as const;

export type AnalyticsEventName = (typeof AnalyticsEvents)[keyof typeof AnalyticsEvents];

/** Custom events + identify require consent. Automatic page views do not. */
const isEventTrackingEnabled = (): boolean =>
  isAnalyticsEnvironment() && hasAnalyticsConsent();

const runQueuedCall = (call: QueuedCall): void => {
  if (!window.tianji) return;

  if (call.type === 'track') {
    window.tianji.track(call.eventName, call.data);
    return;
  }

  window.tianji.identify(call.userInfo);
};

export const flushAnalyticsQueue = (): void => {
  if (!isEventTrackingEnabled() || !window.tianji) return;

  while (queue.length > 0) {
    const call = queue.shift();
    if (call) runQueuedCall(call);
  }
};

export const trackEvent = (
  eventName: AnalyticsEventName | string,
  data?: Record<string, unknown>,
): void => {
  if (!isEventTrackingEnabled()) return;

  const payload = data ? { ...data } : undefined;

  if (window.tianji?.track) {
    window.tianji.track(eventName, payload);
    return;
  }

  queue.push({ type: 'track', eventName, data: payload });
};

export const identifyUser = (userInfo: Record<string, unknown>): void => {
  if (!isEventTrackingEnabled()) return;

  if (window.tianji?.identify) {
    window.tianji.identify(userInfo);
    return;
  }

  queue.push({ type: 'identify', userInfo: { ...userInfo } });
};

/** Identify with stable non-sensitive traits only (no names / prompts). */
export const identifyAccount = (account: Account): void => {
  const traits: Record<string, unknown> = {
    userId: account.email,
  };
  if (account.company?.id != null) {
    traits.companyId = account.company.id;
  }
  if (account.is_company_manager) {
    traits.isCompanyManager = true;
  }
  identifyUser(traits);
};
