import { Platform } from 'react-native';
import AsyncStorage from '@react-native-async-storage/async-storage';
import * as Application from 'expo-application';
import * as Device from 'expo-device';
import Constants from 'expo-constants';

const STORAGE_KEY = 'rebreak_device_id';

let cached: string | null = null;

export async function getDeviceId(): Promise<string> {
  if (cached) return cached;

  if (Platform.OS === 'ios') {
    const vendor = await Application.getIosIdForVendorAsync();
    if (vendor) {
      cached = vendor;
      return vendor;
    }
  }

  if (Platform.OS === 'android') {
    const androidId = Application.getAndroidId();
    if (androidId) {
      cached = androidId;
      return androidId;
    }
  }

  // Fallback: persisted UUID via AsyncStorage (web / simulator edge cases)
  const stored = await AsyncStorage.getItem(STORAGE_KEY).catch(() => null);
  if (stored) {
    cached = stored;
    return stored;
  }

  const uuid =
    'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
      const r = (Math.random() * 16) | 0;
      return (c === 'x' ? r : (r & 0x3) | 0x8).toString(16);
    });

  await AsyncStorage.setItem(STORAGE_KEY, uuid).catch(() => {});
  cached = uuid;
  return uuid;
}

export function getPlatformName(): string {
  if (Platform.OS === 'ios') return 'ios';
  if (Platform.OS === 'android') return 'android';
  return 'web';
}

export interface DeviceInfo {
  deviceId: string;
  platform: string;
  name: string;
  model: string;
  osVersion: string;
  appVersion: string;
}

export async function getDeviceInfo(): Promise<DeviceInfo> {
  const deviceId = await getDeviceId();
  const platform = getPlatformName();

  // expo-device returnt zuverlässige Hardware-Infos auf realen Devices.
  // Constants ist Fallback für Simulator/Web (Device-APIs sind dort null).
  const name =
    Device.deviceName ||
    (Constants as any).deviceName ||
    Device.modelName ||
    platform;

  const model =
    Device.modelName ||
    Device.modelId ||
    Constants.platform?.ios?.model ||
    platform;

  const osVersion =
    Device.osVersion ||
    Constants.platform?.ios?.systemVersion?.toString() ||
    (Platform.Version as string | number)?.toString() ||
    '';

  const appVersion = Application.nativeApplicationVersion || '';

  return { deviceId, platform, name, model, osVersion, appVersion };
}
