import type { ParsedEvent } from '../models/api.types';
import { unwrapJsonPayload } from '../../shared/utils/json.util';
import { readNumericField } from '../../shared/utils/number.util';

export type MouseHighlightTarget = 'left' | 'middle' | 'right' | 'wheel';

export function isMouseTelemetryEvent(event: ParsedEvent): boolean {
  const t = (event.event_type ?? '').toLowerCase();
  return t.includes('mouse');
}

/**
 * Payload распознаётся как перемещение курсора (координаты + action «move», без учёта регистра).
 * Сводка телеметрии и фильтр «Исключить перемещения мыши» должны опираться на одну логику.
 */
export function isMouseMovePayload(o: Record<string, unknown>): boolean {
  const rawAction = o['action'];
  const action =
    typeof rawAction === 'string' ? rawAction.trim().toLowerCase() : '';
  if (action !== 'move') {
    return false;
  }
  return readNumericField(o, 'x') !== null && readNumericField(o, 'y') !== null;
}

/** Событие перемещения курсора (payload или тип события с «move»). */
export function isMouseMoveTelemetryEvent(event: ParsedEvent): boolean {
  const raw = unwrapJsonPayload(event.data);
  if (raw == null || typeof raw !== 'object' || Array.isArray(raw)) {
    return false;
  }
  const o = raw as Record<string, unknown>;
  if (isMouseMovePayload(o)) {
    return true;
  }
  const t = (event.event_type ?? '').toLowerCase();
  if (t.includes('mouse') && t.includes('move') && readNumericField(o, 'x') !== null && readNumericField(o, 'y') !== null) {
    return true;
  }
  return false;
}

export function parseMouseHighlightTargets(data: unknown): MouseHighlightTarget[] {
  const raw = unwrapJsonPayload(data);
  if (raw == null || typeof raw !== 'object' || Array.isArray(raw)) {
    return [];
  }
  const o = raw as Record<string, unknown>;
  const action = typeof o['action'] === 'string' ? o['action'].toLowerCase() : '';

  if (action.includes('wheel') || action.includes('scroll')) {
    return ['wheel'];
  }

  const buttonName = typeof o['button_name'] === 'string' ? o['button_name'].trim().toLowerCase() : '';
  if (buttonName === 'left' || buttonName === 'lmb') {
    return ['left'];
  }
  if (buttonName === 'right' || buttonName === 'rmb') {
    return ['right'];
  }
  if (buttonName === 'middle' || buttonName === 'mmb' || buttonName === 'wheel') {
    return ['middle'];
  }

  const button = readNumericField(o, 'button');
  const isDown = o['is_down'];
  if (button == null) {
    return [];
  }
  if (isDown === false) {
    return [];
  }
  // Primary scheme in backend telemetry is 1-based: 1=left, 2=right, 3=middle.
  if (button === 1) {
    return ['left'];
  }
  if (button === 2) {
    return ['right'];
  }
  if (button === 3) {
    return ['middle'];
  }
  // Compatibility fallback for legacy/DOM-style 0-based payloads.
  if (button === 0) {
    return ['left'];
  }
  return [];
}
