/**
 * Core video player interface that all platform implementations must follow
 */

export interface FallbackSource {
  url: string;
  type?: 'mp4' | 'hls' | 'dash' | 'webm' | 'auto';
  priority?: number; // Lower number = higher priority (default: index order)
}

export interface VideoSource {
  url: string;
  type?: 'mp4' | 'hls' | 'dash' | 'webm' | 'auto';
  drm?: DRMConfig;
  subtitles?: SubtitleTrack[];
  metadata?: VideoMetadata;

  // Fallback configuration
  fallbackSources?: FallbackSource[]; // Alternative video URLs to try on failure
  fallbackPoster?: string; // Static image to show when all video sources fail
  fallbackShowErrorMessage?: boolean; // Show error message overlay on fallback poster (default: true)
  fallbackRetryDelay?: number; // Delay in ms before trying next fallback (default: 1000)
  fallbackRetryAttempts?: number; // Number of retry attempts per source (default: 1)
  onAllSourcesFailed?: (errors: Array<{ url: string; error: any }>) => void; // Callback when all sources fail
}

export interface DRMConfig {
  licenseUrl: string;
  certificateUrl?: string;
  headers?: Record<string, string>;
  type: 'widevine' | 'playready' | 'fairplay' | 'clearkey';
}

export interface SubtitleTrack {
  url: string;
  language: string;
  label: string;
  kind: 'subtitles' | 'captions' | 'descriptions';
  default?: boolean;
}

export interface VideoMetadata {
  id?: string;
  videoId?: string;
  title?: string;
  description?: string;
  duration?: number;
  thumbnailUrl?: string;
  posterUrl?: string;
}

export interface Quality {
  height: number;
  width: number;
  bitrate: number;
  label: string;
  index: number;
}

export interface PlayerState {
  isPlaying: boolean;
  isPaused: boolean;
  isBuffering: boolean;
  isEnded: boolean;
  isError: boolean;
  currentTime: number;
  duration: number;
  bufferedPercentage: number;
  volume: number;
  isMuted: boolean;
  playbackRate: number;
  currentQuality?: Quality;
  availableQualities: Quality[];
}

export interface PlayerEvents {
  onReady?: () => void;
  onPlay?: () => void;
  onPause?: () => void;
  onEnded?: () => void;
  onTimeUpdate?: (time: number) => void;
  onBuffering?: (isBuffering: boolean) => void;
  onError?: (error: PlayerError) => void;
  onQualityChanged?: (quality: Quality) => void;
  onVolumeChanged?: (volume: number) => void;
  onFullscreenChanged?: (isFullscreen: boolean) => void;
  onProgress?: (buffered: number) => void;
  onSeeking?: () => void;
  onSeeked?: () => void;
  onLoadedMetadata?: (metadata: VideoMetadata) => void;
  // Fired exactly once when free preview duration is reached and playback is blocked
  onFreePreviewEnded?: () => void;
  // EPG (Electronic Program Guide) events
  epgToggle?: (data?: any) => void;
  epgDataSet?: (data?: any) => void;
  // Framework branding events
  frameworkBrandingClick?: (data: { timestamp: number; url: string; userAgent: string }) => void;
  // Chapter events
  chapterchange?: (chapter: any) => void;
  segmententered?: (segment: any) => void;
  segmentexited?: (segment: any) => void;
  segmentskipped?: (segment: any) => void;
  chapterSegmentEntered?: (data: any) => void;
  chapterSegmentSkipped?: (data: any) => void;
  chapterSkipButtonShown?: (data: any) => void;
  chapterSkipButtonHidden?: (data: any) => void;
  chaptersLoaded?: (data: any) => void;
  chaptersLoadError?: (data: any) => void;
  // Navigation events
  navigationBackClicked?: () => void;
  navigationCloseClicked?: () => void;
  // Live stream waiting events
  onLiveStreamWaiting?: () => void;
  onLiveStreamReady?: () => void;
  // Bandwidth detection events
  onBandwidthDetected?: (data: { bandwidth: number | null; tier: string; method: string }) => void;
  onBandwidthTierChanged?: (data: { tier: string; bandwidth: number | null }) => void;
}

export interface PlayerError {
  code: string;
  message: string;
  type: 'network' | 'media' | 'drm' | 'unknown';
  fatal: boolean;
  details?: any;
}

export interface PaywallConfig {
  enabled: boolean;
  apiBase: string;          // e.g., http://localhost:3100
  userId: string;
  videoId: string;
  gateways: Array<'stripe' | 'cashfree'>;
  branding?: { title?: string; description?: string; logoUrl?: string; theme?: any };
  popup?: { width?: number; height?: number };
  
  // Email OTP Authentication (optional - if not provided, assumes user is already authenticated)
  emailAuth?: {
    enabled: boolean;                    // Enable email authentication flow
    skipIfAuthenticated?: boolean;       // Skip email auth if user already has valid session (default: true)
    sessionStorage?: {
      tokenKey?: string;                 // Key for storing session token (default: 'uvf_session_token')
      refreshTokenKey?: string;          // Key for storing refresh token (default: 'uvf_refresh_token')
      userIdKey?: string;                // Key for storing user ID (default: 'uvf_user_id')
    };
    api?: {
      requestOtp: string;                // POST /auth/request-otp endpoint
      verifyOtp: string;                 // POST /auth/verify-otp endpoint  
      refreshToken?: string;             // POST /auth/refresh-token endpoint
      logout?: string;                   // POST /auth/logout endpoint
    };
    ui?: {
      title?: string;                    // Modal title (default: "Sign in to continue")
      description?: string;              // Modal description
      emailPlaceholder?: string;         // Email input placeholder
      otpPlaceholder?: string;           // OTP input placeholder
      submitButtonText?: string;         // Submit button text
      resendButtonText?: string;         // Resend OTP button text
      resendCooldown?: number;           // Resend cooldown in seconds (default: 30)
    };
    validation?: {
      otpLength?: number;                // Expected OTP length (default: 6)
      otpTimeout?: number;               // OTP validity timeout in seconds (default: 300)
      rateLimiting?: {
        maxAttempts?: number;            // Max OTP requests per hour (default: 5)
        windowMinutes?: number;          // Rate limiting window (default: 60)
      };
    };
  };
}

export interface ShareConfig {
  enabled?: boolean;
  url?: string;
  title?: string;
  text?: string;
  generateUrl?: (videoData: { videoId?: string; metadata?: any }) => string;
}

/**
 * Configuration for individual player control visibility
 * All controls default to true (visible) unless explicitly set to false
 */
export interface ControlsVisibilityConfig {
  /** Playback control buttons */
  playback?: {
    /** Large center play button overlay (default: true) */
    centerPlayButton?: boolean;
    /** Bottom bar play/pause button (default: true) */
    playPauseButton?: boolean;
    /** Skip forward/backward 10s buttons (default: true) */
    skipButtons?: boolean;
    /** Previous track button (default: auto based on playlist config) */
    previousButton?: boolean;
    /** Next track button (default: auto based on playlist config) */
    nextButton?: boolean;
  };

  /** Audio control buttons */
  audio?: {
    /** Volume mute/unmute button (default: true) */
    volumeButton?: boolean;
    /** Volume slider panel (default: true) */
    volumeSlider?: boolean;
  };

  /** Progress and time controls */
  progress?: {
    /** Video seekbar/progress bar (default: true) */
    progressBar?: boolean;
    /** Current time / duration display (default: true) */
    timeDisplay?: boolean;
  };

  /** Quality and settings controls */
  quality?: {
    /** Quality badge indicator (HD, 4K, etc.) (default: true) */
    badge?: boolean;
    /** Settings menu button (default: true) */
    settingsButton?: boolean;
  };

  /** Display mode controls */
  display?: {
    /** Fullscreen toggle button (default: true) */
    fullscreenButton?: boolean;
    /** Picture-in-picture button (default: true on supported browsers) */
    pipButton?: boolean;
  };

  /** Advanced feature controls */
  features?: {
    /** Electronic Program Guide button (default: true when EPG data available) */
    epgButton?: boolean;
    /** Playlist panel toggle button (default: true when callback provided) */
    playlistButton?: boolean;
    /** Cast to TV button (default: true) */
    castButton?: boolean;
    /** Share video button (default: true) */
    shareButton?: boolean;
    // Note: Stop casting button is automatically shown/hidden based on active casting state
  };

  /** Navigation and branding chrome */
  chrome?: {
    /** Back/close navigation buttons (default: auto based on navigation config) */
    navigationButtons?: boolean;
    /** Framework watermark/branding (default: true) */
    frameworkBranding?: boolean;
  };
}

export interface PlayerConfig {
  autoPlay?: boolean;
  muted?: boolean;
  volume?: number;
  controls?: boolean;
  loop?: boolean;
  preload?: 'none' | 'metadata' | 'auto';
  crossOrigin?: 'anonymous' | 'use-credentials';
  playsInline?: boolean;
  defaultQuality?: number;
  enableAdaptiveBitrate?: boolean;
  debug?: boolean;

  // Playback start time
  startTime?: number; // Start playback from this time in seconds (e.g., 125 for 2:05)

  // Free preview
  freeDuration?: number; // seconds of free playback before paywall

  // Live stream indicator
  isLive?: boolean; // Force LIVE indicator display (for live streams)

  // Live stream waiting configuration
  liveWaitingMessages?: {
    waitingForStream?: string;  // Default: "Waiting for Stream"
    loading?: string;            // Default: "Loading"
    comingBack?: string;         // Default: "Coming back"
  };
  liveMessageRotationInterval?: number; // Default: 2500ms (2.5s per message)
  liveRetryInterval?: number;           // Default: 5000ms (stream retry interval)
  liveMaxRetryAttempts?: number;        // Default: undefined (infinite)

  // Live stream countdown configuration - shows timer when program hasn't started
  liveCountdown?: {
    /** UTC timestamp (milliseconds) when next program starts - will be converted to local time */
    nextProgramStartTime?: number;
    /** Message shown above countdown (default: "There is no active program in this channel.") */
    noProgramMessage?: string;
    /** Countdown prefix message (default: "Next program will start in:") */
    countdownMessage?: string;
    /** Color for the countdown timer text (default: uses theme accent color or #00d4ff) */
    timerColor?: string;
    /** Callback when countdown reaches zero */
    onCountdownComplete?: () => void;
    /** Auto-reload stream when timer ends (default: true) */
    autoReloadOnComplete?: boolean;
    /** Update interval in milliseconds (default: 1000) */
    updateInterval?: number;
  };

  // Optional paywall for dynamic rental flow
  paywall?: PaywallConfig;

  // Share configuration
  share?: ShareConfig;

  // Adaptive bitrate starting configuration
  adaptiveBitrate?: {
    /** Starting bitrate in bps (e.g. 2_000_000 for 2 Mbps) */
    startBitrate?: number;
  };

  // Playlist navigation controls
  playlist?: {
    showPrevNext?: boolean;             // show ⏮/⏭ standalone buttons (deprecated — use replaceSkipWithPrevNext)
    onPreviousTrack?: () => void;       // fired when previous track is triggered
    onNextTrack?: () => void;           // fired when next track is triggered
    replaceSkipWithPrevNext?: boolean;  // repurpose skip-back/forward buttons as prev/next track
    onPlaylistToggle?: () => void;      // fired when playlist icon button in controls is clicked
  };

  // Fine-grained control over individual player control visibility
  /**
   * Fine-grained control over individual player control visibility
   * All controls default to true unless explicitly set to false
   */
  controlsVisibility?: ControlsVisibilityConfig;

  // Settings menu configuration
  /**
   * Settings menu configuration
   * @deprecated Use controlsVisibility.quality.settingsButton to hide/show the settings button
   */
  settings?: {
    enabled?: boolean;      // Show/hide settings button (deprecated - use controlsVisibility.quality.settingsButton)
    speed?: boolean;        // Enable playback speed control
    quality?: boolean;      // Enable quality selection
    subtitles?: boolean;    // Enable subtitle selection
  };

  // Navigation configuration (back/close buttons)
  /**
   * Navigation button configuration (back/close buttons in top bar)
   */
  navigation?: {
    onBack?: () => void;    // Callback when back button is clicked
    onClose?: () => void;   // Callback when close button is clicked
  };

  // Framework branding display
  /**
   * Show/hide framework branding watermark
   * @deprecated Use controlsVisibility.chrome.frameworkBranding instead
   */
  showFrameworkBranding?: boolean;

  // Custom element to use for requestFullscreen() — defaults to the internal player wrapper
  fullscreenElement?: HTMLElement;
}

/**
 * Main video player interface
 */
export interface IVideoPlayer {
  // Lifecycle methods
  initialize(container: HTMLElement | string, config?: PlayerConfig): Promise<void>;
  destroy(): Promise<void>;

  // Media control
  load(source: VideoSource): Promise<void>;
  play(): Promise<void>;
  pause(): void;
  stop(): void;
  seek(time: number): void;

  // Volume control
  setVolume(level: number): void;
  mute(): void;
  unmute(): void;
  toggleMute(): void;

  // Quality control
  getQualities(): Quality[];
  getCurrentQuality(): Quality | null;
  setQuality(index: number): void;
  setAutoQuality(enabled: boolean): void;

  // Playback control
  setPlaybackRate(rate: number): void;
  getPlaybackRate(): number;

  // State queries
  getCurrentTime(): number;
  getDuration(): number;
  getBufferedPercentage(): number;
  getState(): PlayerState;
  isPlaying(): boolean;
  isPaused(): boolean;
  isEnded(): boolean;

  // Display control
  enterFullscreen(): Promise<void>;
  exitFullscreen(): Promise<void>;
  toggleFullscreen(): Promise<void>;
  enterPictureInPicture(): Promise<void>;
  exitPictureInPicture(): Promise<void>;

  // Event handling
  on(event: string, handler: Function): void;
  off(event: string, handler?: Function): void;
  once(event: string, handler: Function): void;

  // Subtitle control
  getSubtitles(): SubtitleTrack[];
  setSubtitleTrack(index: number): void;
  disableSubtitles(): void;

  // Advanced features
  setAudioTrack?(index: number): void;
  getAudioTracks?(): any[];
  getThumbnail?(time: number): string;
  getStats?(): any;

  // Free preview runtime controls (optional)
  setFreeDuration?(seconds: number): void;
  resetFreePreviewGate?(): void;

  // Bandwidth detection controls (optional)
  getBandwidthInfo?(): { estimated: number | null; tier: string | null; method: string | null };
  redetectBandwidth?(): Promise<void>;
}
